Commit Graph

771 Commits

Author SHA1 Message Date
Jordan Ritter 87b2bb0250 fix(showcase/shell-docs): add iframe sandbox + a11y title on IframeSwitcher & YouTubeVideo
IframeSwitcher had no sandbox attribute, letting user-controlled MDX embed
malicious-origin iframes with full browser capabilities. Mirror the
InlineDemo sandbox policy (scripts/same-origin/forms/popups) and add an
a11y title.

YouTubeVideo was missing both a title (screen readers announced only the
URL) and a sandbox policy. Add sandbox tuned for YouTube embeds
(scripts/same-origin/presentation/popups) and title fallback.
2026-04-20 16:45:21 -07:00
Jordan Ritter 40aa676e8c chore(showcase/shell-docs): bump tsconfig target to ES2022
React 19 / Next 15 expects modern runtimes; ES2017 is stale. ES2022 gives
us top-level await, class fields, and error cause without needing additional
helpers. `next build` still passes.
2026-04-20 16:42:08 -07:00
Jordan Ritter 1db5e4047e chore(showcase/shell-docs): engines, start port, drop unused deps
- Add `engines.node >=18.18` to match Next.js 15 runtime requirements.
- Align `npm run start` with the dev port (3003) for local parity; the
  Docker runner sets PORT=10000 via ENV and is unaffected.
- Drop unused dependencies that are not imported anywhere in shell-docs:
  `react-markdown`, `react-syntax-highlighter`, `rehype-raw`, and
  `@types/react-syntax-highlighter`. These are used in showcase/shell/
  but not here; removing them keeps the dependency surface honest.
