Add config-driven docs navigation#56
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
📜 Recent review details🧰 Additional context used📓 Path-based instructions (2)**/*.{ts,tsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/*.{js,ts,jsx,tsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
🔇 Additional comments (1)
📝 WalkthroughSummary by CodeRabbit
WalkthroughAdds a curated, config-driven docs navigation model ( ChangesCurated Navigation (nav) Feature
HTTPS and Portless Infrastructure
Sequence Diagram(s)sequenceDiagram
participant DocsConfig
participant CLI_Generate
participant ResolveDocsNavigation
participant Generators
participant DocsShell
DocsConfig->>CLI_Generate: export/defineDocsConfig(nav)
CLI_Generate->>ResolveDocsNavigation: nav: effectiveNav
ResolveDocsNavigation->>Generators: navigation manifest, ordered pages
Generators->>DocsShell: write src/generated/docs-nav.json
DocsShell->>ResolveDocsNavigation: load docs-nav.json for runtime sidebar/routes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 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 docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 90fea4d56f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (seenUrlPaths.has(page.urlPath)) { | ||
| continue; | ||
| } |
There was a problem hiding this comment.
Preserve pages referenced in multiple nav branches
When the same page is intentionally listed under multiple curated-nav branches, the single shared seenUrlPaths set drops every occurrence after the first. This affects the new c15t config in this commit, where /ai-agents is included in the Start pages for Next.js, React, and JavaScript, so it will only appear under the first framework and disappear from the later sidebars/llms/sitemap navigation. Deduplication should be scoped to an include/group where duplicates are accidental, not across the whole navigation tree.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
No new issues found.
TL;DR — Introduces a config-owned nav tree on DocsConfig / DocsCollection as the curated source of truth for docs IA, threads it through every artifact generator and the CLI, and dogfoods it across the repo's example apps. Legacy frontmatter group survives as taxonomy/fallback.
Key changes
- Add
navtoDocsConfigandDocsCollection— recursive{ title, slug?, description?, base?, pages?, children? }tree withstring | { include, exclude?, sort?, required? }page entries, validated at load and rejected when combined withcollections. - Resolve curated nav in
llm.ts— newresolveNavGroups,joinNavPath,globToRegExp, andbuildNavigationFromNavwith a sharedseenUrlPathsdedup; explicit-page misses throw, empty includes warn (or throw whenrequired: true). - Thread
navthrough every artifact —generateLlmsTxt,generateLLMFullContextFiles,generateAgentReadabilityArtifacts,generateAgentsMd,resolveDocsNavigation, andcreateDocsSourceall acceptnavand prefer it overgroups;generateCLI disables nav under explicit--include/--excludefilters. - Widen public types —
groupsbecomes optional onLlmsTxtConfig,LLMFullContextConfig,AgentReadabilityConfig,AgentsMdConfig, andResolveDocsNavigationConfig;DocsNavigationPagegainsrelativePathforAGENTS.mdrelative.mdlinks. - Merge
navacross collections —mergeCollectionNavprefixes each collection's nav with itsmountPath, rewriting rootbaseand/-rooted descendant refs. - Dogfood in docs and examples —
docs/docs.config.ts,apps/example, andapps/c15t-exampleswitch to curated nav;apps/example/src/lib/docs.tsderives top tabs from root nav nodes and swaps sidebar by active group; newdocs/changelog/nav-migration-prompts.mdxships library and UI migration prompts. - Tighten dev server settings — example apps move to
PORTLESS_PORT=443 PORTLESS_HTTPS=1withallowedHosts: [".localhost"]; Playwright driveshttps://example.localhostdirectly (HTTPS→HTTP downgrade removed).
Summary | 32 files | 2 commits | base: main ← KayleeWilliams/wrong-groups-c15t
Curated nav resolver and the legacy fallback
Before:
groups+ frontmattergroup:was the only source of structure; sidebar,llms.txt,AGENTS.md, and Agent Readability all derived from the same flat group tree.
After:navis the preferred curated tree;groupsremains for legacy fallback, search facets, and unknown-group validation. Withnavpresent, every generator builds from the curated tree andseenUrlPathsdedupes across siblings.
Page entries cascade base to descendants and accept root-relative refs via a leading /. Wildcard { include } entries sort by ["order", "path"] by default and warn when they match nothing (or throw under required: true).
How does collection-mode prefixing work?
`mergeCollectionNav` walks each collection's nav and rewrites root `base` and `/`-rooted descendant bases/pages/excludes through the collection's `mountPath`. Non-`/` page strings are left alone and resolve relative to the prefixed `base`, so `/`-prefixed refs escape to the *collection* root rather than the docs root once a config opts into `collections`.
packages/leadtype/src/llm/llm.ts · packages/leadtype/src/cli/generate.ts · packages/leadtype/src/llm/readability.ts
Top-level docs tabs from root nav nodes
Before:
apps/examplehad a hard-coded{ label: "Docs", to: "/docs" }header entry and a singledocsSidebarSectionsconstant covering the entire group tree.
After: Header tabs derive fromdocsNavigationManifest.groupsviafirstPageInGroup, andgetDocsSidebarSections(pathname)swaps the sidebar based on which root node owns the active route.
isNavigationRouteActive uses a docsGroupKey for docs tabs (so any page inside the group highlights it) and falls back to direct to equality for non-docs routes.
apps/example/src/lib/docs.ts · apps/example/src/components/site-header.tsx · apps/example/src/components/docs-shell.tsx
Migration prompts and dogfooded configs
Before: No published guidance for moving an existing docs site off frontmatter-only
groupnavigation.
After:docs/changelog/nav-migration-prompts.mdxships copyable library and UI prompts, anddocs/docs.config.tsplusapps/c15t-example/leadtype.config.tsdemonstrate the API end-to-end (including the React-framework factory pattern that emits matching Next.js and React trees).
docs/changelog/nav-migration-prompts.mdx · docs/docs.config.ts · apps/c15t-example/leadtype.config.ts · docs/authoring/frontmatter.mdx
Claude Opus | 𝕏
There was a problem hiding this comment.
No new issues found.
TL;DR — Two follow-up commits land the changeset and dogfood the new nav API by removing legacy group: frontmatter and the now-redundant groups block from this repo's own docs config, the example app's generate script, and the in-doc snippets. Clean continuation of the previous review.
Key changes
- Add
leadtypepatch changeset for the config-driven nav release. - Remove
group:frontmatter from everydocs/**/*.mdxpage (andorder: 40fromdocs/build/generate-static-artifacts.mdx) now that placement is curated indocs.config.tsnav. - Strip
groups: [...]fromdocs/docs.config.ts— repo docs are nav-only. - Drop
groups: docsConfig.groupsfrom doc snippets indocs/reference/llm.mdx,docs/build/generate-static-artifacts.mdx, anddocs/changelog/nav-migration-prompts.mdx, plus the liveapps/example/scripts/llm-generate.tspipeline. - Update CLI test in
packages/leadtype/src/cli.test.tsto assert onnavtitles ("Docs") instead of legacy group slugs ("docs-site"). - Refresh generated artifacts (
agent-readability.json,docs-nav.json,docs-pages.json, search index/content).
Summary | 35 files | 2 commits (incremental) | base: main ← KayleeWilliams/wrong-groups-c15t
Self-consistent dogfooding
Before:
docs/docs.config.tscarried both a curatednavand the legacygroupstaxonomy; every doc page declaredgroup:in frontmatter.
After: Repo docs run nav-only. Frontmatter is title + description; placement, sidebar order, andllms.txtsections all come from confignav. The CLI test was updated to match, so the new contract is exercised end-to-end.
The migration-prompt example also dropped its groups: [{ slug: "guides" }] line. The prompt body still says "Keep groups defined when existing group frontmatter should continue to validate" — that guidance is conditional, so the cleaned-up example showing the no-legacy case is internally consistent rather than contradictory.
docs/docs.config.ts · packages/leadtype/src/cli.test.ts · apps/example/scripts/llm-generate.ts · .changeset/config-driven-docs-nav.md
Claude Opus | 𝕏
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
docs/reference/llm.mdx (1)
111-149:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winDeclare/import
docsConfigin standalone code snippets.These examples reference
docsConfig.product/docsConfig.navbut never declaredocsConfig, so copy-pasting fails immediately.Proposed fix
import { convertAllMdx } from "leadtype/convert"; import { defaultRemarkPlugins, remarkInclude } from "leadtype/remark"; import { generateAgentReadabilityArtifacts, generateLLMFullContextFiles, generateLlmsTxt, } from "leadtype/llm"; +import docsConfig from "../docs/docs.config"; // adjust path await convertAllMdx({ srcDir: "docs", outDir: "public/docs", remarkPlugins: [remarkInclude, ...defaultRemarkPlugins], });+import docsConfig from "../docs/docs.config"; // adjust path const mounts = [ { pathPrefix: "", urlPrefix: "/docs" }, { pathPrefix: "changelog", urlPrefix: "/changelog" }, ];Also applies to: 169-190
🤖 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 `@docs/reference/llm.mdx` around lines 111 - 149, The snippet uses docsConfig (e.g., docsConfig.product, docsConfig.nav) but never declares/imports it, so add a minimal example declaration or import for docsConfig before calling convertAllMdx/generateLlmsTxt/generateLLMFullContextFiles/generateAgentReadabilityArtifacts; create a const docsConfig = { product: { name: "My Library", summary: "..." }, nav: [/* sample nav items */] } (or show an import) so the standalone snippet is copy-pasteable and the referenced symbols resolve.
🤖 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 @.changeset/config-driven-docs-nav.md:
- Line 2: Update the changeset in .changeset/config-driven-docs-nav.md by
changing the "leadtype": patch entry to use a minor bump (e.g., "leadtype":
minor) so the release reflects new user-facing features; locate the "leadtype":
patch line in that file and replace patch with minor and save the changeset.
In `@apps/example/src/lib/docs.ts`:
- Around line 102-105: The current truthy check skips group-based matching when
route.docsGroupKey is an empty string; update the condition to explicitly check
for null/undefined (e.g., route.docsGroupKey != null) so an empty "" value is
still used for group matching with findTopNavigationGroup(pathname) and
groupKey(activeGroup), preserving correct active-route behavior when segmentPath
produced an empty key.
In `@packages/leadtype/src/llm/llm.ts`:
- Around line 1248-1294: The resolveNavEntryPages function treats non-include
entries (checked via isNavIncludeEntry) as strict and throws when the referenced
doc (looked up in docsByRelativePath) is missing, but treats include entries as
permissive and only warns unless entry.required is true; add a short JSDoc above
resolveNavEntryPages (or update the DocsNavPageEntry type comment) that states
this asymmetry explicitly: non-include string refs will throw on missing pages,
include globs will only warn unless entry.required is true, and reference the
symbols resolveNavEntryPages, isNavIncludeEntry, docsByRelativePath,
entry.include, and entry.required to make the behavior clear to future readers.
---
Outside diff comments:
In `@docs/reference/llm.mdx`:
- Around line 111-149: The snippet uses docsConfig (e.g., docsConfig.product,
docsConfig.nav) but never declares/imports it, so add a minimal example
declaration or import for docsConfig before calling
convertAllMdx/generateLlmsTxt/generateLLMFullContextFiles/generateAgentReadabilityArtifacts;
create a const docsConfig = { product: { name: "My Library", summary: "..." },
nav: [/* sample nav items */] } (or show an import) so the standalone snippet is
copy-pasteable and the referenced symbols resolve.
🪄 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: ASSERTIVE
Plan: Pro
Run ID: 2ce13425-d890-4216-ad4b-eb021fdd4b97
⛔ Files ignored due to path filters (5)
apps/example/src/generated/agent-readability.jsonis excluded by!**/generated/**apps/example/src/generated/docs-nav.jsonis excluded by!**/generated/**apps/example/src/generated/docs-pages.jsonis excluded by!**/generated/**apps/example/src/generated/docs-search-content.jsonis excluded by!**/generated/**apps/example/src/generated/docs-search-index.jsonis excluded by!**/generated/**
📒 Files selected for processing (47)
.changeset/config-driven-docs-nav.mdapps/c15t-example/leadtype.config.tsapps/c15t-example/package.jsonapps/c15t-example/vite.config.tsapps/example/package.jsonapps/example/playwright.config.tsapps/example/scripts/llm-generate.tsapps/example/src/components/docs-shell.tsxapps/example/src/components/site-header.tsxapps/example/src/lib/docs.tsapps/example/vite.config.tsapps/fumadocs-example/package.jsondocs/authoring/collections.mdxdocs/authoring/components.mdxdocs/authoring/frontmatter.mdxdocs/build/add-search.mdxdocs/build/build-a-docs-site.mdxdocs/build/generate-static-artifacts.mdxdocs/build/integrate-with-fumadocs.mdxdocs/build/optimize-docs-for-agents.mdxdocs/build/use-the-source-primitive.mdxdocs/build/validate-in-ci.mdxdocs/changelog/nav-migration-prompts.mdxdocs/docs.config.tsdocs/how-it-works.mdxdocs/index.mdxdocs/methodology.mdxdocs/package-docs/bundle.mdxdocs/quickstart.mdxdocs/reference/architecture.mdxdocs/reference/cli.mdxdocs/reference/convert.mdxdocs/reference/evals.mdxdocs/reference/lint.mdxdocs/reference/llm.mdxdocs/reference/mdx.mdxdocs/reference/remark.mdxdocs/reference/search.mdxdocs/reference/source.mdxpackages/leadtype/src/cli.test.tspackages/leadtype/src/cli/generate.tspackages/leadtype/src/index.tspackages/leadtype/src/llm/index.tspackages/leadtype/src/llm/llm.test.tspackages/leadtype/src/llm/llm.tspackages/leadtype/src/llm/readability.tspackages/leadtype/src/source/index.ts
💤 Files with no reviewable changes (17)
- docs/methodology.mdx
- docs/reference/remark.mdx
- docs/reference/convert.mdx
- docs/authoring/components.mdx
- docs/authoring/collections.mdx
- docs/build/use-the-source-primitive.mdx
- docs/reference/lint.mdx
- docs/build/optimize-docs-for-agents.mdx
- docs/reference/mdx.mdx
- docs/build/validate-in-ci.mdx
- docs/reference/search.mdx
- docs/index.mdx
- docs/reference/source.mdx
- docs/reference/architecture.mdx
- docs/build/add-search.mdx
- docs/build/integrate-with-fumadocs.mdx
- docs/quickstart.mdx
📜 Review details
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use explicit types for function parameters and return values when they enhance clarity
Preferunknownoveranywhen the type is genuinely unknown
Use const assertions (as const) for immutable values and literal types
Leverage TypeScript's type narrowing instead of type assertions
Files:
apps/example/src/components/docs-shell.tsxapps/example/scripts/llm-generate.tspackages/leadtype/src/index.tspackages/leadtype/src/llm/readability.tspackages/leadtype/src/llm/index.tsapps/c15t-example/vite.config.tspackages/leadtype/src/source/index.tsapps/example/playwright.config.tsapps/example/src/components/site-header.tsxdocs/docs.config.tsapps/example/vite.config.tsapps/example/src/lib/docs.tspackages/leadtype/src/cli.test.tsapps/c15t-example/leadtype.config.tspackages/leadtype/src/llm/llm.test.tspackages/leadtype/src/cli/generate.tspackages/leadtype/src/llm/llm.ts
**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{js,ts,jsx,tsx}: Use meaningful variable names instead of magic numbers - extract constants with descriptive names
Use arrow functions for callbacks and short functions
Preferfor...ofloops over.forEach()and indexedforloops
Use optional chaining (?.) and nullish coalescing (??) for safer property access
Prefer template literals over string concatenation
Use destructuring for object and array assignments
Useconstby default,letonly when reassignment is needed, nevervar
Alwaysawaitpromises in async functions - don't forget to use the return value
Useasync/awaitsyntax instead of promise chains for better readability
Handle errors appropriately in async code with try-catch blocks
Don't use async functions as Promise executors
Removeconsole.log,debugger, andalertstatements from production code
ThrowErrorobjects with descriptive messages, not strings or other values
Usetry-catchblocks meaningfully - don't catch errors just to rethrow them
Prefer early returns over nested conditionals for error cases
Extract complex conditions into well-named boolean variables
Use early returns to reduce nesting
Prefer simple conditionals over nested ternary operators
Don't useeval()or assign directly todocument.cookie
Avoid spread syntax in accumulators within loops
Use top-level regex literals instead of creating them in loops
Prefer specific imports over namespace imports
Use descriptive names for functions, variables, and types for meaningful naming
Add comments for complex logic, but prefer self-documenting code
Files:
apps/example/src/components/docs-shell.tsxapps/example/scripts/llm-generate.tspackages/leadtype/src/index.tspackages/leadtype/src/llm/readability.tspackages/leadtype/src/llm/index.tsapps/c15t-example/vite.config.tspackages/leadtype/src/source/index.tsapps/example/playwright.config.tsapps/example/src/components/site-header.tsxdocs/docs.config.tsapps/example/vite.config.tsapps/example/src/lib/docs.tspackages/leadtype/src/cli.test.tsapps/c15t-example/leadtype.config.tspackages/leadtype/src/llm/llm.test.tspackages/leadtype/src/cli/generate.tspackages/leadtype/src/llm/llm.ts
**/*.{jsx,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{jsx,tsx}: Use function components over class components in React
Call hooks at the top level only, never conditionally
Specify all dependencies in hook dependency arrays correctly
Use thekeyprop for elements in iterables (prefer unique IDs over array indices)
Nest children between opening and closing tags instead of passing as props
Don't define components inside other components
AvoiddangerouslySetInnerHTMLunless absolutely necessary
Use proper image components (e.g., Next.js<Image>) over<img>tags
Use Next.js<Image>component for images
Usenext/heador App Router metadata API for head elements in Next.js
Use Server Components for async data fetching instead of async Client Components in Next.js
Use ref as a prop instead ofReact.forwardRefin React 19+
Files:
apps/example/src/components/docs-shell.tsxapps/example/src/components/site-header.tsx
**/*.{jsx,tsx,html}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{jsx,tsx,html}: Use semantic HTML and ARIA attributes for accessibility: provide meaningful alt text for images, use proper heading hierarchy, add labels for form inputs, include keyboard event handlers alongside mouse events, use semantic elements instead of divs with roles
Addrel="noopener"when usingtarget="_blank"on links
Files:
apps/example/src/components/docs-shell.tsxapps/example/src/components/site-header.tsx
**/index.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Avoid barrel files (index files that re-export everything)
Files:
packages/leadtype/src/index.tspackages/leadtype/src/llm/index.tspackages/leadtype/src/source/index.ts
**/*.{test,spec}.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{test,spec}.{js,ts,jsx,tsx}: Write assertions insideit()ortest()blocks
Avoid done callbacks in async tests - use async/await instead
Don't use.onlyor.skipin committed code
Keep test suites reasonably flat - avoid excessivedescribenesting
Files:
packages/leadtype/src/cli.test.tspackages/leadtype/src/llm/llm.test.ts
🪛 ast-grep (0.42.2)
packages/leadtype/src/llm/llm.ts
[warning] 1204-1204: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(^${source}$)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
🪛 LanguageTool
docs/changelog/nav-migration-prompts.mdx
[style] ~69-~69: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ar within each top-level docs area. - Use base for repeated folder prefixes. ...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~70-~70: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...base` for repeated folder prefixes. - Use explicit page strings for important ent...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~71-~71: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ation, configuration, and cli. - Use { include: "folder/*", sort: ["order",...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~127-~127: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...t, overview, and installation`. - Use wildcard includes for expandable areas ...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~128-~128: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ike component lists and hook lists. - Use a leading / for shared pages that liv...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~157-~157: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... useful nested headings for agents. - Check that wildcard sections do not pull unre...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
🪛 markdownlint-cli2 (0.22.1)
.changeset/config-driven-docs-nav.md
[warning] 5-5: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
🔇 Additional comments (37)
apps/c15t-example/package.json (1)
8-8: LGTM!Also applies to: 10-10
apps/example/package.json (1)
7-7: LGTM!Also applies to: 9-9
apps/fumadocs-example/package.json (1)
10-10: LGTM!apps/c15t-example/vite.config.ts (1)
44-44: LGTM!Also applies to: 49-51
apps/example/vite.config.ts (1)
35-37: LGTM!apps/example/playwright.config.ts (1)
5-5: LGTM!Also applies to: 19-20, 32-32
apps/c15t-example/leadtype.config.ts (1)
11-45: LGTM!Also applies to: 53-81
apps/example/scripts/llm-generate.ts (1)
42-42: LGTM!Also applies to: 49-49, 59-59, 64-69
docs/docs.config.ts (1)
18-18: LGTM!Also applies to: 29-72
apps/example/src/lib/docs.ts (1)
15-101: LGTM!Also applies to: 107-109, 130-166
apps/example/src/components/docs-shell.tsx (1)
5-5: LGTM!Also applies to: 16-16
apps/example/src/components/site-header.tsx (1)
4-4: LGTM!Also applies to: 80-95
packages/leadtype/src/llm/llm.ts (7)
144-167: LGTM!
1573-1614: LGTM!
1640-1677: LGTM!
1706-1740:buildNavigationFromMarkdownDocsnow has a conditional mode parameter.The function signature change from implicit groups-only mode to explicit
mode: "groups" | "nav"with an optionalgroupsForValidationparameter is well-designed. The backwards-compatible default of"groups"preserves existing behavior.
2045-2061:pageViewnow includesrelativePathin the returned object.This aligns with the
DocsNavigationPagetype update inreadability.ts. The change is consistent and complete.
2081-2144: LGTM!
2161-2221: LGTM!packages/leadtype/src/index.ts (1)
37-40: LGTM!packages/leadtype/src/llm/index.ts (1)
27-30: LGTM!packages/leadtype/src/cli/generate.ts (6)
392-454: LGTM!
521-525: LGTM!
558-590: Validation logic is correct but error messaging could be clearer.The mutual exclusivity checks and validation are logically sound. The condition
!(groups || nav)correctly requires at least one ofgroupsornavwhencollectionsis undefined.
765-836: LGTM!
1430-1432: Good defensive design: disabling nav when explicit path filters are used.Disabling the curated navigation when
--includeor--excludefilters are provided makes sense—the navigation tree would not accurately reflect the filtered subset of documents. This prevents confusing output.
1470-1491: LGTM!Also applies to: 1498-1508, 1510-1519, 1528-1538
packages/leadtype/src/source/index.ts (2)
44-44: LGTM!Also applies to: 108-109
459-459: LGTM!packages/leadtype/src/llm/readability.ts (1)
84-92: LGTM!docs/package-docs/bundle.mdx (1)
114-117: LGTM!Also applies to: 130-130
docs/reference/evals.mdx (1)
20-20: LGTM!packages/leadtype/src/llm/llm.test.ts (4)
71-141: LGTM!
1284-1355: LGTM!
1357-1372: LGTM!
1374-1393: LGTM!packages/leadtype/src/cli.test.ts (1)
244-244: LGTM!Also applies to: 257-257
6988530 to
3de83ac
Compare
3de83ac to
d1bd115
Compare
There was a problem hiding this comment.
No new issues. Reviewed the following changes:
- Swapped global nav dedup for a per-group
groupSeenUrlPathsset so sibling and parent/child nav nodes can reference the same page; added aresolveDocsNavigationtest covering sharedai-agentsunder bothNext.jsandReactframework branches. - Switched
packages/leadtype/scripts/generate-docs.tsandapps/example/scripts/docs-source-manifest.tsto passnav: docsConfig.navinstead ofgroups. - Dropped stale
group:andorder:frontmatter fromdocs/build/framework-matrix.mdxand refreshed the generatedagent-readability.json,docs-nav.json,docs-pages.json, and search artifacts. - Bumped the changeset from
patchtominor, tightenedisNavigationRouteActivetoroute.docsGroupKey !== undefinedso empty-string keys still match, and added a JSDoc toresolveNavEntryPagesdocumenting that string refs throw on miss whileincludeentries only throw underrequired: true.
Claude Opus | 𝕏
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/example/scripts/llm-generate.ts (1)
71-75:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winGeneralize the unknown-navigation error text.
Line 74 now reports every unresolved entry as an unknown group, but this flow can also surface invalid
navreferences. Use neutral wording to avoid misdirecting debugging.Suggested fix
- `error: ${urlPath} declares unknown group "${slug}".\n` + `error: ${urlPath} references unknown navigation entry "${slug}".\n`🤖 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 `@apps/example/scripts/llm-generate.ts` around lines 71 - 75, The error text for unresolved navigation entries currently says "declares unknown group" but should use neutral wording; update the message emitted in the loop over navigation.unknown (the for loop destructuring { urlPath, slug } and the process.stderr.write call) to something like "has an unresolved navigation reference" or "contains invalid nav reference" while continuing to include urlPath and slug for context so the message doesn't mislead about "group" specifically.
🤖 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 `@apps/c15t-example/leadtype.config.ts`:
- Around line 24-27: The "Guides" nav entry currently uses { include: "*" }
which re-includes pages already listed in the "Start" entry (the pages
"quickstart", "optimization", and "/ai-agents"); update the "Guides" pages
definition (the Guides entry that uses commonGuidePages and { include: "*" }) to
exclude those specific Start pages (or replace the catch-all with an explicit
include/glob that omits them) so that "quickstart", "optimization" and
"/ai-agents" only appear under the Start entry.
---
Outside diff comments:
In `@apps/example/scripts/llm-generate.ts`:
- Around line 71-75: The error text for unresolved navigation entries currently
says "declares unknown group" but should use neutral wording; update the message
emitted in the loop over navigation.unknown (the for loop destructuring {
urlPath, slug } and the process.stderr.write call) to something like "has an
unresolved navigation reference" or "contains invalid nav reference" while
continuing to include urlPath and slug for context so the message doesn't
mislead about "group" specifically.
🪄 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: ASSERTIVE
Plan: Pro
Run ID: 18eb1e79-8f65-4f42-84d3-29fcea4e95a2
⛔ Files ignored due to path filters (5)
apps/example/src/generated/agent-readability.jsonis excluded by!**/generated/**apps/example/src/generated/docs-nav.jsonis excluded by!**/generated/**apps/example/src/generated/docs-pages.jsonis excluded by!**/generated/**apps/example/src/generated/docs-search-content.jsonis excluded by!**/generated/**apps/example/src/generated/docs-search-index.jsonis excluded by!**/generated/**
📒 Files selected for processing (50)
.changeset/config-driven-docs-nav.mdapps/c15t-example/leadtype.config.tsapps/c15t-example/package.jsonapps/c15t-example/vite.config.tsapps/example/package.jsonapps/example/playwright.config.tsapps/example/scripts/docs-source-manifest.tsapps/example/scripts/llm-generate.tsapps/example/src/components/docs-shell.tsxapps/example/src/components/site-header.tsxapps/example/src/lib/docs.tsapps/example/vite.config.tsapps/fumadocs-example/package.jsondocs/authoring/collections.mdxdocs/authoring/components.mdxdocs/authoring/frontmatter.mdxdocs/build/add-search.mdxdocs/build/build-a-docs-site.mdxdocs/build/framework-matrix.mdxdocs/build/generate-static-artifacts.mdxdocs/build/integrate-with-fumadocs.mdxdocs/build/optimize-docs-for-agents.mdxdocs/build/use-the-source-primitive.mdxdocs/build/validate-in-ci.mdxdocs/changelog/nav-migration-prompts.mdxdocs/docs.config.tsdocs/how-it-works.mdxdocs/index.mdxdocs/methodology.mdxdocs/package-docs/bundle.mdxdocs/quickstart.mdxdocs/reference/architecture.mdxdocs/reference/cli.mdxdocs/reference/convert.mdxdocs/reference/evals.mdxdocs/reference/lint.mdxdocs/reference/llm.mdxdocs/reference/mdx.mdxdocs/reference/remark.mdxdocs/reference/search.mdxdocs/reference/source.mdxpackages/leadtype/scripts/generate-docs.tspackages/leadtype/src/cli.test.tspackages/leadtype/src/cli/generate.tspackages/leadtype/src/index.tspackages/leadtype/src/llm/index.tspackages/leadtype/src/llm/llm.test.tspackages/leadtype/src/llm/llm.tspackages/leadtype/src/llm/readability.tspackages/leadtype/src/source/index.ts
💤 Files with no reviewable changes (18)
- docs/reference/convert.mdx
- docs/build/framework-matrix.mdx
- docs/reference/lint.mdx
- docs/reference/architecture.mdx
- docs/authoring/collections.mdx
- docs/authoring/components.mdx
- docs/index.mdx
- docs/reference/remark.mdx
- docs/reference/source.mdx
- docs/methodology.mdx
- docs/build/optimize-docs-for-agents.mdx
- docs/reference/search.mdx
- docs/build/add-search.mdx
- docs/build/validate-in-ci.mdx
- docs/reference/mdx.mdx
- docs/build/integrate-with-fumadocs.mdx
- docs/quickstart.mdx
- docs/build/use-the-source-primitive.mdx
📜 Review details
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use explicit types for function parameters and return values when they enhance clarity
Preferunknownoveranywhen the type is genuinely unknown
Use const assertions (as const) for immutable values and literal types
Leverage TypeScript's type narrowing instead of type assertions
Files:
apps/example/scripts/docs-source-manifest.tsapps/example/src/components/site-header.tsxpackages/leadtype/src/llm/index.tsapps/c15t-example/vite.config.tspackages/leadtype/scripts/generate-docs.tspackages/leadtype/src/index.tspackages/leadtype/src/source/index.tsapps/example/playwright.config.tspackages/leadtype/src/llm/readability.tsdocs/docs.config.tspackages/leadtype/src/cli.test.tsapps/example/vite.config.tsapps/example/src/components/docs-shell.tsxapps/example/scripts/llm-generate.tspackages/leadtype/src/llm/llm.test.tsapps/example/src/lib/docs.tsapps/c15t-example/leadtype.config.tspackages/leadtype/src/cli/generate.tspackages/leadtype/src/llm/llm.ts
**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{js,ts,jsx,tsx}: Use meaningful variable names instead of magic numbers - extract constants with descriptive names
Use arrow functions for callbacks and short functions
Preferfor...ofloops over.forEach()and indexedforloops
Use optional chaining (?.) and nullish coalescing (??) for safer property access
Prefer template literals over string concatenation
Use destructuring for object and array assignments
Useconstby default,letonly when reassignment is needed, nevervar
Alwaysawaitpromises in async functions - don't forget to use the return value
Useasync/awaitsyntax instead of promise chains for better readability
Handle errors appropriately in async code with try-catch blocks
Don't use async functions as Promise executors
Removeconsole.log,debugger, andalertstatements from production code
ThrowErrorobjects with descriptive messages, not strings or other values
Usetry-catchblocks meaningfully - don't catch errors just to rethrow them
Prefer early returns over nested conditionals for error cases
Extract complex conditions into well-named boolean variables
Use early returns to reduce nesting
Prefer simple conditionals over nested ternary operators
Don't useeval()or assign directly todocument.cookie
Avoid spread syntax in accumulators within loops
Use top-level regex literals instead of creating them in loops
Prefer specific imports over namespace imports
Use descriptive names for functions, variables, and types for meaningful naming
Add comments for complex logic, but prefer self-documenting code
Files:
apps/example/scripts/docs-source-manifest.tsapps/example/src/components/site-header.tsxpackages/leadtype/src/llm/index.tsapps/c15t-example/vite.config.tspackages/leadtype/scripts/generate-docs.tspackages/leadtype/src/index.tspackages/leadtype/src/source/index.tsapps/example/playwright.config.tspackages/leadtype/src/llm/readability.tsdocs/docs.config.tspackages/leadtype/src/cli.test.tsapps/example/vite.config.tsapps/example/src/components/docs-shell.tsxapps/example/scripts/llm-generate.tspackages/leadtype/src/llm/llm.test.tsapps/example/src/lib/docs.tsapps/c15t-example/leadtype.config.tspackages/leadtype/src/cli/generate.tspackages/leadtype/src/llm/llm.ts
**/*.{jsx,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{jsx,tsx}: Use function components over class components in React
Call hooks at the top level only, never conditionally
Specify all dependencies in hook dependency arrays correctly
Use thekeyprop for elements in iterables (prefer unique IDs over array indices)
Nest children between opening and closing tags instead of passing as props
Don't define components inside other components
AvoiddangerouslySetInnerHTMLunless absolutely necessary
Use proper image components (e.g., Next.js<Image>) over<img>tags
Use Next.js<Image>component for images
Usenext/heador App Router metadata API for head elements in Next.js
Use Server Components for async data fetching instead of async Client Components in Next.js
Use ref as a prop instead ofReact.forwardRefin React 19+
Files:
apps/example/src/components/site-header.tsxapps/example/src/components/docs-shell.tsx
**/*.{jsx,tsx,html}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{jsx,tsx,html}: Use semantic HTML and ARIA attributes for accessibility: provide meaningful alt text for images, use proper heading hierarchy, add labels for form inputs, include keyboard event handlers alongside mouse events, use semantic elements instead of divs with roles
Addrel="noopener"when usingtarget="_blank"on links
Files:
apps/example/src/components/site-header.tsxapps/example/src/components/docs-shell.tsx
**/index.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Avoid barrel files (index files that re-export everything)
Files:
packages/leadtype/src/llm/index.tspackages/leadtype/src/index.tspackages/leadtype/src/source/index.ts
**/*.{test,spec}.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{test,spec}.{js,ts,jsx,tsx}: Write assertions insideit()ortest()blocks
Avoid done callbacks in async tests - use async/await instead
Don't use.onlyor.skipin committed code
Keep test suites reasonably flat - avoid excessivedescribenesting
Files:
packages/leadtype/src/cli.test.tspackages/leadtype/src/llm/llm.test.ts
🪛 ast-grep (0.42.2)
packages/leadtype/src/llm/llm.ts
[warning] 1204-1204: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(^${source}$)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
🪛 LanguageTool
docs/changelog/nav-migration-prompts.mdx
[style] ~69-~69: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ar within each top-level docs area. - Use base for repeated folder prefixes. ...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~70-~70: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...base` for repeated folder prefixes. - Use explicit page strings for important ent...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~71-~71: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ation, configuration, and cli. - Use { include: "folder/*", sort: ["order",...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~127-~127: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...t, overview, and installation`. - Use wildcard includes for expandable areas ...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~128-~128: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ike component lists and hook lists. - Use a leading / for shared pages that liv...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~157-~157: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... useful nested headings for agents. - Check that wildcard sections do not pull unre...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
🪛 markdownlint-cli2 (0.22.1)
.changeset/config-driven-docs-nav.md
[warning] 5-5: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
🔇 Additional comments (31)
apps/example/scripts/docs-source-manifest.ts (1)
37-37: LGTM!apps/example/src/components/site-header.tsx (1)
4-4: LGTM!Also applies to: 80-95
packages/leadtype/src/llm/index.ts (1)
27-30: LGTM!.changeset/config-driven-docs-nav.md (1)
1-16: LGTM!apps/c15t-example/vite.config.ts (1)
44-44: LGTM!Also applies to: 49-51
apps/example/package.json (1)
7-7: LGTM!Also applies to: 9-9
packages/leadtype/scripts/generate-docs.ts (1)
34-34: LGTM!Also applies to: 56-56
apps/fumadocs-example/package.json (1)
10-10: LGTM!packages/leadtype/src/index.ts (1)
37-40: LGTM!apps/c15t-example/package.json (1)
8-8: LGTM!Also applies to: 10-10
packages/leadtype/src/source/index.ts (1)
44-44: LGTM!Also applies to: 108-109, 459-459
apps/example/playwright.config.ts (1)
5-5: LGTM!Also applies to: 19-20, 32-32
packages/leadtype/src/llm/readability.ts (1)
86-86: LGTM!docs/docs.config.ts (1)
18-18: LGTM!Also applies to: 30-73
docs/reference/evals.mdx (1)
20-20: LGTM!packages/leadtype/src/cli.test.ts (1)
244-244: LGTM!Also applies to: 257-257
apps/example/vite.config.ts (1)
35-37: LGTM!docs/build/build-a-docs-site.mdx (1)
73-77: LGTM!Also applies to: 81-82
docs/changelog/nav-migration-prompts.mdx (1)
1-169: LGTM!docs/authoring/frontmatter.mdx (1)
3-3: LGTM!Also applies to: 8-10, 23-23, 25-25, 27-31, 33-63, 88-88, 143-149
apps/example/src/components/docs-shell.tsx (1)
5-5: LGTM!Also applies to: 16-16
apps/example/scripts/llm-generate.ts (1)
42-42: LGTM!Also applies to: 49-49, 59-59
docs/build/generate-static-artifacts.mdx (1)
162-162: LGTM!Also applies to: 170-170, 184-184, 191-191
docs/package-docs/bundle.mdx (1)
114-114: LGTM!Also applies to: 117-117, 130-130
docs/how-it-works.mdx (1)
87-87: LGTM!Also applies to: 126-126
packages/leadtype/src/llm/llm.test.ts (1)
71-142: LGTM!Also applies to: 1284-1446
docs/reference/cli.mdx (1)
59-62: LGTM!Also applies to: 66-69, 153-153
apps/example/src/lib/docs.ts (1)
15-166: LGTM!docs/reference/llm.mdx (1)
44-44: LGTM!Also applies to: 134-134, 141-141, 148-148, 174-174, 181-181, 188-188, 419-419, 425-425, 436-436, 448-448, 460-460, 465-465
packages/leadtype/src/cli/generate.ts (1)
67-67: LGTM!Also applies to: 130-130, 175-175, 392-454, 521-525, 558-589, 596-596, 765-836, 841-859, 1411-1416, 1423-1433, 1443-1443, 1475-1475, 1485-1485, 1504-1504, 1515-1515, 1533-1533, 1551-1551, 1561-1561, 1578-1578, 1604-1604
packages/leadtype/src/llm/llm.ts (1)
36-37: LGTM!Also applies to: 66-68, 144-167, 212-213, 233-237, 275-277, 289-291, 301-303, 323-325, 357-359, 387-388, 410-477, 1060-1064, 1073-1073, 1156-1300, 1400-1458, 1516-1555, 1579-1619, 1646-1660, 1668-1668, 1682-1682, 1714-1731, 1781-1790, 1851-1853, 1871-1913, 1942-1950, 1985-2034, 2057-2057, 2087-2167, 2172-2173, 2193-2216
There was a problem hiding this comment.
No new issues. Reviewed the following changes:
- Extracted
frameworkStartPagesinapps/c15t-example/leadtype.config.tsand excluded it from the React-framework Guides wildcard so the per-group dedup change no longer surfacesquickstart/optimizationunder both Start and Guides.
Claude Opus | 𝕏
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@apps/c15t-example/leadtype.config.ts`:
- Around line 11-20: The arrays commonGuidePages and frameworkStartPages are
immutable config literals and should be declared with const assertions to make
them readonly literal tuples; update their declarations to use "as const" (e.g.,
change the definitions of commonGuidePages and frameworkStartPages to include
"as const") so the compiler treats their elements as literal types and prevents
accidental mutation in code that reuses them.
🪄 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: ASSERTIVE
Plan: Pro
Run ID: 68d4db21-fbe0-4a02-8e02-f26761ac89b5
📒 Files selected for processing (1)
apps/c15t-example/leadtype.config.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use explicit types for function parameters and return values when they enhance clarity
Preferunknownoveranywhen the type is genuinely unknown
Use const assertions (as const) for immutable values and literal types
Leverage TypeScript's type narrowing instead of type assertions
Files:
apps/c15t-example/leadtype.config.ts
**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{js,ts,jsx,tsx}: Use meaningful variable names instead of magic numbers - extract constants with descriptive names
Use arrow functions for callbacks and short functions
Preferfor...ofloops over.forEach()and indexedforloops
Use optional chaining (?.) and nullish coalescing (??) for safer property access
Prefer template literals over string concatenation
Use destructuring for object and array assignments
Useconstby default,letonly when reassignment is needed, nevervar
Alwaysawaitpromises in async functions - don't forget to use the return value
Useasync/awaitsyntax instead of promise chains for better readability
Handle errors appropriately in async code with try-catch blocks
Don't use async functions as Promise executors
Removeconsole.log,debugger, andalertstatements from production code
ThrowErrorobjects with descriptive messages, not strings or other values
Usetry-catchblocks meaningfully - don't catch errors just to rethrow them
Prefer early returns over nested conditionals for error cases
Extract complex conditions into well-named boolean variables
Use early returns to reduce nesting
Prefer simple conditionals over nested ternary operators
Don't useeval()or assign directly todocument.cookie
Avoid spread syntax in accumulators within loops
Use top-level regex literals instead of creating them in loops
Prefer specific imports over namespace imports
Use descriptive names for functions, variables, and types for meaningful naming
Add comments for complex logic, but prefer self-documenting code
Files:
apps/c15t-example/leadtype.config.ts
🔇 Additional comments (1)
apps/c15t-example/leadtype.config.ts (1)
22-40: LGTM!Also applies to: 42-53, 61-89

Summary
navfor curated docs IA with nested sections, explicit pages, wildcard includes, sorting, and root-relative page references.navthroughllms.txt, full-context files, Agent Readability,docs-nav.json, source navigation, and CLI generation.Validation
bun run --filter leadtype testbun run --filter leadtype check-typesbun run --filter example check-typesbun run --filter example buildbun x ultracite checkbun testwith 278 passing tests.