Skip to content

Centralize docs site configuration into single source of truth#1115

Open
r33drichards wants to merge 5 commits intomainfrom
claude/standardize-menu-order-NX1xc
Open

Centralize docs site configuration into single source of truth#1115
r33drichards wants to merge 5 commits intomainfrom
claude/standardize-menu-order-NX1xc

Conversation

@r33drichards
Copy link
Collaborator

@r33drichards r33drichards commented Feb 26, 2026

Summary

Extracted the hardcoded documentation site configuration from the custom header component into a centralized, reusable configuration file. This establishes a single source of truth for docs site metadata and enables automatic generation of related configuration files.

Key Changes

  • New file: docs/src/lib/docs-sites.ts - Created a centralized configuration module that exports:

    • DocsSiteConfig interface defining the structure for documentation sites
    • docsSites array containing configuration for all four documentation sites (Cua, Cua Bench, Cua-Bot, Lume)
    • sidebarPages derived from the main configuration for sidebar navigation
  • Updated: docs/src/components/custom-header.tsx - Refactored to:

    • Import configuration from the new centralized module
    • Separate logo assets into a siteLogos lookup object keyed by site slug
    • Dynamically merge logos with site configuration instead of maintaining duplicate data
  • New file: docs/scripts/sync-docs-meta.ts - Created a build script that:

    • Generates content/docs/meta.json from the centralized configuration
    • Runs automatically via prebuild and predev hooks
    • Can be run manually via pnpm docs:sync-meta
  • Updated: docs/package.json - Added:

    • prebuild and predev hooks to auto-sync metadata
    • docs:sync-meta script for manual synchronization
  • Updated: docs/content/docs/meta.json - Reformatted with proper JSON spacing (no functional change)

Implementation Details

The configuration is now maintainable from a single location. Logo assets remain as imports in the header component but are mapped to site slugs, eliminating duplication while keeping asset imports colocated with their usage. The sync script ensures the sidebar metadata stays in sync with the source configuration automatically.

https://claude.ai/code/session_012xmdj4JSbSFBDTUmvKMmfL

Summary by CodeRabbit

  • Chores
    • Automated documentation metadata synchronization now executes before builds and during development startup.
    • Consolidated all documentation site configuration into a single centralized source.
    • Documentation site metadata now includes comprehensive navigation and visual properties in unified configuration.

Swap Lume and Cua-Bot in the dropdown menu's docsSites array so both
the header dropdown and the left sidebar show products in the same
order: Cua, Cua Bench, Cua-Bot, Lume.

https://claude.ai/code/session_012xmdj4JSbSFBDTUmvKMmfL
Move the docsSites array from custom-header.tsx into a shared config
at src/lib/docs-sites.ts. The header component now imports from this
config and maps logos onto it. A new sync script generates
content/docs/meta.json from the same config, run automatically via
prebuild/predev hooks.

To change site order or add a new site, edit src/lib/docs-sites.ts —
both the dropdown and sidebar will update automatically.

https://claude.ai/code/session_012xmdj4JSbSFBDTUmvKMmfL
@vercel
Copy link
Contributor

vercel bot commented Feb 26, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview, Comment Feb 26, 2026 1:56am

Request Review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 26, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The changes introduce a centralized documentation sites configuration module and add a synchronization mechanism to generate metadata. A new docs/src/lib/docs-sites.ts file defines site configuration and metadata, and a new sync script generates content/docs/meta.json from this source. The build and dev processes were updated with prebuild and predev hooks to run the sync script automatically.

Changes

Cohort / File(s) Summary
Configuration & Data
docs/src/lib/docs-sites.ts
New module exporting DocsSiteConfig interface and docsSites array containing metadata for multiple documentation sites (Cua, Cua Bench, Cua-Bot, Lume) with navigation, icons, and descriptions; also exports sidebarPages derived from site slugs.
Synchronization Script
docs/scripts/sync-docs-meta.ts
New script that reads documentation site configuration from src/lib/docs-sites.ts, generates metadata with title and description, and writes a formatted JSON file to content/docs/meta.json.
Build Integration
docs/package.json
Added three npm scripts: prebuild and predev hooks to auto-run the sync script before build and dev, plus a manual docs:sync-meta script.
Component Refactoring
docs/src/components/custom-header.tsx
Replaced hard-coded docsSites array with dynamic construction from external docs-sites config; introduced logo mapping and merged site data, reducing file size while maintaining runtime behavior.
Metadata Formatting
docs/content/docs/meta.json
Reformatted "pages" array from single-line to multi-line, indented structure; no functional change.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A hop through configs, neat and clean,
From hard-coded chaos to a data routine,
The sync script hops between old and new,
Building metadata fresh and true! 📄✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main objective of the pull request: centralizing documentation site configuration into a single source of truth by extracting site definitions into docs/src/lib/docs-sites.ts.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/standardize-menu-order-NX1xc

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
docs/scripts/sync-docs-meta.ts (2)

1-1: Consider simplifying the shebang.

Since tsx is already a devDependency and the script is invoked via pnpm (which resolves local binaries), the npx prefix is unnecessary overhead. You could simplify to #!/usr/bin/env tsx or rely solely on the package.json script invocation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/scripts/sync-docs-meta.ts` at line 1, The shebang in the script
currently uses "/usr/bin/env npx tsx"; update it to the simpler "/usr/bin/env
tsx" (or remove the shebang and rely on the package.json script) so the script
uses the locally installed tsx binary without the unnecessary npx wrapper;
change the shebang line at the top of docs/scripts/sync-docs-meta.ts
accordingly.

19-19: Consider adding error handling for file write operations.