- Regenerate package-lock.json to match.
2026-04-20 16:42:03 -07:00
Jordan Ritter 0da65ecbce chore(showcase/shell-docs): .gitignore parity + env secret ignores
Add `.env*.local` and `*.log` entries so accidental secrets and debug
logs never land in the tree. Matches the pattern used by showcase/shell.
Leave the generated /src/data/*.json files tracked, as they are today.
2026-04-20 16:41:56 -07:00
Jordan Ritter e2d5742dfd fix(showcase/shell-docs): Dockerfile hygiene (ARG scope, npm ci, .dockerignore, direct next binary)
- Re-declare COMMIT_SHA and BRANCH ARGs in the runner stage so ENV
  interpolation resolves (ARGs do not cross stages in multi-stage builds).
- Declare NEXT_PUBLIC_BASE_URL as a build-time ARG/ENV so CI can pass it
  via --build-arg for the production `next build` (next.config.ts requires it).
- Copy lockfile for shell-docs and switch to `npm ci` for reproducible installs.
  scripts/ has no committed lockfile yet, so keep `npm install` there.
- Add .dockerignore so local .next/, node_modules/, .git, logs, and .env*
  are not slurped into the build context.
- Invoke next via node_modules/.bin/next (both build and CMD) instead of
  npx to avoid runtime network-fallback risk.
- Document the required build context at the top of the Dockerfile.
- Note the libc6-compat discussion: the slim base is Debian (glibc), so
  no compat shim is required; note how to enable it if we ever move to
  node:20-alpine.
2026-04-20 16:41:51 -07:00
Jordan Ritter 9ed2f9fb37 fix(showcase/shell-docs): StoredFrameworkHighlight reads storedFramework (feature was broken on /docs/*)
The component's name, comments, and stated purpose are to highlight the
user's remembered framework pick on the docs root pivot. The code was
keying off 'framework' (strictly URL-derived), which is always null on
/docs/* where this component is actually mounted — the 'Your choice'
badge and accent ring NEVER rendered.

Now reads 'storedFramework' (the remembered advisory preference) and
compares it against the card's slug, which is what the rest of the file
already documents it doing.
2026-04-20 16:38:20 -07:00
Jordan Ritter 4c73052c1d fix(showcase/shell-docs): RouterPivot redirects using storedFramework; aligned supported/unsupported deployed filter
Functional regressions in the docs router pivot:

1. The redirect effect was reading 'framework' (URL-derived) only. On
   /docs/<feature> the URL prefix 'docs' is never in knownFrameworks, so
   'framework' is always null and the effect never fired. The whole
   'picked-once, sticks' feature was silently broken — users with a
   stored preference were never redirected. Now prefers URL framework,
   falling back to storedFramework, as a single 'target' signal.

2. The 'Loading <framework> view...' placeholder was unreachable for the
   same reason. Now renders when 'target' is set.

3. The supported/unsupported filters disagreed on whether 'deployed'
   applied. supported = withCell (ignored deployed); unsupported =
   !withCell && deployed. Now both require deployed; undeployed
   integrations are omitted entirely rather than surfacing dead links.

4. FrameworkGuardedContent previously returned null whenever 'framework'
   was null, which on /docs/* is always. The MDX body was permanently
   hidden. Now it hides only while a redirect is imminent (URL framework
   set, or storedFramework set — both cases are about to navigate away);
   users with no stored preference see the pivot alongside the MDX body.
2026-04-20 16:38:14 -07:00
Jordan Ritter a2565ec87a fix(showcase/shell-docs): dark-mode-aware highlight.js theme import + layer ordering
- Move highlight.js @import ahead of @import "tailwindcss" so Tailwind
  utility layers can still override specific hljs selectors when needed
  rather than being silently shadowed in Tailwind v4's layer ordering.
- Scope the dark-dimmed theme via prefers-color-scheme so it only
  paints when the user's system is in dark mode. shell-docs does not
  yet ship a dark theme, but this makes syntax blocks correct the
  moment it does.
2026-04-20 16:38:05 -07:00
Jordan Ritter de5301be50 fix(showcase/shell-docs): throw on useFramework outside provider; log localStorage errors; validate slugs
- useFramework() now throws when called outside FrameworkProvider instead
  of returning a silent no-op context. Silent fallback was masking wiring
  bugs where components rendered outside the provider would report no
  framework forever.
- readStoredFramework / writeStoredFramework now log once per session on
  failure (guarded by module-scope flags) instead of swallowing errors
  entirely. localStorage may still be unavailable (SSR, private mode),
  but devs get a warning the first time.
- Dropped 'stored' from the URL-persist effect's deps. It was causing
  redundant re-check cycles every time we called setStored from within.
  The internal !== guard still short-circuits the no-op case.
- setStoredFramework now validates against knownFrameworks. Previously
  any string could poison the stored preference (e.g. a route segment
  like 'docs'); invalid slugs now warn and no-op.
2026-04-20 16:38:02 -07:00
Jordan Ritter 286b214fbf fix(showcase/shell-docs): middleware skips non-GET requests and router prefetches
`docs_pageview` was firing on every matched request — HEAD probes,
POSTs, and Next.js router prefetches all counted as pageviews, which
inflated counts and polluted funnels. Next.js App Router prefetches
links via low-priority fetches that still hit middleware, so they're
especially noisy on pages with long link lists.

We now bail out of tracking when:
  - the method is not GET
  - `next-router-prefetch: 1` is set (Next.js App Router)
  - `purpose: prefetch` is set (generic prefetch hint)

The response is still served normally; only the PostHog capture is
skipped.
2026-04-20 16:37:40 -07:00
Jordan Ritter 16d940779a chore(showcase/shell-docs): a11y-hide commit-SHA overlay; short-sha 7 chars; distinguish dev vs empty
- Add aria-hidden=true so the SHA is not announced by screen readers.
- Shorten to the conventional 7-char git short-sha (was 9).
- Distinguish 'dev' (NEXT_PUBLIC_COMMIT_SHA undefined) from 'unknown'
  (env present but empty string) so Docker ARG-scope bugs surface as
  something other than a misleading 'dev' label in production.
2026-04-20 16:37:25 -07:00
Jordan Ritter b69846c353 fix(showcase/shell-docs): tighten middleware matcher + log posthog errors + module-load warning
Three smaller cleanups to the middleware:

1. Matcher regex: `(?!api|...)` matched `/apidocs` as well as `/api`,
   dropping analytics for any docs path whose first segment starts with
   'api'. The pattern now uses `api/` with a terminator, and also
   excludes `robots.txt`, `sitemap.xml`, `manifest.webmanifest`, and
   the `.well-known/` prefix, which some static-path tooling expects
   to reach without middleware interception.

2. Capture errors are now logged via `console.warn` rather than
   silently swallowed. PostHog 401/403/5xx, DNS failures, etc. were
   invisible to operators.

3. The missing-`POSTHOG_PROJECT_KEY` warning now fires once at module
   load rather than via a module-scoped mutable flag. Edge runtime
   isolates are short-lived and per-request, so the in-memory
   warn-once flag was unreliable. Module-load is the cleanest
   available single-fire hook.
2026-04-20 16:37:07 -07:00
Jordan Ritter bb1c337255 fix(showcase/shell-docs): guard knownFrameworks against reserved-route-slug collisions
If a registry integration ever ships a slug matching a top-level route
segment (docs, ag-ui, reference, api, matrix, integrations), the
FrameworkProvider.urlFramework resolver would treat the route as a
framework scope and hijack navigation. Filter those slugs out in the
root layout and log a dev-only console.error so the collision is
visible to the maintainer.
2026-04-20 16:37:06 -07:00
Jordan Ritter 6a355693ea fix(showcase/shell-docs): drop redundant env block in next.config.ts; validate NEXT_PUBLIC_BASE_URL at build time 2026-04-20 16:37:01 -07:00
Jordan Ritter 6faf3a7bb7 fix(showcase/shell-docs): middleware uses per-visitor distinct_id via first-party cookie
The previous hard-coded distinct_id ("docs-pageview-tracker") collapsed
every visitor into a single synthetic PostHog person, which destroyed
unique-visitor analytics.

Each visitor now gets a stable UUID minted on first visit, persisted
in a first-party `ph_distinct_id` cookie (Lax, Secure, ~2 year TTL)
and read back on subsequent requests. This avoids IP+UA hashing and
the PII concerns that come with it.

Also wraps the PostHog capture POST in `event.waitUntil()` — the
middleware signature now takes `NextFetchEvent` — so the Edge runtime
keeps the request alive until the POST resolves. A bare fire-and-forget
fetch can be torn down as soon as `NextResponse.next()` returns,
dropping events.
2026-04-20 16:36:40 -07:00
Jordan Ritter a6836556d7 chore(showcase/shell-docs): add package-lock.json
Matches shell/ and shell-dashboard/ which commit their npm lockfiles to
pin standalone (non-pnpm-workspace) install closures. Ensures reproducible
Docker builds in CI.
2026-04-20 14:05:11 -07:00
Jordan Ritter b6568518ee fix(showcase/shell-docs): drop @copilotkitnext/react CSS import
shell-docs renders pure MDX docs with iframed live demos (via <InlineDemo>
and <IframeSwitcher>) — it never instantiates the live copilot runtime
inline, so it doesn't need @copilotkitnext/react or its styles. Dropping
the import also removes the package from shell-docs's dep closure, keeping
the docs shell lean.
2026-04-20 14:04:51 -07:00
Jordan Ritter c320457180 chore(showcase/shell-docs): add .gitignore matching shell-dashboard pattern 2026-04-20 14:02:45 -07:00
Jordan Ritter c298fe2ae2 fix(showcase/shell-docs): move 4085-added unselected/prebuilt-components content into shell-docs
These files were added in #4085 but landed in showcase/shell/src/content/docs/
after the MDX-docs extraction had already moved the rest of content/docs into
shell-docs. Follow The Rule (MDX docs content belongs in shell-docs) and
relocate them so they render correctly on docs.showcase.copilotkit.ai.
2026-04-20 14:00:57 -07:00
Jordan Ritter fc80501048 feat(showcase): move MDX docs routes + components + libs + content into shell-docs
Extracts everything that exists to render MDX documentation (docs/[[...slug]],
[framework]/[[...slug]], ag-ui/[[...slug]], reference/[...slug]) out of shell
into the new shell-docs package that will serve docs.showcase.copilotkit.ai.

Moves (git mv preserves history):
  - App routes: /docs, /[framework], /ag-ui, /reference
  - Docs-only components: docs-page-view, docs-callout, docs-steps, docs-tabs,
    mdx-components, framework-tabs, framework-selector, sidebar-*, snippet,
    property-reference, router-pivot, stored-framework-highlight, react/*
  - Docs-only libs: lib/docs-render, lib/mdx-registry
  - All content: content/docs, content/ag-ui, content/reference, content/snippets
  - .docs-sync-sha marker (follows the content)

Duplicates into shell-docs (both shells need them):
  - brand-nav, search-modal, search-trigger, copy-button, framework-provider
  - lib/registry.ts, data/registry.json, data/demo-content.json,
    data/search-index.json
  - app/layout.tsx + globals.css + public/{images,logos}

shell-docs gets its own minimal middleware (PostHog-only — no SEO redirect
table, docs host never served legacy URLs). shell keeps seo-redirects.ts
for the legacy-URL migration table; framework-scope protection in its
middleware is now effectively dead but harmless (next.config.ts redirects
fire before middleware ever sees /<framework>/ paths).

InlineDemo updated for cross-host context: 'Open full demo' link points
at the shell host (showcase.copilotkit.ai) since the integration profile
route only exists there.
2026-04-20 14:00:28 -07:00
Jordan Ritter dc73b9f334 chore(showcase): scaffold shell-docs package 2026-04-20 13:59:48 -07:00