docs: derive section landing-page cards from the page tree + lint drift - #2567

Merged
pranaygp merged 1 commit into
mainfrom
pgp/docs-nit
Jun 22, 2026
Merged

docs: derive section landing-page cards from the page tree + lint drift#2567
pranaygp merged 1 commit into
mainfrom
pgp/docs-nit

Conversation

@pranaygp

@pranaygppranaygp commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Problem

Section landing pages (e.g. foundations/index.mdx) render a <Cards> grid that's supposed to link to every page in that section. That grid was hand-written, so it drifted from the two other representations of the same list:

  1. meta.jsonpages — the sidebar nav
  2. the actual .mdx files on disk
  3. the hand-written <Cards> in index.mdx

Concrete drift this fixes: v5/foundations was missing cancellation; v5/errors was missing abort-signal-timeout-in-workflow; and several meta.json entries pointed at pages that don't exist.

Approach (single source of truth + lint)

Hybrid: derive cards from the fumadocs page tree where possible, and lint-enforce parity everywhere else.

  • resolveSectionChildren(tree, url) (lib/geistdocs/section-children.ts) — walks the page tree (built from meta.json + frontmatter) and returns a section's children in nav order. Handles both leaf pages and sub-folders (folder.index). This one function is the shared source of truth.
  • <AutoCards /> (components/geistdocs/auto-cards.tsx) — renders the card grid from those children. Bound per-route in both docs routes so hrefs land in the right URL space (/docs/... for v4, /v5/docs/... for v5).
  • getLLMText expands <AutoCards/> into <Card> JSX in the markdown export, so llms.txt / .md / copy-page keep the child links (a bare <AutoCards/> tag would otherwise strip them from agent-facing markdown).
  • manualCards: true frontmatter opt-out (source.config.ts) for pages whose grid is intentionally curated (links outside the section, custom layout, deliberate omissions).
  • Two lint checks in scripts/lint.ts (already CI-gated via lint.yml):
    • checkSectionCards — every section index must use <AutoCards/>, set manualCards: true, or have a <Card> for every nav child.
    • checkMetaEntriesResolve — every plain-slug meta.json entry must resolve to a real page/folder.

Authoring model going forward

  • Exhaustive list<AutoCards /> (drift-proof; card text comes from each child's frontmatter title/description).
  • Curated / partial → keep hand-written <Cards> + manualCards: true.
  • Hand-written but should stay complete (e.g. getting-started's framework logos, grouped api-reference) → leave as-is; the lint fails if a nav child loses its card.

Content changes

  • Converted to <AutoCards/>: foundations and errors (both had real drift), v5 observability.
  • Marked manualCards: true: deploying (links /worlds, omits the world/ subfolder), ai (tutorial with a curated next-steps grid).
  • Removed dangling nav entries surfaced by the new meta check: v4 cancellation (foundations + how-it-works), root introduction (v4 + v5 — vestigial; /docs redirects to /docs/getting-started), v4/internal serializable-abort-controller (v5-only page).

Note on ai/index: treated as curated (kept its 4-item grid) rather than auto-listing all AI pages, since it's a tutorial. If those extra pages should appear there, switch it to <AutoCards/> and drop the flag.

Verification

  • bun ./scripts/lint.ts (the docs CI gate) passes; both new checks were confirmed to fail on injected drift (removed card / re-added dangling entry).
  • Full build: 690/690 static pages, all turbo tasks successful.
  • Runtime: v5 foundations cards now include cancellation in /v5/docs/...; errors lists all 15; markdown export expands <AutoCards/> to real card links.
  • Biome-clean on all changed files. No changeset needed (docs-only).

Docs Preview

Pages whose card grid changed (behind Vercel deployment protection — requires team access):

Pagev4v5
Foundations/docs/foundations/v5/docs/foundations
Errors/docs/errors/v5/docs/errors
Observability/v5/docs/observability

🤖 Generated with Claude Code

Section index card grids (e.g. foundations) were hand-written and drifted
from the sidebar (meta.json) and the actual pages. Make them derive from
the fumadocs page tree (single source of truth) and add CI lint so the
card grid and navigation can't fall out of sync again.
- resolveSectionChildren + <AutoCards/>, bound in both v4 and v5 docs
routes (correct /docs vs /v5/docs URL spaces)
- getLLMText expands <AutoCards/> so llms.txt/.md/copy-page keep child links
- manualCards frontmatter opt-out for curated pages (source.config.ts)
- checkSectionCards (card<->nav completeness) + checkMetaEntriesResolve
(dangling meta entries) in scripts/lint.ts
- convert foundations + errors (drift fixes) and v5 observability to AutoCards
- mark deploying + ai as manualCards (intentionally curated)
- remove dangling meta entries: v4 cancellation (x2), root introduction
(x2), v4/internal serializable-abort-controller
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@pranaygp
pranaygp requested review from a team and ijjk as code ownersJune 22, 2026 20:44
CopilotAI review requested due to automatic review settings June 22, 2026 20:44
@changeset-bot

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: ca5a2cd

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel

vercelBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@VaguelySeriousVaguelySerious left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@pranaygp
pranaygp merged commit 6fad87b into mainJun 22, 2026
58 checks passed
@pranaygp
pranaygp deleted the pgp/docs-nit branch June 22, 2026 21:37
pranaygp added a commit that referenced this pull request Jun 23, 2026
…testing
* origin/main:
Trace /flow route initialization (#2592)
Version Packages (beta) (#2591)
feat(web): add trace step shortcut helper (#2582)
[web-shared] reskin json viewer (no duplicates, better colours and navigation) (#2434)
Send occurredAt with workflow events (#2580)
docs: use actual eve logo and tidy OSS nav dropdown (#2586)
Display occurredAt in trace details (#2581)
fix(next): discover root entrypoints (#2564)
[core] Turbo: skip the unused run_started event-log preload (#2569)
fix(next): prewarm SWC plugin cache (#2538)
[world-vercel] Use v3 stream endpoint (supports transparent reconnect on timeout) (#2424)
[core] Retry stream reopen against the reconnect budget (#2334)
Add Platformatic World to worlds-manifest.json (#1450)
docs: derive section landing-page cards from the page tree + lint drift (#2567)
Sign up for freeto 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.

3 participants

@pranaygp@VaguelySerious
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

docs: derive section landing-page cards from the page tree + lint drift - #2567

Merged
pranaygp merged 1 commit into
mainfrom
pgp/docs-nit
Jun 22, 2026
Merged

docs: derive section landing-page cards from the page tree + lint drift#2567
pranaygp merged 1 commit into
mainfrom
pgp/docs-nit

Conversation

@pranaygp

@pranaygppranaygp commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Problem

Section landing pages (e.g. foundations/index.mdx) render a <Cards> grid that's supposed to link to every page in that section. That grid was hand-written, so it drifted from the two other representations of the same list:

  1. meta.jsonpages — the sidebar nav
  2. the actual .mdx files on disk
  3. the hand-written <Cards> in index.mdx

Concrete drift this fixes: v5/foundations was missing cancellation; v5/errors was missing abort-signal-timeout-in-workflow; and several meta.json entries pointed at pages that don't exist.

Approach (single source of truth + lint)

Hybrid: derive cards from the fumadocs page tree where possible, and lint-enforce parity everywhere else.

  • resolveSectionChildren(tree, url) (lib/geistdocs/section-children.ts) — walks the page tree (built from meta.json + frontmatter) and returns a section's children in nav order. Handles both leaf pages and sub-folders (folder.index). This one function is the shared source of truth.
  • <AutoCards /> (components/geistdocs/auto-cards.tsx) — renders the card grid from those children. Bound per-route in both docs routes so hrefs land in the right URL space (/docs/... for v4, /v5/docs/... for v5).
  • getLLMText expands <AutoCards/> into <Card> JSX in the markdown export, so llms.txt / .md / copy-page keep the child links (a bare <AutoCards/> tag would otherwise strip them from agent-facing markdown).
  • manualCards: true frontmatter opt-out (source.config.ts) for pages whose grid is intentionally curated (links outside the section, custom layout, deliberate omissions).
  • Two lint checks in scripts/lint.ts (already CI-gated via lint.yml):
    • checkSectionCards — every section index must use <AutoCards/>, set manualCards: true, or have a <Card> for every nav child.
    • checkMetaEntriesResolve — every plain-slug meta.json entry must resolve to a real page/folder.

Authoring model going forward

  • Exhaustive list<AutoCards /> (drift-proof; card text comes from each child's frontmatter title/description).
  • Curated / partial → keep hand-written <Cards> + manualCards: true.
  • Hand-written but should stay complete (e.g. getting-started's framework logos, grouped api-reference) → leave as-is; the lint fails if a nav child loses its card.

Content changes

  • Converted to <AutoCards/>: foundations and errors (both had real drift), v5 observability.
  • Marked manualCards: true: deploying (links /worlds, omits the world/ subfolder), ai (tutorial with a curated next-steps grid).
  • Removed dangling nav entries surfaced by the new meta check: v4 cancellation (foundations + how-it-works), root introduction (v4 + v5 — vestigial; /docs redirects to /docs/getting-started), v4/internal serializable-abort-controller (v5-only page).

Note on ai/index: treated as curated (kept its 4-item grid) rather than auto-listing all AI pages, since it's a tutorial. If those extra pages should appear there, switch it to <AutoCards/> and drop the flag.

Verification

  • bun ./scripts/lint.ts (the docs CI gate) passes; both new checks were confirmed to fail on injected drift (removed card / re-added dangling entry).
  • Full build: 690/690 static pages, all turbo tasks successful.
  • Runtime: v5 foundations cards now include cancellation in /v5/docs/...; errors lists all 15; markdown export expands <AutoCards/> to real card links.
  • Biome-clean on all changed files. No changeset needed (docs-only).

Docs Preview

Pages whose card grid changed (behind Vercel deployment protection — requires team access):

Pagev4v5
Foundations/docs/foundations/v5/docs/foundations
Errors/docs/errors/v5/docs/errors
Observability/v5/docs/observability

🤖 Generated with Claude Code

Section index card grids (e.g. foundations) were hand-written and drifted
from the sidebar (meta.json) and the actual pages. Make them derive from
the fumadocs page tree (single source of truth) and add CI lint so the
card grid and navigation can't fall out of sync again.
- resolveSectionChildren + <AutoCards/>, bound in both v4 and v5 docs
routes (correct /docs vs /v5/docs URL spaces)
- getLLMText expands <AutoCards/> so llms.txt/.md/copy-page keep child links
- manualCards frontmatter opt-out for curated pages (source.config.ts)
- checkSectionCards (card<->nav completeness) + checkMetaEntriesResolve
(dangling meta entries) in scripts/lint.ts
- convert foundations + errors (drift fixes) and v5 observability to AutoCards
- mark deploying + ai as manualCards (intentionally curated)
- remove dangling meta entries: v4 cancellation (x2), root introduction
(x2), v4/internal serializable-abort-controller
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@pranaygp
pranaygp requested review from a team and ijjk as code ownersJune 22, 2026 20:44
CopilotAI review requested due to automatic review settings June 22, 2026 20:44
@changeset-bot

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: ca5a2cd

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel

vercelBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@VaguelySeriousVaguelySerious left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@pranaygp
pranaygp merged commit 6fad87b into mainJun 22, 2026
58 checks passed
@pranaygp
pranaygp deleted the pgp/docs-nit branch June 22, 2026 21:37
pranaygp added a commit that referenced this pull request Jun 23, 2026
…testing
* origin/main:
Trace /flow route initialization (#2592)
Version Packages (beta) (#2591)
feat(web): add trace step shortcut helper (#2582)
[web-shared] reskin json viewer (no duplicates, better colours and navigation) (#2434)
Send occurredAt with workflow events (#2580)
docs: use actual eve logo and tidy OSS nav dropdown (#2586)
Display occurredAt in trace details (#2581)
fix(next): discover root entrypoints (#2564)
[core] Turbo: skip the unused run_started event-log preload (#2569)
fix(next): prewarm SWC plugin cache (#2538)
[world-vercel] Use v3 stream endpoint (supports transparent reconnect on timeout) (#2424)
[core] Retry stream reopen against the reconnect budget (#2334)
Add Platformatic World to worlds-manifest.json (#1450)
docs: derive section landing-page cards from the page tree + lint drift (#2567)
Sign up for freeto 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.

3 participants

@pranaygp@VaguelySerious
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs: derive section landing-page cards from the page tree + lint drift - #2567

Merged
pranaygp merged 1 commit into
mainfrom
pgp/docs-nit
Jun 22, 2026
Merged

docs: derive section landing-page cards from the page tree + lint drift#2567
pranaygp merged 1 commit into
mainfrom
pgp/docs-nit

Conversation

@pranaygp

@pranaygppranaygp commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Problem

Section landing pages (e.g. foundations/index.mdx) render a <Cards> grid that's supposed to link to every page in that section. That grid was hand-written, so it drifted from the two other representations of the same list:

  1. meta.jsonpages — the sidebar nav
  2. the actual .mdx files on disk
  3. the hand-written <Cards> in index.mdx

Concrete drift this fixes: v5/foundations was missing cancellation; v5/errors was missing abort-signal-timeout-in-workflow; and several meta.json entries pointed at pages that don't exist.

Approach (single source of truth + lint)

Hybrid: derive cards from the fumadocs page tree where possible, and lint-enforce parity everywhere else.

  • resolveSectionChildren(tree, url) (lib/geistdocs/section-children.ts) — walks the page tree (built from meta.json + frontmatter) and returns a section's children in nav order. Handles both leaf pages and sub-folders (folder.index). This one function is the shared source of truth.
  • <AutoCards /> (components/geistdocs/auto-cards.tsx) — renders the card grid from those children. Bound per-route in both docs routes so hrefs land in the right URL space (/docs/... for v4, /v5/docs/... for v5).
  • getLLMText expands <AutoCards/> into <Card> JSX in the markdown export, so llms.txt / .md / copy-page keep the child links (a bare <AutoCards/> tag would otherwise strip them from agent-facing markdown).
  • manualCards: true frontmatter opt-out (source.config.ts) for pages whose grid is intentionally curated (links outside the section, custom layout, deliberate omissions).
  • Two lint checks in scripts/lint.ts (already CI-gated via lint.yml):
    • checkSectionCards — every section index must use <AutoCards/>, set manualCards: true, or have a <Card> for every nav child.
    • checkMetaEntriesResolve — every plain-slug meta.json entry must resolve to a real page/folder.

Authoring model going forward

  • Exhaustive list<AutoCards /> (drift-proof; card text comes from each child's frontmatter title/description).
  • Curated / partial → keep hand-written <Cards> + manualCards: true.
  • Hand-written but should stay complete (e.g. getting-started's framework logos, grouped api-reference) → leave as-is; the lint fails if a nav child loses its card.

Content changes

  • Converted to <AutoCards/>: foundations and errors (both had real drift), v5 observability.
  • Marked manualCards: true: deploying (links /worlds, omits the world/ subfolder), ai (tutorial with a curated next-steps grid).
  • Removed dangling nav entries surfaced by the new meta check: v4 cancellation (foundations + how-it-works), root introduction (v4 + v5 — vestigial; /docs redirects to /docs/getting-started), v4/internal serializable-abort-controller (v5-only page).

Note on ai/index: treated as curated (kept its 4-item grid) rather than auto-listing all AI pages, since it's a tutorial. If those extra pages should appear there, switch it to <AutoCards/> and drop the flag.

Verification

  • bun ./scripts/lint.ts (the docs CI gate) passes; both new checks were confirmed to fail on injected drift (removed card / re-added dangling entry).
  • Full build: 690/690 static pages, all turbo tasks successful.
  • Runtime: v5 foundations cards now include cancellation in /v5/docs/...; errors lists all 15; markdown export expands <AutoCards/> to real card links.
  • Biome-clean on all changed files. No changeset needed (docs-only).

Docs Preview

Pages whose card grid changed (behind Vercel deployment protection — requires team access):

Pagev4v5
Foundations/docs/foundations/v5/docs/foundations
Errors/docs/errors/v5/docs/errors
Observability/v5/docs/observability

🤖 Generated with Claude Code

Section index card grids (e.g. foundations) were hand-written and drifted
from the sidebar (meta.json) and the actual pages. Make them derive from
the fumadocs page tree (single source of truth) and add CI lint so the
card grid and navigation can't fall out of sync again.
- resolveSectionChildren + <AutoCards/>, bound in both v4 and v5 docs
routes (correct /docs vs /v5/docs URL spaces)
- getLLMText expands <AutoCards/> so llms.txt/.md/copy-page keep child links
- manualCards frontmatter opt-out for curated pages (source.config.ts)
- checkSectionCards (card<->nav completeness) + checkMetaEntriesResolve
(dangling meta entries) in scripts/lint.ts
- convert foundations + errors (drift fixes) and v5 observability to AutoCards
- mark deploying + ai as manualCards (intentionally curated)
- remove dangling meta entries: v4 cancellation (x2), root introduction
(x2), v4/internal serializable-abort-controller
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@pranaygp
pranaygp requested review from a team and ijjk as code ownersJune 22, 2026 20:44
CopilotAI review requested due to automatic review settings June 22, 2026 20:44
@changeset-bot

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: ca5a2cd

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel

vercelBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@VaguelySeriousVaguelySerious left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@pranaygp
pranaygp merged commit 6fad87b into mainJun 22, 2026
58 checks passed
@pranaygp
pranaygp deleted the pgp/docs-nit branch June 22, 2026 21:37
pranaygp added a commit that referenced this pull request Jun 23, 2026
…testing
* origin/main:
Trace /flow route initialization (#2592)
Version Packages (beta) (#2591)
feat(web): add trace step shortcut helper (#2582)
[web-shared] reskin json viewer (no duplicates, better colours and navigation) (#2434)
Send occurredAt with workflow events (#2580)
docs: use actual eve logo and tidy OSS nav dropdown (#2586)
Display occurredAt in trace details (#2581)
fix(next): discover root entrypoints (#2564)
[core] Turbo: skip the unused run_started event-log preload (#2569)
fix(next): prewarm SWC plugin cache (#2538)
[world-vercel] Use v3 stream endpoint (supports transparent reconnect on timeout) (#2424)
[core] Retry stream reopen against the reconnect budget (#2334)
Add Platformatic World to worlds-manifest.json (#1450)
docs: derive section landing-page cards from the page tree + lint drift (#2567)
Sign up for freeto 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.

3 participants

@pranaygp@VaguelySerious
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs: derive section landing-page cards from the page tree + lint drift - #2567

Merged
pranaygp merged 1 commit into
mainfrom
pgp/docs-nit
Jun 22, 2026
Merged

docs: derive section landing-page cards from the page tree + lint drift#2567
pranaygp merged 1 commit into
mainfrom
pgp/docs-nit

Conversation

@pranaygp

@pranaygppranaygp commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Problem

Section landing pages (e.g. foundations/index.mdx) render a <Cards> grid that's supposed to link to every page in that section. That grid was hand-written, so it drifted from the two other representations of the same list:

  1. meta.jsonpages — the sidebar nav
  2. the actual .mdx files on disk
  3. the hand-written <Cards> in index.mdx

Concrete drift this fixes: v5/foundations was missing cancellation; v5/errors was missing abort-signal-timeout-in-workflow; and several meta.json entries pointed at pages that don't exist.

Approach (single source of truth + lint)

Hybrid: derive cards from the fumadocs page tree where possible, and lint-enforce parity everywhere else.

  • resolveSectionChildren(tree, url) (lib/geistdocs/section-children.ts) — walks the page tree (built from meta.json + frontmatter) and returns a section's children in nav order. Handles both leaf pages and sub-folders (folder.index). This one function is the shared source of truth.
  • <AutoCards /> (components/geistdocs/auto-cards.tsx) — renders the card grid from those children. Bound per-route in both docs routes so hrefs land in the right URL space (/docs/... for v4, /v5/docs/... for v5).
  • getLLMText expands <AutoCards/> into <Card> JSX in the markdown export, so llms.txt / .md / copy-page keep the child links (a bare <AutoCards/> tag would otherwise strip them from agent-facing markdown).
  • manualCards: true frontmatter opt-out (source.config.ts) for pages whose grid is intentionally curated (links outside the section, custom layout, deliberate omissions).
  • Two lint checks in scripts/lint.ts (already CI-gated via lint.yml):
    • checkSectionCards — every section index must use <AutoCards/>, set manualCards: true, or have a <Card> for every nav child.
    • checkMetaEntriesResolve — every plain-slug meta.json entry must resolve to a real page/folder.

Authoring model going forward

  • Exhaustive list<AutoCards /> (drift-proof; card text comes from each child's frontmatter title/description).
  • Curated / partial → keep hand-written <Cards> + manualCards: true.
  • Hand-written but should stay complete (e.g. getting-started's framework logos, grouped api-reference) → leave as-is; the lint fails if a nav child loses its card.

Content changes

  • Converted to <AutoCards/>: foundations and errors (both had real drift), v5 observability.
  • Marked manualCards: true: deploying (links /worlds, omits the world/ subfolder), ai (tutorial with a curated next-steps grid).
  • Removed dangling nav entries surfaced by the new meta check: v4 cancellation (foundations + how-it-works), root introduction (v4 + v5 — vestigial; /docs redirects to /docs/getting-started), v4/internal serializable-abort-controller (v5-only page).

Note on ai/index: treated as curated (kept its 4-item grid) rather than auto-listing all AI pages, since it's a tutorial. If those extra pages should appear there, switch it to <AutoCards/> and drop the flag.

Verification

  • bun ./scripts/lint.ts (the docs CI gate) passes; both new checks were confirmed to fail on injected drift (removed card / re-added dangling entry).
  • Full build: 690/690 static pages, all turbo tasks successful.
  • Runtime: v5 foundations cards now include cancellation in /v5/docs/...; errors lists all 15; markdown export expands <AutoCards/> to real card links.
  • Biome-clean on all changed files. No changeset needed (docs-only).

Docs Preview

Pages whose card grid changed (behind Vercel deployment protection — requires team access):

Pagev4v5
Foundations/docs/foundations/v5/docs/foundations
Errors/docs/errors/v5/docs/errors
Observability/v5/docs/observability

🤖 Generated with Claude Code

Section index card grids (e.g. foundations) were hand-written and drifted
from the sidebar (meta.json) and the actual pages. Make them derive from
the fumadocs page tree (single source of truth) and add CI lint so the
card grid and navigation can't fall out of sync again.
- resolveSectionChildren + <AutoCards/>, bound in both v4 and v5 docs
routes (correct /docs vs /v5/docs URL spaces)
- getLLMText expands <AutoCards/> so llms.txt/.md/copy-page keep child links
- manualCards frontmatter opt-out for curated pages (source.config.ts)
- checkSectionCards (card<->nav completeness) + checkMetaEntriesResolve
(dangling meta entries) in scripts/lint.ts
- convert foundations + errors (drift fixes) and v5 observability to AutoCards
- mark deploying + ai as manualCards (intentionally curated)
- remove dangling meta entries: v4 cancellation (x2), root introduction
(x2), v4/internal serializable-abort-controller
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@pranaygp
pranaygp requested review from a team and ijjk as code ownersJune 22, 2026 20:44
CopilotAI review requested due to automatic review settings June 22, 2026 20:44
@changeset-bot

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: ca5a2cd

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel

vercelBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@VaguelySeriousVaguelySerious left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@pranaygp
pranaygp merged commit 6fad87b into mainJun 22, 2026
58 checks passed
@pranaygp
pranaygp deleted the pgp/docs-nit branch June 22, 2026 21:37
pranaygp added a commit that referenced this pull request Jun 23, 2026
…testing
* origin/main:
Trace /flow route initialization (#2592)
Version Packages (beta) (#2591)
feat(web): add trace step shortcut helper (#2582)
[web-shared] reskin json viewer (no duplicates, better colours and navigation) (#2434)
Send occurredAt with workflow events (#2580)
docs: use actual eve logo and tidy OSS nav dropdown (#2586)
Display occurredAt in trace details (#2581)
fix(next): discover root entrypoints (#2564)
[core] Turbo: skip the unused run_started event-log preload (#2569)
fix(next): prewarm SWC plugin cache (#2538)
[world-vercel] Use v3 stream endpoint (supports transparent reconnect on timeout) (#2424)
[core] Retry stream reopen against the reconnect budget (#2334)
Add Platformatic World to worlds-manifest.json (#1450)
docs: derive section landing-page cards from the page tree + lint drift (#2567)
Sign up for freeto 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.

3 participants

@pranaygp@VaguelySerious
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

docs: derive section landing-page cards from the page tree + lint drift - #2567

Merged
pranaygp merged 1 commit into
mainfrom
pgp/docs-nit
Jun 22, 2026
Merged

docs: derive section landing-page cards from the page tree + lint drift#2567
pranaygp merged 1 commit into
mainfrom
pgp/docs-nit

Conversation

@pranaygp

@pranaygppranaygp commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Problem

Section landing pages (e.g. foundations/index.mdx) render a <Cards> grid that's supposed to link to every page in that section. That grid was hand-written, so it drifted from the two other representations of the same list:

  1. meta.jsonpages — the sidebar nav
  2. the actual .mdx files on disk
  3. the hand-written <Cards> in index.mdx

Concrete drift this fixes: v5/foundations was missing cancellation; v5/errors was missing abort-signal-timeout-in-workflow; and several meta.json entries pointed at pages that don't exist.

Approach (single source of truth + lint)

Hybrid: derive cards from the fumadocs page tree where possible, and lint-enforce parity everywhere else.

  • resolveSectionChildren(tree, url) (lib/geistdocs/section-children.ts) — walks the page tree (built from meta.json + frontmatter) and returns a section's children in nav order. Handles both leaf pages and sub-folders (folder.index). This one function is the shared source of truth.
  • <AutoCards /> (components/geistdocs/auto-cards.tsx) — renders the card grid from those children. Bound per-route in both docs routes so hrefs land in the right URL space (/docs/... for v4, /v5/docs/... for v5).
  • getLLMText expands <AutoCards/> into <Card> JSX in the markdown export, so llms.txt / .md / copy-page keep the child links (a bare <AutoCards/> tag would otherwise strip them from agent-facing markdown).
  • manualCards: true frontmatter opt-out (source.config.ts) for pages whose grid is intentionally curated (links outside the section, custom layout, deliberate omissions).
  • Two lint checks in scripts/lint.ts (already CI-gated via lint.yml):
    • checkSectionCards — every section index must use <AutoCards/>, set manualCards: true, or have a <Card> for every nav child.
    • checkMetaEntriesResolve — every plain-slug meta.json entry must resolve to a real page/folder.

Authoring model going forward

  • Exhaustive list<AutoCards /> (drift-proof; card text comes from each child's frontmatter title/description).
  • Curated / partial → keep hand-written <Cards> + manualCards: true.
  • Hand-written but should stay complete (e.g. getting-started's framework logos, grouped api-reference) → leave as-is; the lint fails if a nav child loses its card.

Content changes

  • Converted to <AutoCards/>: foundations and errors (both had real drift), v5 observability.
  • Marked manualCards: true: deploying (links /worlds, omits the world/ subfolder), ai (tutorial with a curated next-steps grid).
  • Removed dangling nav entries surfaced by the new meta check: v4 cancellation (foundations + how-it-works), root introduction (v4 + v5 — vestigial; /docs redirects to /docs/getting-started), v4/internal serializable-abort-controller (v5-only page).

Note on ai/index: treated as curated (kept its 4-item grid) rather than auto-listing all AI pages, since it's a tutorial. If those extra pages should appear there, switch it to <AutoCards/> and drop the flag.

Verification

  • bun ./scripts/lint.ts (the docs CI gate) passes; both new checks were confirmed to fail on injected drift (removed card / re-added dangling entry).
  • Full build: 690/690 static pages, all turbo tasks successful.
  • Runtime: v5 foundations cards now include cancellation in /v5/docs/...; errors lists all 15; markdown export expands <AutoCards/> to real card links.
  • Biome-clean on all changed files. No changeset needed (docs-only).

Docs Preview

Pages whose card grid changed (behind Vercel deployment protection — requires team access):

Pagev4v5
Foundations/docs/foundations/v5/docs/foundations
Errors/docs/errors/v5/docs/errors
Observability/v5/docs/observability

🤖 Generated with Claude Code

Section index card grids (e.g. foundations) were hand-written and drifted
from the sidebar (meta.json) and the actual pages. Make them derive from
the fumadocs page tree (single source of truth) and add CI lint so the
card grid and navigation can't fall out of sync again.
- resolveSectionChildren + <AutoCards/>, bound in both v4 and v5 docs
routes (correct /docs vs /v5/docs URL spaces)
- getLLMText expands <AutoCards/> so llms.txt/.md/copy-page keep child links
- manualCards frontmatter opt-out for curated pages (source.config.ts)
- checkSectionCards (card<->nav completeness) + checkMetaEntriesResolve
(dangling meta entries) in scripts/lint.ts
- convert foundations + errors (drift fixes) and v5 observability to AutoCards
- mark deploying + ai as manualCards (intentionally curated)
- remove dangling meta entries: v4 cancellation (x2), root introduction
(x2), v4/internal serializable-abort-controller
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@pranaygp
pranaygp requested review from a team and ijjk as code ownersJune 22, 2026 20:44
CopilotAI review requested due to automatic review settings June 22, 2026 20:44
@changeset-bot

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: ca5a2cd

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel

vercelBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@VaguelySeriousVaguelySerious left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@pranaygp
pranaygp merged commit 6fad87b into mainJun 22, 2026
58 checks passed
@pranaygp
pranaygp deleted the pgp/docs-nit branch June 22, 2026 21:37
pranaygp added a commit that referenced this pull request Jun 23, 2026
…testing
* origin/main:
Trace /flow route initialization (#2592)
Version Packages (beta) (#2591)
feat(web): add trace step shortcut helper (#2582)
[web-shared] reskin json viewer (no duplicates, better colours and navigation) (#2434)
Send occurredAt with workflow events (#2580)
docs: use actual eve logo and tidy OSS nav dropdown (#2586)
Display occurredAt in trace details (#2581)
fix(next): discover root entrypoints (#2564)
[core] Turbo: skip the unused run_started event-log preload (#2569)
fix(next): prewarm SWC plugin cache (#2538)
[world-vercel] Use v3 stream endpoint (supports transparent reconnect on timeout) (#2424)
[core] Retry stream reopen against the reconnect budget (#2334)
Add Platformatic World to worlds-manifest.json (#1450)
docs: derive section landing-page cards from the page tree + lint drift (#2567)
Sign up for freeto 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.

3 participants

@pranaygp@VaguelySerious
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs: derive section landing-page cards from the page tree + lint drift - #2567

Merged
pranaygp merged 1 commit into
mainfrom
pgp/docs-nit
Jun 22, 2026
Merged

docs: derive section landing-page cards from the page tree + lint drift#2567
pranaygp merged 1 commit into
mainfrom
pgp/docs-nit

Conversation

@pranaygp

@pranaygppranaygp commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Problem

Section landing pages (e.g. foundations/index.mdx) render a <Cards> grid that's supposed to link to every page in that section. That grid was hand-written, so it drifted from the two other representations of the same list:

  1. meta.jsonpages — the sidebar nav
  2. the actual .mdx files on disk
  3. the hand-written <Cards> in index.mdx

Concrete drift this fixes: v5/foundations was missing cancellation; v5/errors was missing abort-signal-timeout-in-workflow; and several meta.json entries pointed at pages that don't exist.

Approach (single source of truth + lint)

Hybrid: derive cards from the fumadocs page tree where possible, and lint-enforce parity everywhere else.

  • resolveSectionChildren(tree, url) (lib/geistdocs/section-children.ts) — walks the page tree (built from meta.json + frontmatter) and returns a section's children in nav order. Handles both leaf pages and sub-folders (folder.index). This one function is the shared source of truth.
  • <AutoCards /> (components/geistdocs/auto-cards.tsx) — renders the card grid from those children. Bound per-route in both docs routes so hrefs land in the right URL space (/docs/... for v4, /v5/docs/... for v5).
  • getLLMText expands <AutoCards/> into <Card> JSX in the markdown export, so llms.txt / .md / copy-page keep the child links (a bare <AutoCards/> tag would otherwise strip them from agent-facing markdown).
  • manualCards: true frontmatter opt-out (source.config.ts) for pages whose grid is intentionally curated (links outside the section, custom layout, deliberate omissions).
  • Two lint checks in scripts/lint.ts (already CI-gated via lint.yml):
    • checkSectionCards — every section index must use <AutoCards/>, set manualCards: true, or have a <Card> for every nav child.
    • checkMetaEntriesResolve — every plain-slug meta.json entry must resolve to a real page/folder.

Authoring model going forward

  • Exhaustive list<AutoCards /> (drift-proof; card text comes from each child's frontmatter title/description).
  • Curated / partial → keep hand-written <Cards> + manualCards: true.
  • Hand-written but should stay complete (e.g. getting-started's framework logos, grouped api-reference) → leave as-is; the lint fails if a nav child loses its card.

Content changes

  • Converted to <AutoCards/>: foundations and errors (both had real drift), v5 observability.
  • Marked manualCards: true: deploying (links /worlds, omits the world/ subfolder), ai (tutorial with a curated next-steps grid).
  • Removed dangling nav entries surfaced by the new meta check: v4 cancellation (foundations + how-it-works), root introduction (v4 + v5 — vestigial; /docs redirects to /docs/getting-started), v4/internal serializable-abort-controller (v5-only page).

Note on ai/index: treated as curated (kept its 4-item grid) rather than auto-listing all AI pages, since it's a tutorial. If those extra pages should appear there, switch it to <AutoCards/> and drop the flag.

Verification

  • bun ./scripts/lint.ts (the docs CI gate) passes; both new checks were confirmed to fail on injected drift (removed card / re-added dangling entry).
  • Full build: 690/690 static pages, all turbo tasks successful.
  • Runtime: v5 foundations cards now include cancellation in /v5/docs/...; errors lists all 15; markdown export expands <AutoCards/> to real card links.
  • Biome-clean on all changed files. No changeset needed (docs-only).

Docs Preview

Pages whose card grid changed (behind Vercel deployment protection — requires team access):

Pagev4v5
Foundations/docs/foundations/v5/docs/foundations
Errors/docs/errors/v5/docs/errors
Observability/v5/docs/observability

🤖 Generated with Claude Code

Section index card grids (e.g. foundations) were hand-written and drifted
from the sidebar (meta.json) and the actual pages. Make them derive from
the fumadocs page tree (single source of truth) and add CI lint so the
card grid and navigation can't fall out of sync again.
- resolveSectionChildren + <AutoCards/>, bound in both v4 and v5 docs
routes (correct /docs vs /v5/docs URL spaces)
- getLLMText expands <AutoCards/> so llms.txt/.md/copy-page keep child links
- manualCards frontmatter opt-out for curated pages (source.config.ts)
- checkSectionCards (card<->nav completeness) + checkMetaEntriesResolve
(dangling meta entries) in scripts/lint.ts
- convert foundations + errors (drift fixes) and v5 observability to AutoCards
- mark deploying + ai as manualCards (intentionally curated)
- remove dangling meta entries: v4 cancellation (x2), root introduction
(x2), v4/internal serializable-abort-controller
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@pranaygp
pranaygp requested review from a team and ijjk as code ownersJune 22, 2026 20:44
CopilotAI review requested due to automatic review settings June 22, 2026 20:44
@changeset-bot

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: ca5a2cd

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel

vercelBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@VaguelySeriousVaguelySerious left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@pranaygp
pranaygp merged commit 6fad87b into mainJun 22, 2026
58 checks passed
@pranaygp
pranaygp deleted the pgp/docs-nit branch June 22, 2026 21:37
pranaygp added a commit that referenced this pull request Jun 23, 2026
…testing
* origin/main:
Trace /flow route initialization (#2592)
Version Packages (beta) (#2591)
feat(web): add trace step shortcut helper (#2582)
[web-shared] reskin json viewer (no duplicates, better colours and navigation) (#2434)
Send occurredAt with workflow events (#2580)
docs: use actual eve logo and tidy OSS nav dropdown (#2586)
Display occurredAt in trace details (#2581)
fix(next): discover root entrypoints (#2564)
[core] Turbo: skip the unused run_started event-log preload (#2569)
fix(next): prewarm SWC plugin cache (#2538)
[world-vercel] Use v3 stream endpoint (supports transparent reconnect on timeout) (#2424)
[core] Retry stream reopen against the reconnect budget (#2334)
Add Platformatic World to worlds-manifest.json (#1450)
docs: derive section landing-page cards from the page tree + lint drift (#2567)
Sign up for freeto 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.

3 participants

@pranaygp@VaguelySerious
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs: derive section landing-page cards from the page tree + lint drift - #2567

Merged
pranaygp merged 1 commit into
mainfrom
pgp/docs-nit
Jun 22, 2026
Merged

docs: derive section landing-page cards from the page tree + lint drift#2567
pranaygp merged 1 commit into
mainfrom
pgp/docs-nit

Conversation

@pranaygp

@pranaygppranaygp commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Problem

Section landing pages (e.g. foundations/index.mdx) render a <Cards> grid that's supposed to link to every page in that section. That grid was hand-written, so it drifted from the two other representations of the same list:

  1. meta.jsonpages — the sidebar nav
  2. the actual .mdx files on disk
  3. the hand-written <Cards> in index.mdx

Concrete drift this fixes: v5/foundations was missing cancellation; v5/errors was missing abort-signal-timeout-in-workflow; and several meta.json entries pointed at pages that don't exist.

Approach (single source of truth + lint)

Hybrid: derive cards from the fumadocs page tree where possible, and lint-enforce parity everywhere else.

  • resolveSectionChildren(tree, url) (lib/geistdocs/section-children.ts) — walks the page tree (built from meta.json + frontmatter) and returns a section's children in nav order. Handles both leaf pages and sub-folders (folder.index). This one function is the shared source of truth.
  • <AutoCards /> (components/geistdocs/auto-cards.tsx) — renders the card grid from those children. Bound per-route in both docs routes so hrefs land in the right URL space (/docs/... for v4, /v5/docs/... for v5).
  • getLLMText expands <AutoCards/> into <Card> JSX in the markdown export, so llms.txt / .md / copy-page keep the child links (a bare <AutoCards/> tag would otherwise strip them from agent-facing markdown).
  • manualCards: true frontmatter opt-out (source.config.ts) for pages whose grid is intentionally curated (links outside the section, custom layout, deliberate omissions).
  • Two lint checks in scripts/lint.ts (already CI-gated via lint.yml):
    • checkSectionCards — every section index must use <AutoCards/>, set manualCards: true, or have a <Card> for every nav child.
    • checkMetaEntriesResolve — every plain-slug meta.json entry must resolve to a real page/folder.

Authoring model going forward

  • Exhaustive list<AutoCards /> (drift-proof; card text comes from each child's frontmatter title/description).
  • Curated / partial → keep hand-written <Cards> + manualCards: true.
  • Hand-written but should stay complete (e.g. getting-started's framework logos, grouped api-reference) → leave as-is; the lint fails if a nav child loses its card.

Content changes

  • Converted to <AutoCards/>: foundations and errors (both had real drift), v5 observability.
  • Marked manualCards: true: deploying (links /worlds, omits the world/ subfolder), ai (tutorial with a curated next-steps grid).
  • Removed dangling nav entries surfaced by the new meta check: v4 cancellation (foundations + how-it-works), root introduction (v4 + v5 — vestigial; /docs redirects to /docs/getting-started), v4/internal serializable-abort-controller (v5-only page).

Note on ai/index: treated as curated (kept its 4-item grid) rather than auto-listing all AI pages, since it's a tutorial. If those extra pages should appear there, switch it to <AutoCards/> and drop the flag.

Verification

  • bun ./scripts/lint.ts (the docs CI gate) passes; both new checks were confirmed to fail on injected drift (removed card / re-added dangling entry).
  • Full build: 690/690 static pages, all turbo tasks successful.
  • Runtime: v5 foundations cards now include cancellation in /v5/docs/...; errors lists all 15; markdown export expands <AutoCards/> to real card links.
  • Biome-clean on all changed files. No changeset needed (docs-only).

Docs Preview

Pages whose card grid changed (behind Vercel deployment protection — requires team access):

Pagev4v5
Foundations/docs/foundations/v5/docs/foundations
Errors/docs/errors/v5/docs/errors
Observability/v5/docs/observability

🤖 Generated with Claude Code

Section index card grids (e.g. foundations) were hand-written and drifted
from the sidebar (meta.json) and the actual pages. Make them derive from
the fumadocs page tree (single source of truth) and add CI lint so the
card grid and navigation can't fall out of sync again.
- resolveSectionChildren + <AutoCards/>, bound in both v4 and v5 docs
routes (correct /docs vs /v5/docs URL spaces)
- getLLMText expands <AutoCards/> so llms.txt/.md/copy-page keep child links
- manualCards frontmatter opt-out for curated pages (source.config.ts)
- checkSectionCards (card<->nav completeness) + checkMetaEntriesResolve
(dangling meta entries) in scripts/lint.ts
- convert foundations + errors (drift fixes) and v5 observability to AutoCards
- mark deploying + ai as manualCards (intentionally curated)
- remove dangling meta entries: v4 cancellation (x2), root introduction
(x2), v4/internal serializable-abort-controller
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@pranaygp
pranaygp requested review from a team and ijjk as code ownersJune 22, 2026 20:44
CopilotAI review requested due to automatic review settings June 22, 2026 20:44
@changeset-bot

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: ca5a2cd

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel

vercelBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@VaguelySeriousVaguelySerious left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@pranaygp
pranaygp merged commit 6fad87b into mainJun 22, 2026
58 checks passed
@pranaygp
pranaygp deleted the pgp/docs-nit branch June 22, 2026 21:37
pranaygp added a commit that referenced this pull request Jun 23, 2026
…testing
* origin/main:
Trace /flow route initialization (#2592)
Version Packages (beta) (#2591)
feat(web): add trace step shortcut helper (#2582)
[web-shared] reskin json viewer (no duplicates, better colours and navigation) (#2434)
Send occurredAt with workflow events (#2580)
docs: use actual eve logo and tidy OSS nav dropdown (#2586)
Display occurredAt in trace details (#2581)
fix(next): discover root entrypoints (#2564)
[core] Turbo: skip the unused run_started event-log preload (#2569)
fix(next): prewarm SWC plugin cache (#2538)
[world-vercel] Use v3 stream endpoint (supports transparent reconnect on timeout) (#2424)
[core] Retry stream reopen against the reconnect budget (#2334)
Add Platformatic World to worlds-manifest.json (#1450)
docs: derive section landing-page cards from the page tree + lint drift (#2567)
Sign up for freeto 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.

3 participants

@pranaygp@VaguelySerious
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

docs: derive section landing-page cards from the page tree + lint drift - #2567

Merged
pranaygp merged 1 commit into
mainfrom
pgp/docs-nit
Jun 22, 2026
Merged

docs: derive section landing-page cards from the page tree + lint drift#2567
pranaygp merged 1 commit into
mainfrom
pgp/docs-nit

Conversation

@pranaygp

@pranaygppranaygp commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Problem

Section landing pages (e.g. foundations/index.mdx) render a <Cards> grid that's supposed to link to every page in that section. That grid was hand-written, so it drifted from the two other representations of the same list:

  1. meta.jsonpages — the sidebar nav
  2. the actual .mdx files on disk
  3. the hand-written <Cards> in index.mdx

Concrete drift this fixes: v5/foundations was missing cancellation; v5/errors was missing abort-signal-timeout-in-workflow; and several meta.json entries pointed at pages that don't exist.

Approach (single source of truth + lint)

Hybrid: derive cards from the fumadocs page tree where possible, and lint-enforce parity everywhere else.

  • resolveSectionChildren(tree, url) (lib/geistdocs/section-children.ts) — walks the page tree (built from meta.json + frontmatter) and returns a section's children in nav order. Handles both leaf pages and sub-folders (folder.index). This one function is the shared source of truth.
  • <AutoCards /> (components/geistdocs/auto-cards.tsx) — renders the card grid from those children. Bound per-route in both docs routes so hrefs land in the right URL space (/docs/... for v4, /v5/docs/... for v5).
  • getLLMText expands <AutoCards/> into <Card> JSX in the markdown export, so llms.txt / .md / copy-page keep the child links (a bare <AutoCards/> tag would otherwise strip them from agent-facing markdown).
  • manualCards: true frontmatter opt-out (source.config.ts) for pages whose grid is intentionally curated (links outside the section, custom layout, deliberate omissions).
  • Two lint checks in scripts/lint.ts (already CI-gated via lint.yml):
    • checkSectionCards — every section index must use <AutoCards/>, set manualCards: true, or have a <Card> for every nav child.
    • checkMetaEntriesResolve — every plain-slug meta.json entry must resolve to a real page/folder.

Authoring model going forward

  • Exhaustive list<AutoCards /> (drift-proof; card text comes from each child's frontmatter title/description).
  • Curated / partial → keep hand-written <Cards> + manualCards: true.
  • Hand-written but should stay complete (e.g. getting-started's framework logos, grouped api-reference) → leave as-is; the lint fails if a nav child loses its card.

Content changes

  • Converted to <AutoCards/>: foundations and errors (both had real drift), v5 observability.
  • Marked manualCards: true: deploying (links /worlds, omits the world/ subfolder), ai (tutorial with a curated next-steps grid).
  • Removed dangling nav entries surfaced by the new meta check: v4 cancellation (foundations + how-it-works), root introduction (v4 + v5 — vestigial; /docs redirects to /docs/getting-started), v4/internal serializable-abort-controller (v5-only page).

Note on ai/index: treated as curated (kept its 4-item grid) rather than auto-listing all AI pages, since it's a tutorial. If those extra pages should appear there, switch it to <AutoCards/> and drop the flag.

Verification

  • bun ./scripts/lint.ts (the docs CI gate) passes; both new checks were confirmed to fail on injected drift (removed card / re-added dangling entry).
  • Full build: 690/690 static pages, all turbo tasks successful.
  • Runtime: v5 foundations cards now include cancellation in /v5/docs/...; errors lists all 15; markdown export expands <AutoCards/> to real card links.
  • Biome-clean on all changed files. No changeset needed (docs-only).

Docs Preview

Pages whose card grid changed (behind Vercel deployment protection — requires team access):

Pagev4v5
Foundations/docs/foundations/v5/docs/foundations
Errors/docs/errors/v5/docs/errors
Observability/v5/docs/observability

🤖 Generated with Claude Code

Section index card grids (e.g. foundations) were hand-written and drifted
from the sidebar (meta.json) and the actual pages. Make them derive from
the fumadocs page tree (single source of truth) and add CI lint so the
card grid and navigation can't fall out of sync again.
- resolveSectionChildren + <AutoCards/>, bound in both v4 and v5 docs
routes (correct /docs vs /v5/docs URL spaces)
- getLLMText expands <AutoCards/> so llms.txt/.md/copy-page keep child links
- manualCards frontmatter opt-out for curated pages (source.config.ts)
- checkSectionCards (card<->nav completeness) + checkMetaEntriesResolve
(dangling meta entries) in scripts/lint.ts
- convert foundations + errors (drift fixes) and v5 observability to AutoCards
- mark deploying + ai as manualCards (intentionally curated)
- remove dangling meta entries: v4 cancellation (x2), root introduction
(x2), v4/internal serializable-abort-controller
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@pranaygp
pranaygp requested review from a team and ijjk as code ownersJune 22, 2026 20:44
CopilotAI review requested due to automatic review settings June 22, 2026 20:44
@changeset-bot

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: ca5a2cd

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel

vercelBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@VaguelySeriousVaguelySerious left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@pranaygp
pranaygp merged commit 6fad87b into mainJun 22, 2026
58 checks passed
@pranaygp
pranaygp deleted the pgp/docs-nit branch June 22, 2026 21:37
pranaygp added a commit that referenced this pull request Jun 23, 2026
…testing
* origin/main:
Trace /flow route initialization (#2592)
Version Packages (beta) (#2591)
feat(web): add trace step shortcut helper (#2582)
[web-shared] reskin json viewer (no duplicates, better colours and navigation) (#2434)
Send occurredAt with workflow events (#2580)
docs: use actual eve logo and tidy OSS nav dropdown (#2586)
Display occurredAt in trace details (#2581)
fix(next): discover root entrypoints (#2564)
[core] Turbo: skip the unused run_started event-log preload (#2569)
fix(next): prewarm SWC plugin cache (#2538)
[world-vercel] Use v3 stream endpoint (supports transparent reconnect on timeout) (#2424)
[core] Retry stream reopen against the reconnect budget (#2334)
Add Platformatic World to worlds-manifest.json (#1450)
docs: derive section landing-page cards from the page tree + lint drift (#2567)
Sign up for freeto 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.

3 participants

@pranaygp@VaguelySerious