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.
18 per-framework MDX pages had the closing half of a multi-line
import statement left at the top of the file (the orphaned
"Symbol1, Symbol2, } from '...'" tail with the opening "import {"
line missing). The current sync-docs-from-main import stripper
handles multi-line imports correctly, so this was a historical
artifact from an earlier stripper version that misparsed them —
every affected file predates that fix.
MDX treats the orphan as plain text, so pages rendered the
identifier list and "} from ..." string as visible garbage at the
top before the real content started. Strip the orphan blocks; future
syncs won't re-introduce them.
The MDX registry had TailoredContent and TailoredContentOption
stubbed as passthrough <div>{children}</div> wrappers. MDX pages
author these as a variant-switcher (e.g. on Readables:
"Custom graph" vs "Prebuilt agent" paths for LangGraph setup), so
the stub rendered both option paths stacked — the same useAgentContext
example, the same steps, effectively duplicating multi-hundred-line
sections on every page that uses the component.
Swap the stubs for the real implementation at
components/react/tailored-content.tsx, which has been in the repo
since the shell-docs move but was never wired in. The real component
renders only the selected option and persists the choice in a URL
search param (?impl=graph / ?impl=prebuilt).
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).
Every framework under integrations/<fw>/ shipped its own copy of
contributing/ + telemetry/ content that was byte-identical (or
trivially divergent — a stray "cd" path, a legacy CLI name) to the
canonical copy at root (other)/. The duplicates were stale sync
artifacts with no framework-specific content: "how to contribute to
CopilotKit" and "how to configure telemetry" don't vary by agent
framework.
Beyond disk clutter (~2.5k lines across 8 frameworks), the duplicates
surfaced as a "Other" group nested under the framework-scoped
sidebar section whenever the merged nav built from meta.json — a
second copy of root's own "Other" section at the bottom of the
sidebar. Deleting the trees makes that UI bug disappear without any
filter patching.
Scope:
- Remove integrations/<fw>/(other)/ trees for ag2, agno, aws-strands,
crewai-flows, langgraph, llamaindex, mastra, microsoft-agent-framework.
- Drop ---Other--- + ...(other) entries from each framework's meta.json.
- Add a path-exclusion filter in sync-docs-from-main.ts so the next
sync run doesn't resurrect the subtrees when upstream edits touch
them. Upstream keeps its copies (removing them there means touching
all 13 parallel framework trees, out of scope for this branch).
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.
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.
Per-framework meta.json files (mastra, langgraph, llamaindex, etc.)
mirror the root tree's section names ("Getting Started", "Basics").
Passing them through buildFrameworkOverridesNav into the merged
sidebar caused duplicate React keys when the merge ran — every root
section collided with the override's copy of the same title.
The override block is already wrapped in a single "{frameworkName}"
section by mergeFrameworkNav, so nested section headers added no
information anyway. Drop them at the filter step.
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.
## Summary
The top-nav "Integrations" link on shell-docs (and the inline link
inside `IntegrationGrid`) both pointed at `/integrations` on shell-docs
itself — a redundant framework-picker + matrix page that duplicated the
sidebar's framework selector. The real integration explorer (live demos,
filtering, feature browsing) lives on the shell app at `/integrations`.
This PR routes both links to the shell host instead.
## Changes
- `showcase/shell-docs/src/components/brand-nav.tsx` — top-nav
"Integrations" href is now `${NEXT_PUBLIC_SHELL_URL}/integrations`.
- `showcase/shell-docs/src/components/integration-grid.tsx` — inline
"See Integrations" href updated the same way.
- `showcase/shell-docs/next.config.ts` — adds `NEXT_PUBLIC_SHELL_URL`
build-time validation mirroring the existing `NEXT_PUBLIC_BASE_URL`
pattern: throws during `next build` if missing, warns in dev.
- `showcase/shell-docs/src/content/docs/integrations/index.mdx` —
deleted. The redundant page those links targeted. Legacy per-framework
subtrees under `integrations/*` are unchanged.
Components use a localhost:3000 dev fallback via
`process.env.NEXT_PUBLIC_SHELL_URL ?? "http://localhost:3000"` — matches
the existing dev-fallback pattern documented in `next.config.ts` for
`NEXT_PUBLIC_BASE_URL`. No hardcoded prod URLs in the code.
## Prod safety
`next build` fails loudly if `NEXT_PUBLIC_SHELL_URL` is unset. Since
`NEXT_PUBLIC_*` values are inlined at build time, a successful prod
build ships with the correct host baked in; the localhost fallback is
only reachable in dev.
## Test plan
With shell running at `http://localhost:3000` and shell-docs running at
`http://localhost:3003`:
- [ ] Hover the "Integrations" link in shell-docs' top nav — status bar
shows `http://localhost:3000/integrations`
- [ ] Click it — lands on the live `IntegrationExplorer` at
`localhost:3000/integrations`
- [ ] The inline "See Integrations" link rendered by `<IntegrationGrid
/>` (e.g. on `/prebuilt-components`) behaves the same way
- [ ] Visiting `/integrations` on shell-docs directly (e.g.
`http://localhost:3003/integrations`) 404s — the page was deleted
- [ ] Sidebar and other nav elements unchanged
Now that generated JSON is gitignored, every path that consumes these
files must run generators first. Fixes:
- shell: add bundle-demo-content to dev preamble (eliminates race
between watcher and Next.js on fresh clone); add
bundle-starter-content to Dockerfile RUN chain
- shell-dojo: add predev hook (generate-registry + bundle-demo-content)
- shell-docs: add predev hook (generate-registry + bundle-demo-content
+ generate-search-index)
- ops: replace direct COPY of gitignored registry.json with
generate-registry.ts at build time (copy scripts+shared+packages,
npm ci, run generator)
Add */src/data/*.json patterns to showcase/.gitignore for all 4 shell
apps. Remove 11 tracked JSON blobs (~28K lines of generated content)
that were causing constant git noise from embedded timestamps and
leaking into PRs on every build/dev run.
Every build path (Docker, CI, npm run build, npm run dev) regenerates
these files — they never needed to be committed.
Every generator embedded `generated_at: new Date().toISOString()` in its
output, causing constant git noise on every build/dev run even when
actual content was unchanged. Remove the field from all 4 generator
scripts, all consumer interfaces (Registry, BundledContent,
BundledStarters, DocsStatusBundle), inline type casts, and test
assertions.
Also: add shell-dashboard as a generate-registry output directory (it
was cross-importing from shell); move probe-docs output to
shell-dashboard/src/data/ (sole consumer); update test beforeAll to
generate files instead of restoring from git HEAD (prep for gitignore).
Shell owns /integrations (live explorer) and /matrix (feature matrix),
mirroring shell's existing redirect table that sends /docs/*, /ag-ui/*,
/reference/*, and /<framework>/* to the docs host. Adds the reverse
redirects in shell-docs' next.config so /integrations and /matrix jump
out to showcase.copilotkit.ai at the edge.
Removes the redundant shell-docs framework-picker page at
showcase/shell-docs/src/content/docs/integrations/index.mdx. All internal
links can now use bare /integrations hrefs — the redirect handles the
cross-host jump in production, and in dev it 404s cleanly (no local
page to render). Legacy per-framework subtrees under integrations/* are
unchanged.
## Summary
First round of the snippet-linking sweep: every code fence in shell-docs
should be a `<Snippet>` pointing to real showcase source, not
hand-written inline ```tsx.
Scope on this PR is **prebuilt-components + the unselected twin** — 4
commits, easy per-commit review.
### Commits
- `7efe08ae8` — **Strip hand-written fences from Styling sections** on
all 6 prebuilt-components pages (base + unselected ×
chat/sidebar/popup). Keeps the `## Styling` header, intro copy, and
bullet links to `/custom-look-and-feel/*`; drops only the duplicative
slot-override code.
- `157cdae57` — **Wording pass**: replace "showcase cell" references
with neutral phrasing ("the example below", etc.) across 21 files.
- `f6086011a` — **Snippet-ify the Code example section on both chat.mdx
pages.** Adds a new `@region[chat-component]` to
`showcase/packages/langgraph-python/src/app/demos/agentic-chat/page.tsx`
wrapping the existing `Chat` helper (hook + render). Hand-written tsx
fences on `docs/prebuilt-components/chat.mdx` and
`docs/unselected/prebuilt-components/chat.mdx` replaced with `<Snippet
region="chat-component">`. The three `demo-content.json` bundles are
regenerated to include the new region.
- `ef0823372` — **Snippet-ify variant code blocks on
`unselected/prebuilt-components/index.mdx`.** Three hand-written tsx
fences (CopilotChat, CopilotSidebar, CopilotPopup variants) become
Snippets pointing at `chat-component` (agentic-chat),
`sidebar-basic-setup` (prebuilt-sidebar), and `popup-basic-setup`
(prebuilt-popup). Drops the redundant Deep customization inline example
in favor of a link to the Slots guide.
### Showcase-source change
Only one: `@region[chat-component]` / `@endregion[chat-component]`
markers added around the existing `Chat` helper in
`showcase/packages/langgraph-python/src/app/demos/agentic-chat/page.tsx`
(2 lines, no runtime behavior change).
## Test plan
Run shell-docs at `localhost:3003`.
Prebuilt-components pages (clear framework selection to reach
`/unselected/*`):
- [ ] `/langgraph-python/prebuilt-components/chat` — Basic setup =
`provider-setup` Snippet; Code example = new `chat-component` Snippet
showing the full `Chat` function; Styling = header + intro + 3 bullet
links, no code
- [ ] `/langgraph-python/prebuilt-components/sidebar` — Basic setup =
`sidebar-basic-setup` Snippet; Configuring = `sidebar-configuration`
Snippet; Styling = header + intro + link, no code
- [ ] `/langgraph-python/prebuilt-components/popup` — Basic setup =
`popup-basic-setup` Snippet; Styling = header + intro + link, no code
- [ ] `/unselected/prebuilt-components/chat`, `/sidebar`, `/popup` —
same expected rendering as the langgraph-python variants
Index page (URL-only, not in sidebar):
- [ ] `/unselected/prebuilt-components` — 3 variant subsections
(CopilotChat, CopilotSidebar, CopilotPopup), each showing a real-source
Snippet block; Deep customization is a one-paragraph pointer to Slots,
no code
Replaces the three hand-written tsx fences (CopilotChat, CopilotSidebar,
CopilotPopup variants) with Snippet references pointing at real showcase
regions: chat-component in agentic-chat, sidebar-basic-setup in
prebuilt-sidebar, and popup-basic-setup in prebuilt-popup.
Also drops the redundant Deep customization inline example — the section
already links out to the dedicated Slots guide; a hand-written slot-pattern
example duplicates what that guide covers with real code. Shortened the
lead-in to point readers at Slots for runnable examples.
One fence remains on this page: the 'Setup' section's CSS stylesheet import,
a one-line CLI-style instruction with no corresponding showcase region.
Left inline as a legitimate snippet-linking exception (same pattern used
for npx commands).
Replaces the hand-written tsx fence in the 'Code example' section of both
docs/prebuilt-components/chat.mdx and docs/unselected/prebuilt-components/chat.mdx
with a <Snippet> reference to a new chat-component region in the
langgraph-python agentic-chat demo source.
The new @region[chat-component] wraps the whole Chat helper function in
showcase/packages/langgraph-python/src/app/demos/agentic-chat/page.tsx,
so readers see a self-contained real-code component (hook + render) with
the view-source link that a Snippet provides.
Also regenerates the three demo-content.json bundles to include the new
region.
Declare open-gen-ui and open-gen-ui-advanced in langgraph-python
manifest (code existed, was never registered). Add both to
constrained-explicit allowlist, fill shell_docs_path for 5 demos,
add hitl-in-app override, drop stale chat-customization-css fallback.
Regenerate registry.json, demo-content.json, constraints.json,
and docs-status.json across shell / shell-dojo / shell-docs.
Bump feature/demo count assertion 30→32 in generate-registry test.
Extend check-binaries.sh whitelist for sister-shell demo-content.
Resolves former priority item 5. The Styling sections on the chat, sidebar,
and popup prebuilt-component pages (base + unselected/) each had an inline
tsx code fence that duplicated styling patterns already covered on the
dedicated /custom-look-and-feel/{css,slots,headless-ui} pages. Per Atai's
directive that every code fence in shell-docs should be a showcase-linked
Snippet, not hand-written, removing these fences is the right move here.
Section headers, intro copy, and bullet links to the dedicated styling
pages are preserved — those are legitimate pointers.
The Styling section referenced "import the stylesheet once at your app
boundary" but the fenced block was empty, leaving users with nowhere
to copy from.
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.
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.
Adds multimodal-attachments, runtime-server-adapter, and vs-code-extension
pages under a new ---Platform--- section in meta.json. threads.mdx was
already in place and left untouched. fumadocs-ui import lines are stripped
since shell-docs pulls components from its MDX registry instead.
When the runtime registers an agent as default, CopilotKit hooks auto-select
it; passing agentId: "default" (or a stale "assistant" ID that isn't
actually registered) is noise. Applies to built-in-agent/shared-state.mdx
and unselected/shared-state.mdx across shell-docs and upstream.
Goal: fast 'wow that's fast' initial experience for users trying the
built-in agent. Sweeps shell-docs unselected/ and upstream built-in-agent/
so both trees match. Also collapses two mismatched GPT-4o rows in the
model-selection table into a single honest 'GPT-5.4 Mini' row.
LangChain wants to be referred to as LangChain in docs; LangGraph is the
under-the-hood graph framework. Updates prose only — URLs, package names,
code identifiers, and LangGraph Studio/Platform product names are preserved.
Upstream docs/ already reflects this change; this brings shell-docs into
alignment so the next sync does not regress.
⚠️ **Docs sync — MANUAL REVIEW REQUIRED**
This PR was auto-opened because the docs-sync script detected
showcase-local modifications overlapping with upstream changes.
The script attempted a best-effort 3-way merge:
- Where `git merge-file` produced a clean merge, the merged content was
written.
- Where `git merge-file` produced conflict markers, **upstream content
was written as-is** and showcase-local modifications were overridden.
**Manual review required.**
### Review items
```
Files where 3-way merge FAILED — upstream content written as-is, local modifications overridden. Manual review REQUIRED before merging this PR:
- docs/snippets/shared/generative-ui/tool-rendering.mdx
Files auto-merged via 3-way merge (clean, no conflict markers — still worth a glance):
- docs/content/docs/integrations/langgraph/generative-ui/state-rendering.mdx
```
### Source
- Upstream ref:
[`189c45fb4`](https://github.com/CopilotKit/CopilotKit/commit/189c45fb4)
- Workflow run:
https://github.com/CopilotKit/CopilotKit/actions/runs/24736203326
**Review before merging.** Auto-merge is intentionally disabled
for `needs-review` PRs — confirm the upstream-wins sections
preserve any intentional showcase-local divergence you want to
keep, then merge manually.
The initial shell-docs content-import left 21 reference pages with missing
import statements: 8 component pages had empty `## Import` code fences, and
13 hook pages had `## Signature` fences whose leading `import { X } from
"@copilotkit/react-core/v2";` line was stripped.
This commit restores the import(s) in the Import and Signature fences only.
Usage examples and other code blocks are intentionally not touched.
- 8 components: fill empty Import fence with named (or default for
CopilotChatView) import + styles.css side-effect import
- 13 hooks: prepend import line(s) at the top of the Signature fence.
- useComponent: 3 imports (z, type ComponentType, useComponent)
- useRenderTool: imports injected into both Wildcard and Named overload fences
- useCopilotChatConfiguration: imports injected into both Provider and
hook ### Signature subblocks
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.
- Update registry.json, demo-content.json, status.json, constraints.json,
docs-status.json across shell/shell-docs/shell-dojo
- Add integration="langgraph-python" default to quickstart InlineDemo so
the base unscoped page shows a demo instead of being empty
- 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
- 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