If the content/docs directory doesn't exist (e.g., after a fresh clone or accidental deletion), writeFileSync will throw. A defensive check or try-catch with a helpful error message would improve developer experience.

🛡️ Proposed fix to add directory check
+import { dirname } from 'node:path';
+
 const metaPath = path.resolve(__dirname, '..', 'content', 'docs', 'meta.json');
+
+// Ensure directory exists
+const dir = dirname(metaPath);
+if (!fs.existsSync(dir)) {
+  fs.mkdirSync(dir, { recursive: true });
+}
+
 const meta = {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/scripts/sync-docs-meta.ts` at line 19, The fs.writeFileSync(metaPath,
...) call can throw if the target directory is missing; before calling
fs.writeFileSync ensure the directory exists (e.g., call
fs.mkdirSync(path.dirname(metaPath), { recursive: true })) or wrap the write in
a try-catch that creates the directory on ENOENT and rethrows/logs a clear
error; update the code around the fs.writeFileSync invocation (referencing
metaPath and fs.writeFileSync) to perform the directory check/create or add the
try-catch with a helpful error message.
docs/src/components/custom-header.tsx (1)

24-34: Consider enforcing type alignment between siteLogos keys and docsSitesConfig slugs.

If a new site is added to docsSitesConfig without a corresponding entry in siteLogos, the merged object will have undefined logo properties. While the component handles missing logos gracefully (lines 80, 134), you could catch configuration drift at compile time:

💡 Optional: Type-safe slug keys
// In docs-sites.ts, export the slug union:
export type DocsSiteSlug = typeof docsSites[number]['slug'];

// In custom-header.tsx:
import type { DocsSiteSlug } from '@/lib/docs-sites';

const siteLogos: Record<DocsSiteSlug, { logoBlack: typeof LogoBlack; logoWhite: typeof LogoWhite }> = {
  cua: { logoBlack: LogoBlack, logoWhite: LogoWhite },
  // ... TypeScript will error if a slug is missing
};
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/src/components/custom-header.tsx` around lines 24 - 34, Ensure the keys
of siteLogos are type-locked to the slugs in docsSitesConfig to catch missing
logo entries at compile time: export a slug union type (e.g., DocsSiteSlug =
typeof docsSites[number]['slug']) from the module that defines docsSitesConfig,
import that type into custom-header.tsx, and change the siteLogos declaration to
Record<DocsSiteSlug, { logoBlack: typeof LogoBlack; logoWhite: typeof LogoWhite
}>, so TypeScript will raise an error if any docsSitesConfig slug lacks a
matching siteLogos entry; keep the existing docsSites mapping (which spreads
...siteLogos[site.slug]) unchanged.
🤖 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/scripts/sync-docs-meta.ts`:
- Line 1: The shebang in the script currently uses "/usr/bin/env npx tsx";
update it to the simpler "/usr/bin/env tsx" (or remove the shebang and rely on
the package.json script) so the script uses the locally installed tsx binary
without the unnecessary npx wrapper; change the shebang line at the top of
docs/scripts/sync-docs-meta.ts accordingly.
- Line 19: The fs.writeFileSync(metaPath, ...) call can throw if the target
directory is missing; before calling fs.writeFileSync ensure the directory
exists (e.g., call fs.mkdirSync(path.dirname(metaPath), { recursive: true })) or
wrap the write in a try-catch that creates the directory on ENOENT and
rethrows/logs a clear error; update the code around the fs.writeFileSync
invocation (referencing metaPath and fs.writeFileSync) to perform the directory
check/create or add the try-catch with a helpful error message.

In `@docs/src/components/custom-header.tsx`:
- Around line 24-34: Ensure the keys of siteLogos are type-locked to the slugs
in docsSitesConfig to catch missing logo entries at compile time: export a slug
union type (e.g., DocsSiteSlug = typeof docsSites[number]['slug']) from the
module that defines docsSitesConfig, import that type into custom-header.tsx,
and change the siteLogos declaration to Record<DocsSiteSlug, { logoBlack: typeof
LogoBlack; logoWhite: typeof LogoWhite }>, so TypeScript will raise an error if
any docsSitesConfig slug lacks a matching siteLogos entry; keep the existing
docsSites mapping (which spreads ...siteLogos[site.slug]) unchanged.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fb7e40a and 0ed3535.

📒 Files selected for processing (5)
  • docs/content/docs/meta.json
  • docs/package.json
  • docs/scripts/sync-docs-meta.ts
  • docs/src/components/custom-header.tsx
  • docs/src/lib/docs-sites.ts

Extend the sync script to write section-level meta.json files too,
not just the root one. This fixes the naming inconsistency where the
sidebar showed "Cua-Bench" but the dropdown showed "Cua Bench" — now
both derive titles, descriptions, and page order from docs-sites.ts.

https://claude.ai/code/session_012xmdj4JSbSFBDTUmvKMmfL
Add --exclude '^/' to the lychee external link checker so it skips
root-relative paths like /cua/guide/fundamentals/agent-loops. These
are internal links already validated by the next-validate-link job.

The --scheme http/https flags alone don't prevent lychee from
extracting bare paths from href attributes in MDX files. This was
broken in ebe9f88 which removed the original --exclude '^file://'
without accounting for root-relative paths.

https://claude.ai/code/session_012xmdj4JSbSFBDTUmvKMmfL
The previous --exclude '^/' approach failed because lychee errors
during URL construction before exclusion filters apply. Using
--base 'https://cua.ai' lets lychee resolve root-relative paths
to full URLs, which are then excluded by the existing cua\.ai pattern.

https://claude.ai/code/session_012xmdj4JSbSFBDTUmvKMmfL
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants