Commit Graph

174 Commits

Author SHA1 Message Date
github-actions[bot] f1ff2051c4 style: auto-fix formatting 2026-05-19 01:23:41 +00:00
Tyler Slaton b30e01ad81 feat(shell-docs): adopt Fumadocs UI + floating sidebar + Shiki code chrome
Rebuild the shell-docs chrome on top of Fumadocs UI primitives and ship the
visual polish pass that replaces the legacy custom chrome.

- Fumadocs adoption: route every docs page (home, framework-scoped, ag-ui)
  through a shared ShellDocsLayout that wraps DocsLayout / DocsPage with
  the project's nav slot, sidebar config, scroll preserver, and content
  wrapper. Swap custom tabs/code-block components for Fumadocs's Tabs,
  CodeBlock, Pre, CodeBlockTabs, DynamicCodeBlock — Snippet and DemoSource
  now share the same chrome as authored fenced blocks.
- Syntax highlighting: replace rehype-highlight + hand-rolled hljs CSS
  with Fumadocs's Shiki-based rehypeCode in all three MDX renderers and
  in mdx-registry-loader. A tiny `transformerMeta` Shiki transformer
  surfaces fence title= / language as data-attrs so MdxCodeBlock can
  render the file-path figcaption + floating copy button.
- Sidebar: floats on all four viewport edges (rounded-2xl, 0.75rem inset,
  light-gray border), framework picker pill is rounded-xl with symmetric
  padding above/below, sticky picker bg matches the panel surface.
  Section headers render in normal caps (no more uppercase shouting), with
  scroll position preserved across navigations via SidebarScrollPreserver.
- Navbar: bg flips to `--bg`, full-width inset matches the sidebar,
  search trigger drops its border and the entire right-wing pill is the
  click target.
- Code chrome: figure surface forced to plain white in light and the
  matching dark in dark, shadow stripped, figcaption divider uses
  `--border` (was `currentColor` from `text-fd-muted-foreground`). Scoped
  the `.reference-content code` chip-bg rule to `:not(pre)` so block
  code bodies no longer pick up the gray inline-chip background.
- Content area: 49px (3.0625rem) of left/right padding so the article
  column has visible breathing room from both the floating sidebar and
  the viewport edge.
- IA: meta.json restructure for /docs (Build Generative UI section,
  controlled/declarative/open-ended folders, A2UI lifted to its own
  folder with an index page, Migrate moved under Other), Concepts content
  rewrite, snippet/region cleanups.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 18:20:48 -07:00
Sam Julien 87892105f6 fix(shell-docs): rendering parity, copy dedent, and content cleanup
Consolidates four QA findings from the post-cutover rendering pipeline:

- MdxCodeBlock now dedents fence-in-JSX bodies before passing the copy
  payload to <CopyButton>. Fences nested inside <Tab>/<Step>/<Tabs> were
  reaching the clipboard with 16-24 leading spaces per line (invalid
  Python / TS on paste). The visible <pre> body is dedented in lockstep
  so rendering matches what's copied.

- Wires rehypeCodeMeta + pre: MdxCodeBlock into the framework-root
  after-features MDX renderer, achieving parity with docs-page-view.tsx.
  Previously bare rehypeHighlight left these blocks without copy
  buttons or file-path captions.

- Closes the two fences in display-only.mdx with three backticks instead
  of four, so the fences actually terminate and copy doesn't grab
  adjacent JSX/prose.

- Removes a copy-paste-duplicated <Callout> on tool-rendering.mdx
  (kept the first occurrence, dropped the post-InlineDemo duplicate).
2026-05-15 15:56:38 -07:00
github-actions[bot] 82ff58a078 style: auto-fix formatting 2026-05-15 16:16:56 +00:00
Sam Julien 629a0889c3 feat(shell-docs): render FrameworkOverview at framework root URL
Replaces the hardcoded FrameworkLandingPage splash with a three-tier
resolution at /<framework>:

  1. frameworkOverviews[slug] exists → render <FrameworkOverview> with
     the data record (plus an optional after-features.mdx slot for the
     three frameworks that need one).
  2. integrations/<folder>/index.mdx exists → render through loadDoc /
     DocsPageView.
  3. otherwise notFound().

Recognizes docs-only integrations (a2a, agent-spec, deepagents) that
have docs content but no showcase/integrations/<slug>/ demo package —
previously the registry check sent them to UnscopedDocsPage and they
404'd at /<slug>.

Adds an "index" slug rewrite in buildNavTree and
buildFrameworkOverridesNav so meta.json "index" entries resolve to
the bare /<framework> URL rather than /<framework>/index.

Hoists the framework's Introduction (slug "") to position 0 of the
merged sidebar so users see it above the global root nav rather than
buried inside the per-framework section. RenderNav and sidebar-link
pass an empty slugPath through for active-state matching at the root.
2026-05-15 08:52:54 -07:00
Sam Julien 03930e2484 chore(docs, shell-docs): add favicon.ico
Neither app had a favicon configured locally, so the browser tab
showed the generic globe icon. Drop the canonical copilotkit.ai
favicon (3-image .ico, 16×16 + 32×32) into each app's app/ directory
so Next.js auto-serves it via its file-system convention. Same asset
on both surfaces.
2026-05-14 20:36:44 -05:00
Sam Julien a8eaf7cbac fix(showcase/shell-docs): make highlight.js theme switch follow the .dark class
The Quickstart QA report flagged code blocks reading as black-on-black
in dark mode. Cause: `globals.css` imported `github-dark-dimmed.css`
gated on `prefers-color-scheme: dark`, but shell-docs's theme toggle
flips a `.dark` class on <html> independent of OS preference. A user
on a light OS who clicked the dark toggle ended up with the dark
chrome (page bg, code-block bg via CSS vars) but the LIGHT hljs token
colors — the symptom the report described.

Drop the media-query @import and inline the github-dark-dimmed token
colors below, scoped to `.dark`. Source: highlight.js's own
github-dark-dimmed stylesheet. Also force `.hljs { background: transparent }`
so the upstream `#fff` background no longer punches white rectangles
through our themed `var(--bg-surface)` surfaces.

Adds `.reference-content .mdx-code-block` styling so the new `pre`
override's figure chrome wins over the global `.reference-content pre`
border/shadow/padding rule and doesn't double-up.
2026-05-14 14:51:51 -07:00
Sam Julien 01a39beb99 feat(showcase/shell-docs): wire MdxCodeBlock + rehypeCodeMeta into MDX renderers
Plugs the new `pre` override and rehype plugin into the two places shell-docs
renders MDX:

- `DocsPageView` (the shared component behind /docs/* and /<framework>/*)
- `app/ag-ui/[[...slug]]/page.tsx` (AG-UI catch-all)

The components map now sets `pre: MdxCodeBlock`, and `rehypeCodeMeta` is
appended after `rehypeHighlight` in `options.mdxOptions.rehypePlugins`.
Order is load-bearing — the meta plugin reads the `language-<name>`
className that highlight pushes onto the `<code>` element.
2026-05-14 14:51:40 -07:00
Sam Julien 62facacee1 feat(quickstart): add platform signup as Step 1 across integration quickstarts
Every integration quickstart in docs/ and showcase/shell-docs/ now opens with
a "Create a free account" step that points the reader at the Enterprise
Intelligence Platform before the framework path. Existing top-of-page
<OpsPlatformCTA> blocks on the six integrations that already had one are
left in place.

- New <SignupLink surface="docs_<int>_quickstart_step1">…</SignupLink> MDX
  component in both apps. It mirrors OpsPlatformCTA's URL+UTM contract
  (https://dashboard.operations.copilotkit.ai/ with the canonical docs
  UTMs, picked up from NEXT_PUBLIC_INTELLIGENCE_SIGNUP_URL when set) and
  fires the same PostHog event the other CTAs use:
  posthog.capture("try_for_free_clicked", { location: surface }).
- Registered as an MDX global in:
    docs/app/integrations/[[...slug]]/page.tsx
    docs/app/(home)/[[...slug]]/page.tsx
    showcase/shell-docs/src/lib/mdx-registry.tsx
- All 28 integration quickstart .mdx files now lead with a Step that uses
  this component as an inline link inside a single sentence of prose —
  no CTA card inside <Steps>.

The <TailoredContent> "Choose your starting point" / "How do you want to
get started?" selector is now wrapped in its own <Step> so it advances
the counter, and the inner CLI/manual paths render as steps 3, 4, 5, …
instead of 2, 3, 4, …. Applies to all 20 quickstarts that use the
picker.

- Indigo→purple gradient text on the Step 1 heading on both surfaces
  (`.fd-steps > .fd-step:first-child h3` on docs/,
  `.docs-steps > div:first-child h3` on shell-docs). Direct-child
  combinator scopes it to the outer first Step so inner first-children
  inside TailoredContentOption don't pick it up. Bump weight to 700
  and font-size to 1.375rem on docs/ to compensate for the
  background-clip:text rendering path (grayscale AA, no solid fill)
  which makes glyphs look lighter/smaller than the adjacent solid
  600/20px headings.
- Tone down the selected TailoredContent option card on both surfaces
  to a near-grayscale wash (from-slate-50 → to-indigo-50/30) and
  shorten the card itself (smaller padding, smaller icon, smaller
  title; extra left padding for breathing room) so the picker takes
  less vertical space and doesn't compete with the Step 1 gradient
  heading. Indigo ring still does the "selected" signal.
- Bump the tablist's bottom margin in shell-docs (my-2 → mt-2 mb-6)
  so the gap between the picker and the first inner Step matches the
  1.5rem gap that every other consecutive-Step transition uses.
- Black SignupLink color in Step 1 on shell-docs so the link doesn't
  clash with the gradient heading above it.
- Shell-docs: reset margin-top on the first heading inside any Step so
  the badge and heading align, and nudge the badge top from -0.125rem
  to 0.1875rem so its vertical center matches the heading line center.
  Moved the badge's appearance (background/border/color/font-weight)
  out of inline style and into globals.css so :first-child overrides
  can win without fighting inline-style specificity.
2026-05-13 11:38:29 -07:00
Sam Julien 26a6c07fdd style(shell-docs): align framework landing + not-available pages to canonical shell
The framework-scoped routes had two more places still rendering against
the pre-wave3 shell that the root /docs page just got migrated off of:
- FrameworkLandingPage (e.g. /mastra, /langgraph-python) used the old
  240px sidebar with p-4 + bg-[var(--bg)] + browser-default scrollbar,
  plus a max-w-4xl content column with no centering.
- NotAvailableForFrameworkPage (rendered when a slug exists for some
  frameworks but not the URL's) used the same old shell.

Move both onto the SidebarNav + .docs-content-wrapper +
max-w-[900px] mx-auto pattern docs-page-view uses, and update RenderNav
to match the new section/page/group treatment from OverviewNavItem
(15px banner sections at depth 0, 11px text-faint demoted labels at
depth > 0, h-10 rounded-lg pill page links with dark-aware hover,
border-l tree on nested groups). Picking a different framework now
produces the same chrome as the root overview, instead of revealing
the old shell.
2026-05-08 14:41:24 -07:00
github-actions[bot] ee41d6061e style: auto-fix formatting 2026-05-08 21:34:49 +00:00
Sam Julien 927cb56101 style(shell-docs): polish docs page chrome (header spacing, sidebar, root overview)
Tighten the gap between the page header and the body to canonical's
mb-8 (was mb-14 with a responsive ladder that opened a half-inch hole
at xl widths between the description paragraph and the first prose
paragraph).

Align the sidebar treatment to canonical:
- Section header banner uses the same Plus Jakarta default-weight
  uppercase + tracking as canonical's separator, sized up to 15px so
  it sits above the link list as a clear divider rather than a tiny
  caption below it.
- Section divider rule uses --border (white/10 in dark, #d9d9e0 in
  light) so the horizontal line survives the dark token set.
- Active-link pill picks up dark-mode contrast: --bg-hover surface
  with a 1px white/10 ring instead of the near-flat --bg-surface
  that read as undifferentiated against the sidebar bg in dark.
- Idle pages get a white/5 hover affordance in dark.
- Nested section separators (depth > 0) demote to a quiet 11px
  uppercase label in --text-faint with no divider rule, so the
  Build Generative UI > Controlled / Declarative / Open-Ended
  subsection breaks read as inline labels inside their parent
  group instead of competing banner headers.

Move the root /docs overview route onto the same SidebarNav +
.docs-content-wrapper + max-w-[900px] mx-auto pattern docs-page-view
uses, and rewrite OverviewNavItem so sections, pages, and groups
paint with the same tokens as the per-doc routes -- previously the
root was still rendering against the pre-wave3 shell with a 240px
sidebar, p-4 padding, browser-default scrollbar, and an off-center
max-w-4xl content column.

Rename the "Give Your App Agent Powers" main-meta section to
"Adding Agent Powers" per product copy.
2026-05-08 14:32:57 -07:00
Sam Julien 84fc2b2c27 feat(shell-docs): port canonical dark mode parity
Add a .dark token block to globals.css mirroring canonical
docs.copilotkit.ai for every var the wave3 chrome consumes (--bg,
--bg-surface, --bg-elevated, --bg-hover, --border, --border-dim,
--sidebar, --glass-background, --text*, --accent*, --violet*, --blue,
--scrollbar-color, --scrollbar-track). The navbar already shipped a
Toggle theme button + sun/moon SVGs + documentElement.classList
.toggle('dark') + localStorage.theme persistence; this commit makes
that toggle paint the rest of the page because all wave3 chrome
(sidebar, navbar, banner, callouts, tables, TOC, content wrapper)
consumes those vars.

Add @custom-variant dark (&:is(.dark *)) so dark: Tailwind utilities
react to the .dark class instead of prefers-color-scheme. Without
this, the navbar's class-driven swap pairs (slanted-end-border-dark
vs -light, theme-moon vs theme-sun, every dark: utility) are dead
when the theme toggle runs.

Add an inline beforeInteractive script in <head> that reads
localStorage.theme (falling back to prefers-color-scheme) and applies
the class before first paint, with suppressHydrationWarning on <html>
so Next.js doesn't revert the class to match the server output.

Apply scrollbar-width: thin and scrollbar-color to .docs-content-wrapper
and the sidebar's inner scroll container so the thumb tracks the
active theme instead of paying the bright browser default that pops
against dark surfaces.

Bump dark-mode contrast on the icon-button hover surface in the
navbar (GitHub, Discord, theme toggle) to a rounded black/5 in light
and white/10 in dark so the buttons read as interactive.
2026-05-08 14:32:22 -07:00
Sam Julien a00c4bf9b8 fix(shell-docs): replicate canonical page layout architecture (fixed-height body, internal scroll on content wrapper, sidebar pinning, TOC inside wrapper, route shells) 2026-05-08 11:49:04 -07:00
Sam Julien 708e5aa5f1 style(shell-docs): port canonical visual baseline (color tokens, typography, callouts, tables, code chrome, content wrapper styles) 2026-05-08 11:49:04 -07:00
Sam Julien aa65c89213 feat(shell-docs): add sitemap, robots, and per-framework self-canonical metadata
Phase 3 of the docs.copilotkit.ai cutover: surface a complete sitemap,
basic robots config, and per-framework self-canonical metadata so each
URL variant (bare /quickstart, /langgraph-python/quickstart,
/agno/quickstart, etc.) is indexed under its own canonical rather than
collapsing onto a single root.

- src/app/sitemap.ts: emit one entry per (root URL, framework variant)
  pair plus reference and AG-UI sections. lastModified resolves from
  MDX frontmatter `lastmod`, then file mtime, then now. Strips Next.js
  route-group `(name)` segments and trailing `/index` so URLs match
  what the routers actually serve.
- src/app/robots.ts: allow all, disallow /api/, sitemap pointer at
  ${NEXT_PUBLIC_BASE_URL}/sitemap.xml.
- src/lib/sitemap-helpers.ts: shared MDX walking + base-URL resolution
  used by both metadata routes.
- generateMetadata() on the four catch-all docs routes
  ([[...slug]], [framework]/[[...slug]], reference/[...slug],
  ag-ui/[[...slug]]) sets `alternates.canonical` to the page's own
  full URL. Per-framework self-canonical, NOT root canonical.
- .env.example: document NEXT_PUBLIC_BASE_URL and NEXT_PUBLIC_SHELL_URL.
- next.config.ts: extend the existing NEXT_PUBLIC_BASE_URL doc comment
  with the new sitemap/robots/canonical consumers.
2026-05-07 09:55:33 -07:00
Sam Julien 72794959f3 fix(shell-docs): gate Reo init script on REO_KEY + JSON-escape interpolation
Two bugs in the Reo init <Script> in layout.tsx:

- If NEXT_PUBLIC_REO_KEY was unset, the script still ran with
  e = "undefined" and fetched https://static.reo.dev/undefined/reo.js.
  Sibling REB2B_KEY was correctly gated; Reo now matches.
- Bare interpolation into dangerouslySetInnerHTML — any future env
  value containing " or </script> would break out of the inline
  literal. Switches to JSON.stringify(REO_KEY) and reuses the
  resulting binding inside Reo.init() so the key only appears once.
2026-05-06 15:34:59 -07:00
Sam Julien 68c997b066 refactor(shell-docs): align analytics surface with upstream LCP trim
Mirrors upstream #4646 in two changes from the same PR:

- Drop the duplicate useRB2B hook in favor of the canonical
  <Script id="reb2b-script"> in app/layout.tsx (gated on REB2B_KEY).
  Env var renames from NEXT_PUBLIC_RB2B_ID (the hook's name) to
  NEXT_PUBLIC_REB2B_KEY (upstream's canonical name) — deployment
  ops will need updating.
- Set capture_dead_clicks: false on PostHog init so the
  dead-clicks-autocapture.js bundle isn't pulled in on the critical
  path.
2026-05-06 15:32:33 -07:00
Sam Julien 5f7974a32d feat(shell-docs): port Open Graph image route + vercel.json
Adds app/og/[...slug]/route.tsx for per-page social-share image
generation, and a vercel.json with maxDuration: 60 on app/og/** so
the Edge function has enough headroom to render OG cards.
2026-05-06 15:32:32 -07:00
Sam Julien b355a9aec0 feat(shell-docs): port docs telemetry stack
Brings PostHog, GA4, HubSpot, Reo.dev, Scarf, and RB2B into shell-docs
with parity to docs/. Adds the client-side PostHog provider with
session-stitched bootstrap and pageview capture, the AnalyticsClient
wrapper that mounts RB2B + GA4 hooks behind a single client boundary,
the Scarf pixel for OSS attribution, and the HubSpot and Reo.dev
scripts.

Renames POSTHOG_PROJECT_KEY to POSTHOG_KEY across shell and shell-docs
middlewares so the env names match the upstream pattern, and env-drives
POSTHOG_HOST with eu.i.posthog.com as the fallback.
2026-05-06 15:32:31 -07:00
Sam Julien 14469bedf4 feat(shell-docs): add useThreads at canonical reference path + content parity
The useThreads page existed in shell-docs at
\`src/content/docs/reference/v2/hooks/useThreads.mdx\` but that tree
isn't routed — the canonical reference renderer reads from
\`src/content/reference/\`, not \`src/content/docs/reference/\`. As a
result \`/reference/hooks/useThreads\` 404'd while the upstream docs
have had a working useThreads page for weeks.

Moves the page to the canonical location so it resolves at
\`/reference/hooks/useThreads\`, and pulls the rest of the threads
content stack into parity with upstream:

- Add \`OpsPlatformCTA\` to the reference renderer's component map so
  hook reference pages can host sign-up CTAs (used here on useThreads
  itself).
- Recreate useThreads at the canonical path. Drops the
  \`<ThreadsEarlyAccess>\` wrapper (canonical reference dir doesn't use
  it — threads is GA, no banner) and the \`doc_type: reference\`
  frontmatter field (canonical hooks use plain title + description).
  Keeps the local additions: \`<OpsPlatformCTA>\` placement and the
  \`lastRunAt\` PropertyReference (deliberately kept per commit
  9f18b50f0).
- Fix cross-links to useThreads in threads.mdx and the shared snippet
  to point at the canonical \`/reference/hooks/useThreads\` instead of
  the broken \`/reference/v2/hooks/useThreads\`.
- Bump the prerequisite from \`@copilotkit/react-core v1.50+\` to
  \`v1.56+\` in threads.mdx and the shared snippet to match upstream.

Out of scope: the broader \`/reference/v2/hooks/\<Name\>\` broken-link
problem across other shell-docs pages (useFrontendTool, useAgent,
etc. — same dirname mismatch but for hooks unrelated to this PR).
That's tracked under PDX-103 / PDX-84.

Page-structure differences from upstream are preserved per the
shell-docs IA decision to drop the \`learn/\` concept: \`learn/threads\`
stays \`premium/threads-explained\`, \`learn/intelligence-platform\`
stays \`premium/intelligence-platform\`, \`learn/tutorials/...\` stays
\`tutorials/...\`.
2026-05-05 11:55:02 -07:00
Sam Julien f29f2f0881 fix(showcase/shell-docs): drop broken framework-agnostic link from missingCell banner
The "Not available for {framework} yet" banner offered a "framework-
agnostic version" link pointing at `/${slugPath}`. After the canonical-
pages work landed, the canonical page IS what renders for the current
framework (root MDX wins over per-framework overrides), so that link
sent the user back to the same page they were already on.

Removes the link and the leading "instead, or browse the" copy. The
banner now ends after the inline alternative-framework links.
2026-04-29 13:25:50 -07:00
Sam Julien 1090feee7d fix(showcase/shell-docs): Steps numbering survives WhenFrameworkHas
<Steps> was injecting __index props at build time by walking React
children. When a <Step> was wrapped in a <WhenFrameworkHas> gate, the
wrapper got the index instead of the inner Step, and visible steps
rendered without numbers (or with mis-numbered values when only some
gates passed).

Switched to a CSS counter (.docs-steps resets, .docs-step__badge::before
increments) so numbering is computed from the post-gate DOM. Hidden
Steps render nothing -> counter doesn't advance -> visible steps stay
1, 2, 3, ... in the reader's view regardless of which patterns are
active.

Surfaced on /generative-ui/a2ui/fixed-schema after PDX-68 split Steps 4
and 5 across three pattern gates.
2026-04-29 08:15:16 -07:00
Sam Julien 261c0be08b fix(shell-docs): drop framework-name sidebar link + retire legacy /integrations/ URLs
Two related cleanups that fall out of the soft-default world.

**Framework-name sidebar link** — the labeled "you're reading X's docs"
header link below the framework selector was redundant. The selector
pill above it already identifies the active framework, the breadcrumb
trail at the top of the body covers "go to root," and `/` and
`/<framework>` now render the same docs-landing shell so clicking the
link mostly just changed the URL. Removed from all four call sites:
DocsOverview (unscoped /), FrameworkLandingPage,
NotAvailableForFrameworkPage, and DocsPageView.

DocsPageView's `sidebarTitle` and `backLink` props are gone (no
remaining consumers). Breadcrumb root label is now derived from
`frameworkOverride` at render time — "LangGraph (Python)" on
framework-scoped pages, "Docs" otherwise.

**Legacy `/integrations/<framework>/<slug>` URLs** — the original URL
scheme before `/<framework>/<slug>` shipped. The Notion plan flagged
them as still reachable via UnscopedDocsPage's regex match on
`integrations/...`. Since shell-docs hasn't shipped publicly, no real
inbound links exist; cleaner to retire them than maintain dual schemes.

UnscopedDocsPage's integrationMatch branch is gone. Any
`/integrations/...` URL now 404s. The `integrations/<framework>/`
content tree on disk stays — it's still loaded by the framework
router's per-framework override fallback (e.g. `/built-in-agent/quickstart`
serves `integrations/built-in-agent/quickstart.mdx`). Only the URL
scheme is retired.

search-modal.tsx integration and demo result links now point at the
shell host's integrations explorer (`${SHELL_HOST}/integrations/...`)
instead of the now-404 shell-docs paths.
2026-04-28 09:45:24 -07:00
Sam Julien d02d4e89e5 fix(shell-docs): drop "All docs" sidebar back-link and "Reset to default" dropdown row
Both affordances were vestiges of the pre-soft-default world.

"All docs" pointed at `/`. Before the IA restructure, that was a
distinct picker view; now `/` and `/<framework>` render the same
docs-landing shell with whichever framework is effective. Clicking
the link from a deep page just changed the URL with no visible
content change. The CopilotKit logo in the top header already covers
"go to root," and the framework-name link below the selector covers
"go to this framework's landing." Removed from all three call sites
(feature-page backLink, FrameworkLandingPage sidebar,
NotAvailableForFrameworkPage sidebar).

"Reset to default" set storedFramework to null and navigated to the
unscoped equivalent of the current page. With the CopilotKit row
pinned at the top of the dropdown, picking it does the same thing
end-to-end (effectiveFramework becomes BIA, navigation lands on a
BIA-scoped URL) — the user reaches for the same target either way.
The button only appeared when storedFramework was set, so removing it
loses no on-screen affordance for fresh visitors and one redundant
row for returning visitors.
2026-04-28 09:34:40 -07:00
Sam Julien f80a29c717 feat(shell-docs): soft-default to Built-in Agent for unselected visitors
FrameworkProvider gains an `effectiveFramework` field that falls
through URL → stored → DEFAULT_FRAMEWORK ("built-in-agent"), so it's
never null. Snippet renderers, sidebar links, and "Continue with X"
affordances read this; the original `framework` field stays
URL-strict for the few call sites that genuinely need to know
"is the URL scoped?"

Removes the forced-picker dead end. Fresh visitors land on the docs,
see BIA code immediately, and switch backends from the picker on the
landing page or the sidebar dropdown when they want.

Consumers updated:

- SidebarLink resolves href against effectiveFramework. Drops
  hideWhenUnscoped (Quickstart entry now always lands on a real
  framework-scoped URL).
- DocsLandingNext collapses its two-branch render (picker vs
  Continue-with-X) into one: always shows "Continue with
  {effectiveFramework}" + Quickstart/Browse pointer cards, with the
  categorized framework picker below as a "Switch backend" affordance.
- RouterPivot becomes a pure redirect: dispatches to
  `/<effectiveFramework>/<slug>` on mount. The legacy picker grid is
  gone — soft-default makes that branch unreachable.
- FrameworkGuardedContent always returns null (the body is hidden
  during the redirect tick).
- UnscopedDocsPage drops the props that fed RouterPivot's old picker
  (frameworksWithCell, previewUrl, featureName, featureDescription).
2026-04-28 09:11:34 -07:00
github-actions[bot] 2e95ba75fc style: auto-fix formatting 2026-04-27 23:25:21 +00:00
github-actions[bot] 39d86aa872 style: auto-fix formatting 2026-04-27 16:24:06 -07:00
Sam Julien d1cd9f06a8 feat(shell-docs): collapse framework landing into the docs landing shell
Switching frameworks now lands on the same shell as / does, just with
the framework already URL-active. The /<framework> route renders the
docs-landing hero, CLI command, and utility cards (Concepts / API
Reference / Generative UI), then DocsLandingNext's "Continue with X"
branch with Quickstart / Browse {framework} docs / Switch framework
pointers. Replaces the previous bespoke FrameworkLandingPage that
showed a "You're viewing docs scoped to" panel and a hardcoded 4-card
grid (chat-ui / tool-rendering / frontend-tools / human-in-the-loop)
that drifted from the docs landing.

DocsLandingNext now prefers the URL-active framework over the stored
preference so /<framework> can render the "Continue with X" branch
during SSR with no mount-flicker — the previous storedFramework-only
gating caused a brief picker render before the localStorage effect
caught up.

Delete the orphaned per-framework index.mdx files. They were the
backing for the old sidebar Introduction entry (already removed) and
the URL /<framework>/index, which Next.js's optional catch-all
collapses to the bare framework path anyway. Their FrameworkOverview
content (banner video, init command, supportedFeatures grid) was a
legacy marketing-style landing that doesn't fit the new docs-routing
shape.
2026-04-27 16:23:40 -07:00
Sam Julien 7d1e806799 feat(shell-docs): hide sidebar Quickstart entry until a framework is active
The root /quickstart page is a routing shim — it has no real content,
just a pointer to the per-framework quickstarts. Showing it in the
sidebar on / leads users into a dead-end click ("This page is a
routing shim..."). Hide the entry until a framework is active in the
URL or stored in localStorage; once either is set, SidebarLink prepends
it and the click lands on real per-framework content.
2026-04-27 16:23:40 -07:00
Sam Julien 4711c7de06 fix(shell-docs): per-framework quickstart wins over routing shim
The framework-scoped route resolves root MDX before per-framework
overrides, which is correct for most pages — root content rendered
with framework-specific snippets is the primary path. But the new
root quickstart.mdx is a routing shim that exists only so the sidebar
entry has a backing page; real quickstart content lives per-framework
at integrations/<framework>/quickstart.mdx. Special-case the
quickstart slug so the override always wins for framework-scoped URLs.

While here, add the missing crewai-crews → crewai-flows docs-folder
mapping. The registry slug was renamed but the docs folder kept the
older name, so /crewai-crews/quickstart couldn't find the override.
2026-04-27 16:23:40 -07:00
Sam Julien 8adbebd30b feat(shell-docs): merge docs landing + /quickstart picker into one page
The docs landing at `/` and the standalone `/quickstart` picker did
overlapping jobs and confused first-time users. "Quickstart" as a
top-level URL was misleading: clicking it from the shell landing or
the docs overview's top-card list led to a 23-line picker rather than
the actual quickstart guide (which lives at `/<framework>/quickstart`,
117–527 lines per framework).

Merge them. `/` becomes the single docs-side landing:

  - Always shown: hero + product positioning, the `npx copilotkit@latest
    create` CLI command (moved up from /quickstart), and three utility
    cards (Concepts, API Reference, Generative UI).
  - Conditional below: a new `DocsLandingNext` client component that
    branches on `storedFramework`. Null → "Pick your agent framework"
    + the integrations grid (the picker). Set → "Continue with
    {name}" + three pointer cards (quickstart for that framework,
    framework landing, switch frameworks).

The standalone `/quickstart` page is deleted; `/quickstart` 301-redirects
to `/`. `/<framework>/quickstart` is unchanged — that's the canonical
per-framework quickstart guide.

Side effects of the merge:

  - The unscoped catch-all's `DocsOverview` was rewritten to drop the
    former two-step "Pick a backend / Or jump into a topic" panels.
    The framework picker is now in `DocsLandingNext` (only when there's
    no stored choice); the topic cards (DOCS_SECTIONS) were a flatter
    duplicate of the new JTBD sidebar and got deleted entirely.
  - `content/docs/index.mdx` was the file that rendered at `/index`
    (reachable from a sidebar entry under Get Started). With the
    merged `/` landing serving as the canonical overview, the
    `/index` URL stops being meaningful — `index.mdx` is deleted and
    the entry is removed from the top-level `meta.json`.
  - `DocsLandingNext` is registered in the MDX components map so
    future pages can drop it inline if useful, but its primary use is
    inside `DocsOverview` itself.

Pairs with PDX-46 (BIA-as-default). Once BIA defaults are in, the
"no framework" branch of `DocsLandingNext` becomes rare and the page
reads as the "what's next" experience for nearly every visitor.

Closes PDX-58.
2026-04-27 16:23:40 -07:00
Sam Julien 2ee45ceead fix(shell-docs): update mergeFrameworkNav anchor for JTBD section names
The merge anchor was hardcoded to "app control" with fallbacks to
"threads" and "backend". After the JTBD reorg renamed "App Control"
→ "Give Your App Agent Powers" and "Backend" → "Agents & Backends",
none of the candidates matched and every framework-scoped sidebar fell
back to append-at-end, relegating the framework section ("Built-in
Agent", "LangGraph (Python)", etc.) to the bottom of the nav.

Restore the original placement by adding the new section names to the
anchor candidate list: "give your app agent powers" (the renamed App
Control) and "agents & backends" (the renamed Backend) take priority,
with the old names kept as fallbacks for resilience. The match is
case-insensitive and stops at the first hit. Verified the framework
section now lands between Give Your App Agent Powers and Agents &
Backends for /built-in-agent/* and /langgraph-python/*.
2026-04-27 16:23:40 -07:00
Sam Julien f9d0da3b59 fix(shell-docs): suppress duplicate group title when section header already labels it
The current meta convention pairs a `---X---` section header with a
`...x` spread that resolves to a sub-meta whose `title` is also "X".
buildNavTree emitted both a section node and a group node with the
same title, and the renderers showed each one — so users saw "BUILD
GENERATIVE UI" (section, uppercase tracking-widest) followed by
"Build Generative UI" (group, regular case) for the same content.
The doubling was already on the live site for one section
("Generative UI") and didn't get pushback there, but the JTBD reorg
makes it more visible: every spread-backed section ends up doubled
(Migrate, Other, etc.).

Fix in two halves, kept narrow:

- buildNavTree: when the previously-pushed node is a section header
  with the same title that the spread's group would carry, set the
  group's title to empty string. The group still wraps its children
  for indentation/nesting; only the redundant inner label is dropped.
- All three nav renderers (renderNavItem in docs-page-view.tsx,
  OverviewNavItem in app/[[...slug]]/page.tsx, RenderNav in
  app/[framework]/[[...slug]]/page.tsx) gain a `{node.title && ...}`
  guard so an empty string doesn't render an empty <div>.

Sections without a matching spread (Get Started → index/quickstart/
coding-agents listed inline) and spreads without a preceding section
header (legacy framework-tree work, override merges) are unaffected.
A spread whose sub-meta title differs from the section header (e.g.
section "Observe & Operate" + ...troubleshooting whose title is
"Troubleshooting") still renders both labels, which is correct —
they're meaningfully different and the inner one acts as a
sub-grouping label.
2026-04-27 16:23:40 -07:00
Sam Julien 13d9af1b40 fix(shell-docs): show integration name in sidebar on framework-scoped routes
The sidebar title on /<framework>/* routes was hardcoded to
"CopilotKit Docs" — a regression noted in the IA analysis where
upstream's `integrations/langgraph/meta.json` correctly rebrands the
sidebar via `title: "LangChain"` + `root: true`.

Pass the integration's display name from the registry (already in
scope at this call site for mergeFrameworkNav and other uses) instead
of the hardcoded string. Verified across slugs: /langgraph-python/*
shows "LangGraph (Python)", /built-in-agent/* shows "Built-in
Agent", /ms-agent-dotnet/* shows "MS Agent Framework (.NET)",
unscoped routes (e.g. /quickstart) keep "CopilotKit Docs" via the
DocsPageView default prop.
2026-04-27 09:17:57 -07:00
github-actions[bot] 351f69ad93 style: auto-fix formatting 2026-04-24 21:52:44 +00:00
Sam Julien 41ef5cbb34 feat(shell-docs): resolve framework-variant URL slugs end-to-end
Registry slugs don't always match the integrations/<folder>/ name on
disk. Three LangChain/LangGraph variants (langgraph-python, langgraph-
typescript, langgraph-fastapi) read from the single langgraph/ tree,
ms-agent-dotnet and ms-agent-python share microsoft-agent-framework/,
and google-adk/strands are legacy renames that point at adk/ and
aws-strands/ respectively.

Before: the framework-scoped router, the sidebar-override nav
builder, and the "not available for this framework" fallback all
used the URL slug directly as a folder name, so any of the seven
mismatched slugs showed empty sidebars, 404s on framework-unique
pages (/langgraph-python/auth, /ms-agent-dotnet/auth), and missing
'available in other integrations' matches.

After: lib/registry exposes getDocsFolder(slug) backed by a small
DOCS_FOLDER_OVERRIDES table. Callers resolve the URL slug to its
actual folder before touching disk; findFrameworksWithPage takes the
resolver as a parameter so docs-render stays registry-free.

Per-page variant selectors authored as <Tabs groupId="..." default="Python">
now open with the URL-matching tab preselected instead of the author's
hardcoded default. getTabDefault(slug, groupId) reads
TAB_DEFAULTS_BY_SLUG; a wrapper in DocsPageView's MDX components map
injects the resolved value into <Tabs> via a 'default' prop alias.
/langgraph-typescript/configurable opens TypeScript, /ms-agent-dotnet/
auth opens .NET, /langgraph-fastapi/deep-agents opens FastAPI. Slugs
and groupIds without a mapping fall through to the existing behavior
(author default, then first items label).
2026-04-24 14:50:54 -07:00
Sam Julien c4e4743eb5 fix(shell-docs): drop deployed-gated styling from docs framework picker
The docs landing page and sidebar framework-selector both gated a
grayed-out card state and a "soon" label on integration.deployed.
That flag tracks whether a live showcase demo with tagged cells
exists — a showcase concern, not a docs concern. Built-in Agent has
ready docs even though no showcase package is published yet, so the
card was incorrectly rendered as "coming soon" and stayed visually
inert after clearing the stored framework.

Every integration that ships docs should be pickable from these
surfaces with the same visual weight. The deployed flag continues to
drive the showcase app, router-pivot filtering, and snippet cell
assertions — this change only touches the two docs-picker call sites.
2026-04-24 14:50:54 -07:00
Sam Julien a6676f8934 feat(shell-docs): fall back to "not available for this framework" page when a slug exists in other integrations
Before this change, visiting /<framework>/<slug> for a topic that only
exists under integrations/<other-framework>/ returned a bare 404 — for
example, /mastra/advanced-configuration (the page only lives under
integrations/built-in-agent/).

Now the router checks whether the slug exists in any other integration
and renders a framework-scoped fallback page inside the docs shell:
sidebar and framework switcher stay intact, and the body lists the
integrations where the topic does exist with direct links. Genuine
unknown slugs still 404.

New helper findFrameworksWithPage walks integrations/<slug>/ for each
registered framework. NotAvailableForFrameworkPage renders the shell
around the fallback body. Nav tree build is hoisted so both the happy
path and the fallback share one source.
2026-04-24 14:50:54 -07:00
Sam Julien 56bf99b0c7 feat(shell-docs): promote Built-in Agent as a first-class integration
Registers Built-in Agent as a framework in the registry and wires up
a router + sidebar-nav pattern so its content can live at /built-in-agent/*
without needing a dedicated per-framework content tree for every topic.

Content model:
- Root MDX pages (/quickstart, /frontend-tools, /shared-state, etc.) are
  the canonical home for framework-agnostic topics. Rendered at
  /built-in-agent/<slug> via the existing framework-override mechanism.
- integrations/built-in-agent/*.mdx is the escape hatch for topics that
  are genuinely BIA-specific (copilot-runtime, server-tools, mcp-servers,
  model-selection, advanced-configuration, custom-agent). The router
  falls back to these when no root equivalent exists.
- Root wins when both exist.

Changes:
- shared/manifest.schema.json: add 'built-in' to the category enum.
- shared/packages.json: register built-in-agent slug.
- packages/built-in-agent/manifest.yaml: new. deployed:false (showcase
  package TBD in a follow-up), sort_order:0, category:popular so it
  appears at the top of the framework dropdown.
- public/logos/built-in-agent.svg: new logo asset (extracted from the
  inline CopilotKit mark in brand-nav.tsx).
- shell-docs/src/app/[framework]/[[...slug]]/page.tsx: router gains a
  fallback to integrations/<framework>/<slug>.mdx when the root file
  doesn't exist. Sidebar nav merges in per-framework overrides as a
  labeled section positioned after 'App Control' (mirrors upstream's
  integrations/built-in-agent/meta.json ordering).
- shell-docs/src/components/docs-page-view.tsx: new optional
  contentSlugPath prop lets the router thread through the override
  content path without changing the URL-slug used for breadcrumbs and
  active-link detection.
- shell-docs/src/lib/docs-render.tsx: new buildFrameworkOverridesNav
  helper that walks integrations/<framework>/* and filters out pages
  that already exist at root.
2026-04-24 14:50:54 -07:00
Sam Julien 779bb10236 fix(shell-docs): move docs scrollbar to viewport edge
Previously <main> was both the scroll container AND width-capped
(`flex-1 max-w-4xl px-8 py-10 overflow-y-auto`). The scrollbar
rendered at the capped column's right edge, parking it mid-viewport
with a blank gutter beside it.

Separate the concerns: <main> is now full-width with the scroll, and
an inner <div> caps the content width and owns the padding. Scrollbar
now lands at the viewport edge (or TOC's left edge on pages that
render the right-rail TOC).

Applies to the four docs entry points that shared this pattern:
the root overview, the /<framework> landing + scoped pages, the
/ag-ui route, and the shared DocsPageView used by scoped docs.
2026-04-23 10:30:52 -07:00
Sam Julien 8fc126066b fix(shell-docs): account for BrandNav border in docs container height
The four docs flex containers used `calc(100vh - 52px)` to subtract the
top nav, but BrandNav is 52px flex content + 1px bottom border = 53px.
The 1px undercount made body overflow by exactly 1px and produced a
document-level scrollbar on top of the inner <main>'s own scroll.

The reference route already uses `calc(100vh - 53px)`; this aligns the
other four layouts with that convention.
2026-04-23 10:30:52 -07:00
Sam Julien 1ad171b620 docs(shell-docs): writing pass to remove em-dash overuse and fix hardcoded framework references
Replace em-dashes in prose across ~37 shell-docs files with appropriate
punctuation (colons, semicolons, commas, parens, periods). Also fixes a
hardcoded "LangGraph Python" reference in quickstart.mdx bridging text,
adds a user-friendly placeholder when no framework is selected on snippet
pages, and makes heading code font size proportional rather than fixed.
2026-04-23 08:34:37 -07:00
Sam Julien b7090a5d07 feat(shell-docs): build real feature matrix, fix card underlines, add backend intro
- Replace FeatureMatrix stub with a real server-rendered table reading from
  registry — 17 integrations × 12 curated feature columns, sticky first column,
  ✓/— cells, integration names link to /{slug} landing pages
- Fix matrix links from /integrations/{slug} (404) to /{slug}
- Remove redundant "Feature comparison" section from index.mdx (FeatureMatrix
  was a stub pointing to same destination as IntegrationGrid)
- Add .reference-content .not-prose a rule to suppress underlines on card grids
  inside MDX without breaking prose link styling
- Add intro sentence to "Explore by AI backend" section
2026-04-23 08:34:37 -07:00
Sam Julien 9582d4770a fix(shell-docs): fix empty FeatureIntegrations and matrix 404
- Correct 3 mismatched feature IDs in MDX (generative-ui-tool-based ->
  gen-ui-tool-based, frontend-tools-sync -> frontend-tools, reasoning ->
  agentic-chat-reasoning) so FeatureIntegrations renders integration chips
- Remove stale 'matrix' from RESERVED_ROUTE_SLUGS (no app/matrix/ route exists)
- Replace broken /matrix links in IntegrationGrid and search-modal with /
  since the matrix lives in shell-dashboard, not shell-docs
2026-04-23 08:34:37 -07:00
Jordan Ritter 8db7b211a4 fix(shell-docs): resolve findFrameworksWithCell + SidebarLink scope type errors
Two pre-existing type errors from commit 9b05ed41 surfaced on main's
Docker build:

1. `unscoped-docs-page.tsx` imports `findFrameworksWithCell` from
   `@/lib/docs-render`, but the helper was only declared locally in the
   two page.tsx routes with a 1-arg signature (and referenced an
   undeclared `demos` in one case — dead code). Export a 3-arg shared
   version from docs-render.tsx that accepts the integration slug list
   and demo map as parameters (keeps the lib free of registry imports),
   drop the dead local in `[[...slug]]/page.tsx`, and rewire the live
   caller in `[framework]/[[...slug]]/page.tsx` through the shared
   export.

2. The Step-2 section cards on the overview call `<SidebarLink>`
   without the required `scope` prop. The prop was already ignored
   internally (destructured as `_scope`) so relaxing it to optional is
   the minimal fix and keeps the call-site intent documented.

`npm run build` in showcase/shell-docs now compiles cleanly.
2026-04-22 12:16:38 -07:00
Jordan Ritter 9b05ed41b3 feat(showcase/shell-docs): error boundary consolidation + docs components
Drop error-boundary-card in favour of Next.js error.tsx at each route,
refresh docs components (brand-nav, docs-callout, docs-page-view,
docs-steps, docs-tabs, framework-provider/selector/tabs,
property-reference, router-pivot, sidebar-link, snippet), update
docs-render + mdx-registry + reference-items for the new QA shape.
2026-04-22 11:00:46 -07:00
Sam Julien 8c4d0c36f9 fix(shell-docs): remove stale 'integrations' from RESERVED_ROUTE_SLUGS
There is no app/integrations/ route, so the reservation was causing
/integrations/... URLs to 404. Without it, these paths fall through to
UnscopedDocsPage via the non-integration fallthrough in [framework].
2026-04-21 17:35:01 -07:00
Sam Julien 87fb9e8260 fix(showcase/shell-docs): fix /<slug> 404 via UnscopedDocsPage fallthrough
Next.js routes /quickstart to [framework]/[[...slug]] (dynamic segment
beats optional catch-all), where "quickstart" is not a registered
integration, causing notFound(). Fix by:

- Extracting the unscoped doc rendering logic into UnscopedDocsPage
- Falling through to it in [framework] when the slug is not a framework
- Simplifying [[...slug]]/page.tsx to handle only the root overview
2026-04-21 17:35:01 -07:00
Sam Julien bb0b14702c fix(showcase/shell-docs): eliminate URL flicker on unscoped navigation
SidebarLink now uses storedFramework as fallback so links on the
overview page go directly to /<framework>/<slug> without a RouterPivot
redirect. OverviewNavItem and section cards now use SidebarLink for the
same reason. FrameworkSelector "Clear selection" was navigating to
/docs/<slug> (broken); fixed to /<slug>. hrefFor now preserves the
current slug when switching frameworks from an unscoped page.
2026-04-21 17:35:01 -07:00