164 Commits

Author SHA1 Message Date
Lukas Moschitz d2b1e61c9f fix(showcase): redirect the legacy premium inspector and guides URLs
Two legacy docs URLs have been dead ends since cc8c945893 ("refactor(docs):
optimize structure, content and navigability", 2026-02-23). That commit had no
redirect config to update — seo-redirects.ts did not exist yet — and nobody
back-filled the entries when it was built.

`/premium/inspector` 404s. The commit renamed `(root)/premium/inspector.mdx` to
`(root)/inspector.mdx` with identical content, so the page still exists; only
the URL moved. Points at /inspector now, expanded over the framework slugs the
way the observability entries are, since /langgraph-python/inspector and its
siblings are served too.

`/direct-to-llm/guides/premium/*` loses the page. All four of them — overview,
headless-ui, observability, inspector — were deleted in the same commit, and
the R16 `/direct-to-llm/:path*` wildcard drops the remainder on the docs home.
That reads as a working link while serving the wrong page, which is why it went
unnoticed longer than a 404 would have. Each gets an exact entry.

Both need entries on the docs host and the shell host: P7 renames `/premium/*`
to a docs-host `/intelligence/*` on the way across, so without the shell entry
the legacy shell URL would 301 into a docs-host 404. The harness driver is the
intentional copy of the shell list and moves with it.

Exact sources beat every wildcard — middleware checks exactMap before the
wildcard list — so these win over INTEL-rename-wild, which would otherwise
rewrite them to a nonexistent /intelligence/inspector.

The decommission report fixtures move with the catalogue: 390 to 395 entries
defined, 377 to 382 zero-hit candidates, plus the five new ids. Regenerated
through the CLI with --events-json so the byte-for-byte cross-check against the
core module keeps its meaning.

Verified all 24 distinct destinations against staging. 22 return 200.
/langroid/inspector and /spring-ai/inspector 404, because those two framework
surfaces are not served at all — their bare roots and quickstarts 404 too. The
existing observability entries carry the same property, so no reachable URL
changes behavior.
2026-09-02 16:39:04 +02:00
Lukas Moschitz 91ee5aa764 fix(showcase): 301 the legacy premium URLs onto the renamed Intelligence tree
/premium/* is an indexed URL surface, so the folder rename needs a
redirect for every old path — at the root and under each of the 22
canonical and 14 legacy framework slugs. A wildcard covers the tree
(including future pages and the .md/.mdx LLM variants); exact entries
cover the bare folder URLs, which no wildcard prefix can match.

Existing entries that pointed INTO the tree are repointed: the retired
observability pages, the premium folder index, and four next.config
destinations. Sources are left untouched — they describe URLs that must
keep resolving.

Two entries in next.config keep the built-in-agent surface at one hop:
its generic prefix-stripping catch-all runs before the middleware and
would otherwise hand the middleware a /premium/ path to rename in a
second hop.

The shell host and the harness probe carry their own copies of the
table, and the harness header requires them to stay in sync or the
decommission report surfaces phantom zero-hit entries. Both updated.

Refs OSS-1078
2026-09-01 14:00:37 +02:00
Ran Shem Tov 766ac3afd3 test(showcase): refresh unavailable backend fixture 2026-08-11 23:02:05 +03:00
Mike Ryan 4d32d941eb feat(showcase): checkpoint 4 - all supported features and docs 2026-07-23 07:14:55 -07:00
Jordan Ritter 0f0b763d58 fix: migrate globals.css styles import to @copilotkit/react-core/v2 (missed in @copilotkitnext sweep) 2026-06-18 16:38:05 -07:00
Jordan Ritter 1398fe225c chore: migrate @copilotkitnext usages to @copilotkit/*/v2 entrypoints 2026-06-18 16:37:58 -07:00
Jordan Ritter 7f9b63b069 fix(showcase/shell): clamp profile-client file-list when collapsed 2026-06-11 16:15:13 -07:00
Jordan Ritter 6dea8ad764 style(showcase): apply oxfmt to SU shell-runtime-urls follow-up files
Pure prettier-style rewrite (line-wrapping, single-line collapses, multi-
line callback indentation). No semantic changes — confirmed via tsc clean,
oxlint clean, vitest 235/235 pass in showcase/shell.

Touched files:
- showcase/scripts/__tests__/generate-registry-pattern.test.ts
- showcase/scripts/generate-registry.ts
- showcase/shell/src/lib/backend-url.ts
- showcase/shell/src/lib/backend-url.test.ts
- showcase/shell/src/lib/docs-redirects.test.ts
- showcase/shell/src/lib/local-backends-env.test.ts
- showcase/shell/src/lib/runtime-config.ts
- showcase/shell/src/lib/runtime-config.test.ts
- showcase/shell/src/lib/runtime-url-wiring.test.ts
- showcase/shell/src/middleware.ts
- showcase/shell/src/middleware.test.ts
- showcase/shell/vitest.global-setup.ts
2026-06-11 14:02:36 -07:00
Jordan Ritter 8e427bbc0a fix(showcase): final-round backend-pattern + POSTHOG + table + script-side parity (SU7-F1/F2/F3)
SU7-F1 — backend host pattern hardening:
- F1.1  Reject bare trailing ?/# in the backend host pattern
- F1.2  Strip internal tab/CR/LF from the backend host pattern
- F1.3  Warn when ignoring an empty-string local backend override
- F1.4  Reject empty-userinfo @ in the backend host pattern authority
- F1.5  Keep __proto__ keys as data in local-backend maps
- F1.6  Commit the local-backends memo key only after the value computes
- F1.7  Trim local backend overrides before validation and name the real
        rejection
- F1.8  Honest FATAL when the pattern host is a stray scheme fragment
- F1.9  Canonicalize the pattern authority for parity with the override
        path
- F1.10 Acknowledge the staging-to-prod fail-open in the pattern fallback
- F1.11 Harden backend-url/local-backends-env test hygiene

SU7-F2 — runtime-config & client-config edge cases:
- F2.1  Branch POSTHOG_HOST rejection reasons (scheme/degenerate/parse-
        failure) instead of the catch-all mislabel
- F2.2  Reject loopback BASE_URL/DOCS_HOST in production instead of the
        silent http:// prepend
- F2.3  Key the DOCS_HOST fallback once-guard on (mode, shellHost, value)
        and mode-prefix all value-only guard keys
- F2.4  Reject a present-but-empty posthogKey in the client config reader
- F2.5  Drop the trailing slash from SSR_PLACEHOLDER_URL for structural
        parity with server values
- F2.6  Attribute the DOCS_HOST slash-strip to readDocsHost itself
- F2.7  Normalize trailing-dot FQDN spellings in the docs self-host loop
        guard (both compare sides)
- F2.8  Harden console spies to capture all log args; pin the full all-env
        config shape; converge SSR simulation on vi.stubGlobal

SU7-F3 — script-side parity, table classification & test isolation:
- F3 #1  Handle a missing reference integration per the error contract
- F3 #2  Port the runtime backend-host-pattern normalization into the
         generator — scheme/trailing-slash strip, degenerate fallback,
         NEXT_PUBLIC fallback
- F3 #3  Treat non-mapping manifest parses (empty/null/scalar/array YAML)
         as validation errors, not TypeErrors
- F3 #4  Label a missing/unreadable constraints.yaml per the stderr+exit(1)
         error contract
- F3 #5  Align atomic-write tmp naming with the test harness straggler-
         sweep convention; guard main() on direct invocation
- F3 #6  Correct the determineCellStatus unshipped docstring; replace
         stale hardcoded cell counts with formulas
- F3 #7  Isolate the pattern suite on a per-suite tmpdir harness; snapshot
         the generator's full write set
- F3 #8  Classify discarded duplicate wildcards as duplicates — hoist the
         owner check above the destination warns
- F3 #9  Reject a root ("/") EXACT seo-redirect source — homepage-hijack
         twin of the root-wildcard guard
- F3 #10 Reject seo-redirect entries with non-printable-ASCII source/
         destination — close the silent-dead-entry class
- F3 #11 Strip trailing slashes in normalizePosthogHost before the scheme
         test
- F3 #12 Message-filter the empty-slug-set error count; pin the single
         matcher entry
2026-06-11 14:01:15 -07:00
Jordan Ritter 4f9f5dba4c fix(showcase/shell): docs-host robustness, builder & matcher hardening (SU2-stragglers + SU5 + SU6-A/B)
Round-by-round CR convergence covering the redirect builder, the middleware
matcher, the docs-host self-loop guard, and the runtime-config env readers.

Highlights:
- Clear module-load warns after fresh middleware import
- Validate SET BASE_URL values (scheme-less/degenerate/garbage) with
  sentinel fallback + once-guarded FATAL log
- Normalize path/query/fragment-bearing DOCS_HOST to origin; reject
  non-http(s) schemes; branch rejection reasons
- Harden POSTHOG_HOST (degenerate-host/scheme rejection); expose
  posthogKey via readEnvPair semantics
- Reject a DOCS_HOST equal to the shell's own host (redirect-loop guard,
  authority compare)
- Warn on missing local-ports.json under SHOWCASE_LOCAL=1 and validate
  TCP port range; extract helper for tests
- backend-url hardening — slug charset guard, frozen local-backends memo,
  pattern path-segment warn, local-override URL validation
- Client config fail-loud covers all four URL fields with type checks
- Make RuntimeConfig.posthogKey optional — absence is a valid state, not
  a wiring bug
- Drop R15/R17 and guard /integrations from SEO redirects
- Dedup duplicate wildcard prefixes with first-match-wins warn
- Validate malformed SEO entries at lookup-build time
- Restore case-insensitive redirect matching parity
- Normalize trailing slashes before redirect matching
- Keep the framework segment on F13, pin MG3 case fix
- Read posthogKey from runtime config in middleware, not raw process.env
- Fall back to the default backend host pattern for degenerate values
- Disable docs redirects when the default fallback collides with the
  shell host
- Bring validateBaseUrl to parity with its sibling readers
- Strip query/fragment from POSTHOG_HOST while keeping reverse-proxy paths
- Restrict local backend overrides to http(s) URLs
- Add server-only guard to runtime-config
- Harden localBackendsEnv failure posture
- Hoist /integrations namespace guard above the docs-host redirect
- Validate seo-redirect sources and cross-kind shadowing in
  buildRedirectLookup
- Unify slash normalization for middleware matching
- Lowercase-normalize REGISTRY_FRAMEWORK_SLUGS at construction
- Escalate missing POSTHOG_KEY to console.error in production
- Skip all redirect steps when docs redirects are disabled (sentinel
  consumer)
- Reject userinfo credentials in DOCS_HOST, POSTHOG_HOST, and the backend
  host pattern
- Branch dev-vs-prod logging in readDocsHost and fatalPatternOnce
- Prepend http:// (not https://) to scheme-less loopback hosts
- Round-5 micro-finding batch across the URL config libs

SU5-A1..A7 — registry safety, // reject, builder lint batch (case-
insensitive :path*, same-destination twin allowlist, original-case
divergence remainder), matcher api boundary, generator+vitest infra, test
hygiene + empty docs-host guard, comment batch.

SU6-A1..A6 — reject miscased :path* tokens, warn on tokenless wildcards,
normalize redirect-destination comparisons like request time, reject
destinations containing "//", surface missing POSTHOG_KEY at config-
resolution time, compile matcher harness like Next's runtime, type
parse/tokensToRegexp in the path-to-regexp shim, keep buildRedirectLookup
JSDoc attached.

SU6-B1..B7 — reject query/fragment/userinfo in pattern and local-override
URL gates, return parsed-normalized URL form from validation success
paths, distinguish unset/blank/padded SHOWCASE_LOCAL states, warn when
SHOWCASE_LOCAL is set to a value other than 1, validate {slug} placeholder
in generate-registry, mirror middleware drop semantics in the wiring
test's registry re-derivation, pin the noStore spy and calls to one fresh
module instance in the Edge-path test.
2026-06-11 14:00:50 -07:00
Jordan Ritter b28a1dc494 fix(showcase/shell): runtime-config + backend-url env-hardening; redirect builder safety (SU2-A/B + CR2-C)
SU2-B series — runtime-config / backend-url env robustness:
- Correct the Edge-safety story in runtime-config (SU2-B1)
- Stop per-request FATAL-CONFIG spam for unset BASE_URL (SU2-B2)
- Prepend https:// to a scheme-less POSTHOG_HOST (SU2-B3)
- Trim whitespace paste artifacts in env values and host patterns (SU2-B4)
- Memoize parseLocalBackends and warn once per value (SU2-B5)
- Make {slug} substitution immune to $-patterns (SU2-B6)
- Harden the client runtime-config reader (SU2-B7)
- runtime-config hardening batch (SU2-B8)
- Validate local-ports.json before baking NEXT_PUBLIC_LOCAL_BACKENDS (SU2-B9)
- test: warn-once assertions retry-safe; stop console leaks (SU2-B10)

CR2-C series — test infrastructure:
- Generate registry.json in a vitest globalSetup (CR2-C1)
- Stop ambient POSTHOG_KEY firing real fetches in middleware tests (CR2-C2)
- Assert the production slug set, not a re-derivation (CR2-C3)
- Make the registry generator subprocess robust (CR2-C4)
- Middleware/wiring test hygiene batch (CR2-C5)

SU2-A series — redirect-layer & PostHog capture:
- Stop $-pattern expansion in wildcard redirect substitution (SU2-A1)
- Surface PostHog capture failures once per failure class (SU2-A2)
- Duplicate exact redirect sources are first-match-wins (SU2-A3)
- Resolve runtime config once per redirected request (SU2-A4)
- Include destination host in seo_redirect capture (SU2-A5)
- Normalize scheme-less POSTHOG_HOST at the capture use site (SU2-A6)
- Correct redirect-layer comments and guard wildcard prefix boundary (SU2-A7)
- Cover docs-host hardening branches, compile matcher via path-to-regexp (SU2-A8)
2026-06-11 14:00:20 -07:00
Jordan Ritter 426ae3a8e1 fix(showcase/shell): SEO redirect table + middleware matcher hardening (SU-2/8/11/14/15/16/17/18/19/20)
Resolve SEO redirect destinations against the docs host (SU-17); forward
the query string on SEO redirects (SU-16); match bare paths on wildcard
SEO sources (SU-19). Collapse duplicate slashes in docs-host redirect
destinations (SU-13). Regression test for /shared//evil.com open redirect
(SU-18). Emit 308 for docs-host redirects to match next.config parity
(SU-2). Add a path boundary to the api matcher exclusion (SU-15). Loud
guard when registry yields zero framework slugs (SU-20). Keep PostHog
capture alive via event.waitUntil (SU-14). Note docs-host redirects are
untracked by design (SU-8). Cover docs-host redirects at the middleware
level (SU-11).

Squash of the SEO-table + matcher-hardening cluster.
2026-06-11 14:00:03 -07:00
Jordan Ritter febd8bc946 feat(showcase/shell): runtime-derived backend URLs and docs-host redirects (SU-13)
Carry backendHostPattern + docsHost in the shell runtime config (no longer
baked from registry.json at Docker build time). Derive demo backend URLs at
runtime from the pattern; issue docs-host 301s from middleware with a runtime
DOCS_HOST so a misconfigured value can no longer 500 every docs route.

Validate NEXT_PUBLIC_LOCAL_BACKENDS and empty overrides; guard the backend
host pattern against silent env misconfigs. Reword the stale demo-page
comment about backend URL derivation. Pin the registry slug set and SSR
placeholder URL composition; fix env/spy/global leaks in runtime-config
test cleanup.

Squash of the initial runtime-URL refactor cluster:
- feat(showcase): carry backendHostPattern + docsHost in shell runtime config
- fix(showcase): derive demo backend URLs at runtime instead of baked registry values
- fix(showcase): issue docs-host 301s from middleware with runtime DOCS_HOST
- fix(showcase): never let a misconfigured DOCS_HOST 500 every docs route
- fix(showcase): guard backend host pattern against silent env misconfigs
- fix(showcase): validate NEXT_PUBLIC_LOCAL_BACKENDS values and empty overrides
- docs(showcase): reword stale demo-page comment about backend URL derivation
- test(showcase): fix env/spy/global leaks in runtime-config test cleanup
- test(showcase): pin registry slug set and SSR placeholder URL composition
2026-06-11 13:59:46 -07:00
Jordan Ritter 9871d06671 refactor(showcase): rename getRuntimeConfigEdge to getRuntimeConfigForMiddleware
Clarify the wrapper's role (it forces noStore:false because unstable_noStore is
unavailable in middleware/Edge). Pure rename across shell, shell-docs, and
shell-dashboard: definitions, middleware call sites, and tests. No behavior
change.
2026-05-30 10:22:35 -07:00
Jordan Ritter 8714ab569b chore(showcase): apply oxfmt formatting across showcase scripts and shells
oxfmt --write normalized formatting on showcase scripts, the four shells, and the
new oxlint rule; required for the repo-root oxfmt --check CI gate.
2026-05-29 11:45:16 -07:00
Jordan Ritter 09b9f8910b chore(showcase): pre-push cleanup -- comment rot, log levels, env coalesce, test hardening
Non-functional cleanup pass on the showcase deploy-pipeline integration
branch. All changes are scoped to comment rot, log severity for already-
demoted runtime-config fields, length-aware env-name coalescing (a
deliberately-empty primary no longer masks a populated alternate), and
test-quality tightening. No production behavior change beyond the
specific items below.

Changes by area:

- shell/shell-dashboard/shell-docs runtime-config.ts: factor the
  `process.env[primary] ?? process.env[alt]` chain into a shared
  length-aware `readEnvPair` helper. The prior `??` form treated
  `PRIMARY=""` as set, masking a populated alternate; the helper now
  treats empty-string as unset and falls through to the alternate.
- shell-docs runtime-config.ts: demote the two recoverable URL fields
  (`intelligenceSignupUrl`, `posthogHost`) from console.info to
  console.warn. The `FATAL-CONFIG:` Sentry-alert prefix is preserved
  only on the true sentinels; the demoted fields now clear prod log-
  aggregation thresholds without raising ops alerts.
- All three shells' runtime-config.ts: prefix log lines with the shell
  name (e.g. `[shell-docs runtime-config]`) so the shared log stream
  identifies which shell emitted the line.
- shell-docs runtime-config-serialize.ts: rewrite the U+2028 / U+2029
  RegExp arguments using six-character ASCII backslash-u escape
  sequences (was: literal codepoints in the string arg). The literal
  codepoints are line terminators that a formatter or editor could
  silently strip, breaking the security-critical XSS escape. The
  ASCII form is robust to any such pass.
- shell-docs use-google-analytics.test.ts: de-tautologize the hook-
  order test. It now asserts `usePathname(` and `useEffect(` both
  exist in the source, so deleting all hooks would fail the test
  rather than trivially satisfying the early-return path.
- shell-dashboard baseline-types.test.ts: update the partner-count
  expectation from 25 to 26 -- the 26th entry (Cloudflare) is a
  legitimate integration that landed independently; the test was
  stale and had nothing to do with this branch.
- scripts/resolve-verify-matrix.ts: drop the `FIX 7 --` plan-
  internal prefix from a comment; keep the explanation.
- shell-docs/.env.example: correct the `NEXT_PUBLIC_SHELL_URL`
  fallback claim (sentinel, not canonical prod host) and document
  the remaining 7 consumed env vars with their FATAL/warn/silent
  semantics so the example matches runtime-config.ts.

Skipped:
- C-SENTINEL-DEDUP (`http://ops.invalid` shared constant across
  shell-dashboard's next.config.ts and runtime-config.ts): both
  files are at different module levels (root vs src/lib) and the
  string appears once in each; extracting to a shared module would
  widen the diff into a refactor for marginal benefit. Skipped per
  the spec's "if it widens diff awkwardly, skip" guidance.
- C-SSRTEST: already exhaustively covered. Each of the three shells
  has an SSR placeholder test that exercises every URL field via
  `new URL()` parseability and (for shell-docs) the analytics-key
  empty-string semantics. Treated as a no-op.

Validation: shell + shell-dashboard + shell-docs runtime-config /
serialize / GA tests green; bin/showcase Ruby suite green (87 runs);
showcase/scripts resolve-verify-matrix + aggregate-build-results +
lint-rule-no-public-env green (79 runs).
2026-05-29 11:45:15 -07:00
Jordan Ritter 28f33ecc8a fix(showcase): stop SSR 500 + hook-order regressions in shell runtime-config; tolerate env-name variants
Six fixes addressing CR findings on the Option-B runtime URL-injection migration:

1. SSR_PLACEHOLDER must be parseable URL sentinels — `new URL("")` throws on
   SSR causing 500s for any consumer that constructs URLs from runtime-config
   fields. Use `.invalid`-TLD sentinels (RFC 2606) for URL fields; analytics
   keys stay empty string. Add `suppressHydrationWarning` on consumers that
   render the placeholder server-side and the real value post-hydration
   (integration-grid, page-actions popover).

2. Hook-order: move `usePathname()`/`useEffect` ABOVE the early-return in
   use-google-analytics. Gate the effect bodies on `GA_ID` instead so React
   sees a stable hook order across renders.

3. `readUrl`/`readKey` accept either bare or `NEXT_PUBLIC_*`-prefixed env
   names via a fallback chain — covers both server-only and inlined-public
   variable conventions without forcing a rename across deploy targets.

4. Extract `serializeRuntimeConfig` to `lib/runtime-config-serialize.ts` so
   the OWASP-escape behavior (XSS via </script>, U+2028/U+2029 line-terminator
   injection) can be unit-tested without importing the layout into vitest.

5. Reclassify `intelligenceSignupUrl`/`posthogHost` from FATAL-CONFIG to
   info-level in shell-docs — these are optional integrations, not hard
   wiring failures, so absence should not poison the error stream.

6. Comment-rot cleanup: drop "Option B", B12, "the bug we are fixing", fix
   "four substrings"→"three substrings" miscounts, and refresh shell-docs
   .env.example to describe the runtime-injection contract instead of a
   stale next.config throw claim.

V1: shell + shell-docs `next build` succeeds (no Edge-runtime crash on
`unstable_noStore`).
V2: `OPS_BASE_URL=` shell-dashboard `next build` no longer throws —
`next.config.ts` is now a phase-aware function that emits a sentinel
destination at build time and throws only at start (PHASE_PRODUCTION_BUILD
from next/constants).

Tests: shell-docs 72/72, shell 12/12, shell-dashboard runtime-config 16/16
(pre-existing baseline-partner-count failure unchanged).
2026-05-29 11:45:15 -07:00
Jordan Ritter 6d9d48ddd0 fix(showcase): SSR-safe runtime-config client for shell-docs/shell/shell-dojo (sentinel, not throw)
getRuntimeConfig() in each shell's runtime-config.client.ts threw when
typeof window === 'undefined'. But Next.js App Router executes 'use
client' component bodies on the SERVER during initial SSR, so any client
component that called getRuntimeConfig() in its render body 500'd the
page. shell-dashboard already had the fix.

Mirror shell-dashboard's pattern: return a typed SSR_PLACEHOLDER (empty
strings for URL/key fields; {} for shell-dojo whose RuntimeConfig is
empty) when window is undefined. Keep the loud throw when window IS
present but window.__SHOWCASE_CONFIG__ is missing — that's a genuine
wiring bug and should not be masked.

Updated shell-docs and shell client tests: replace 'throws on server'
case with 'returns SSR sentinel placeholder' assertion matching each
shell's RuntimeConfig shape. shell-dojo has no client test so verified
via tsc only.
2026-05-29 11:45:09 -07:00
Jordan Ritter 839ec9c573 refactor(showcase): migrate shell middleware to runtime-config
Replaces the module-load read of NEXT_PUBLIC_POSTHOG_HOST in
showcase/shell/src/middleware.ts (which Next inlines into the Edge
bundle at build time and freezes per artifact) with a per-request
read via getRuntimeConfigEdge().posthogHost. The Edge wrapper skips
unstable_noStore() — next/cache is not available in the Edge
runtime, and middleware always runs per-request so there is no
static cache to opt out of.

Refs plan-B §B9.6.
2026-05-29 11:45:07 -07:00
Jordan Ritter ef3c7d7b7b refactor(showcase): inject __SHOWCASE_CONFIG__ in shell root layout
Adds a <head> element (shell previously had only <html> → <body>) and
emits an inline <script> as its first child that writes
window.__SHOWCASE_CONFIG__ from the server-side runtime config before
any client component mounts. The injection JSON is OWASP-escaped:
< → < (guards against </script> breakout from a hostile env
value), and U+2028 / U+2029 are escaped to 
 / 
 (line
separators are legal inside JSON strings but a syntax error inside a
JS string literal in pre-ES2019 engines / when parsed as
text/javascript).

The commit-sha overlay continues to read process.env.NEXT_PUBLIC_COMMIT_SHA
directly — COMMIT_SHA is build-stamped intentionally (identifies the
artifact, not the env).

Refs plan-B §B6.
2026-05-29 11:45:07 -07:00
Jordan Ritter 83af6b8530 feat(showcase): add shell runtime-config server+client
Introduces showcase/shell/src/lib/runtime-config.ts (server-only —
imports next/cache and is read at request time by the root layout)
plus runtime-config.client.ts (reads window.__SHOWCASE_CONFIG__
injected by the layout). Shell's RuntimeConfig contains baseUrl and
posthogHost. getRuntimeConfigEdge() provides the Edge-runtime variant
for middleware (skips unstable_noStore).

Adds vitest config + dev deps to package.json and red-green tests for
both modules. Tests verify env-vs-fallback precedence, trailing-slash
stripping, no-module-load-freeze (live process.env reads per call),
and the Edge wrapper's noStore-skip behavior.

Refs plan-B §B7.
2026-05-29 11:45:07 -07:00
Tyler Slaton a5050dbe26 fix(showcase): retarget R15/R17 in legacy shell + harness copies
The shell-docs port (e2bef7a0b) updated R15/R17 sources to /integrations/built-in-agent
in showcase/shell-docs/src/lib/seo-redirects.ts and refreshed the snapshot fixture, but
left the legacy shell copy (showcase/shell/src/lib/seo-redirects.ts) and the harness
intentional-copy (showcase/harness/src/probes/drivers/seo-redirects.ts) on the old
/builtin-agent value. The redirect-decommission test imports from the legacy shell
file, so the snapshot diverged: fixture says /integrations/built-in-agent but source
generates /builtin-agent. Mirror the retargeting into both copies so all three files
(shell-docs source, shell legacy source, harness synced copy) agree with the fixture
and Validate Showcase passes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 22:41:18 -07:00
github-actions[bot] a2bfa49b9a style: auto-fix formatting 2026-05-07 16:53:44 +00:00
Sam Julien f5a611f20f feat(shell-docs): port redirect middleware + retarget destinations to shell-docs slugs
Part 1 — Retarget seo-redirects.ts destinations:

- Drop the legacy /docs/integrations/ prefix everywhere; shell-docs
  serves canonical framework docs at /<fw-slug>/<...> from the host
  root.
- Apply registry-slug renames in destinations:
    langgraph                  → langgraph-python
    adk                        → google-adk
    aws-strands                → strands
    microsoft-agent-framework  → ms-agent-dotnet
    crewai-flows               → crewai-crews
    unselected                 → built-in-agent (BIA canonical re-flip)
- Add slug-rename catch-alls for the bare /<old-slug>/* form so legacy
  upstream URLs (e.g. /langgraph/quickstart) 301 to the new slug.
- Add /docs/integrations/* and /docs/* catch-alls so any URL still
  carrying the legacy SHELL routing prefix lands at the shell-docs
  equivalent.
- Add /migration-guides/* → /migrate/* (4 URLs).
- Add folder-index redirects for shell-docs folders without an
  index.mdx (/troubleshooting, /migrate, /premium, /concepts,
  /reference) so bare folder URLs land on a representative inner page.

Part 2 — Port the redirect middleware to shell-docs:

- Copy the retargeted seo-redirects.ts to shell-docs/src/lib/.
- Merge the SHELL redirect-middleware logic into shell-docs's existing
  pageview-tracking middleware: redirects fire first (with seo_redirect
  PostHog event), and non-redirected requests still get the
  docs_pageview capture and distinct_id cookie.
- Preserve the framework-scoped short-circuit so canonical
  /<fw-slug>/<...> URLs are never hijacked by legacy patterns.
- Leave the SHELL versions in place — the SHELL still serves
  docs.showcase.copilotkit.ai until DNS flips.

Verified shell-docs and SHELL builds clean. Spot-checked redirects on a
local shell-docs server: /docs/integrations/langgraph/quickstart →
/langgraph-python/quickstart, /langgraph/quickstart →
/langgraph-python/quickstart, /migration-guides/v2 → /migrate/v2,
/troubleshooting → /troubleshooting/common-issues, /coagents →
/langgraph-python, /aws-strands/quickstart → /strands/quickstart.
2026-05-07 09:52:02 -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
Alem Tuzlak 5a9b5bdf7e fix(showcase): allow microphone in demo iframe so voice demos work
The shell embeds each demo in a cross-origin iframe whose `allow`
attribute only granted clipboard access. Browsers block
`getUserMedia({ audio: true })` at the Permissions Policy layer in
cross-origin frames unless the parent grants `microphone` via `allow`,
so every voice demo across every integration threw "Microphone
permission denied" before any user prompt was shown.

Add `microphone` to the iframe `allow` in all three places that embed
demo previews — the per-demo viewer, the standalone preview route, and
the demo drawer — so voice demos work uniformly across all 18
integrations. No other demo type uses getUserMedia / getDisplayMedia
/ geolocation, so no other Permissions Policy features are needed.
2026-05-01 10:45:45 +02:00
Jordan Ritter 1cd151e5b8 feat(showcase): add favicon and og:image
Heater shield with CopilotKit kite logo in magenta on dark
background, matching the sub-property icon style across
copilotkit.dev properties. Wires up Next.js metadata for
title, description, icons, and openGraph.
2026-04-29 20:03:33 -07:00
Alem Tuzlak 6f9f3f220e Merge remote-tracking branch 'origin/main' into fix/showcase-shell-cli-start-not-live-demo
# Conflicts:
#	showcase/shell/src/data/registry.json
2026-04-24 13:16:45 +02:00
Alem Tuzlak d936bc726d fix(showcase-shell): guard demo.route in viewer + preview, share Demo type
Review feedback from #4196:

- `[slug]/[demo]/page.tsx` constructed `${backend_url}${demo.route}`
  without a null check, so command-only demos (which have no `route`)
  rendered an iframe pointing at `${backend_url}undefined`. Now builds
  the src only when `demo.route` exists and renders a 'no live preview'
  panel otherwise, mirroring the Get Started section on the profile
  page. Also replaces the `any`-typed state with proper `Demo` and
  `Integration` types imported from `@/lib/registry`.
- `[slug]/[demo]/preview/page.tsx` had the same bug — already typed
  but TypeScript doesn't catch template-literal coercion of undefined.
  Now bails with a command-focused message before concatenating.
- `profile-client.tsx` no longer duplicates `Demo`/`Integration`
  interfaces — deleted the local copies and imports from
  `@/lib/registry`. copyDemoCommand's catch now logs the failure so a
  double-failure (no clipboard API + blocked prompt) is diagnosable.
  Comment above the live-demos section updated from 'Demos' to
  'Live Demos' to match the rendered heading.
2026-04-24 13:06:45 +02:00
Jordan Ritter e772879b73 fix(showcase): gitignore generated data JSON and untrack committed blobs
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.
2026-04-23 21:13:12 -07:00
Jordan Ritter 58f95a08ae fix(showcase): strip generated_at timestamps from generators and consumers
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).
2026-04-23 21:12:32 -07:00
devops-bot[bot] 0ce10b6c3d Update preview URLs in registry 2026-04-23 20:27:40 +00:00
Alem Tuzlak 6dff6200e8 feat(showcase): wire open-gen-ui demos, update manifest and constraints
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.
2026-04-23 12:45:36 -07:00
devops-bot[bot] 667ecac916 Update preview URLs in registry 2026-04-23 19:25:31 +00:00
github-actions[bot] 3b887da707 style: auto-fix formatting 2026-04-23 18:59:34 +00:00
devops-bot[bot] da78e0f874 Update preview URLs in registry 2026-04-23 18:33:23 +00:00
github-actions[bot] f35ede00c6 style: auto-fix formatting 2026-04-23 17:33:01 +00:00
devops-bot[bot] 3683106851 Update preview URLs in registry 2026-04-23 16:51:11 +00:00
github-actions[bot] e94aa1d4e1 style: auto-fix formatting 2026-04-23 16:16:22 +00:00
Jordan Ritter 9bce821779 feat(shell-dashboard): Phase 3 dashboard honesty pass
Phase 3.0: Pre-flight verified — 34 e2e_smoke rows in PB (producer
gap from PR #4200 resolved).

Phase 3.1: Rename dashboard e2e subscription to e2e_smoke to match
ops producer key. Update formatLabel/formatTooltip dim unions.

Phase 3.2: Add per-integration L1-L4 LevelStrip with Up/Wired/Chats/
Tools badges. New subscriptions for agent, chat, tools, e2e_smoke.
Widen aggregateConnection to variadic. Tools n/a gate uses
integration.demos.some(d => d.id === "tool-rendering").

Phase 3.3: Retire HealthDot from per-feature cells (L1 Up badge in
strip replaces it). Drop smokeRow from per-cell rollup (Decision #7).
Rollup now uses [healthRow, e2eRow] only. First-ever green rollups
enabled (smokeRow was always null in production).

Phase 3.4: Remove QA column — drop LiveBadge QA, CellState.qa,
subscription, legend entry. No producer ever existed.

Phase 3.5: Docs four-glyph mapping: ok->checkmark, missing->middle
dot, notfound->cross, error->exclamation. Each DocState has a
distinct glyph and tone.

Phase 3.6: Legend rewrite — drop QA/Hosted, add L1-L4 strip docs,
expand docs row for four glyphs, rewrite ? footnote.

Phase 3.7: Add PackagesSection below starters grid. Extends
registry.json with packages array from shared/packages.json. CI
drift test ensures package set matches integration set.
2026-04-23 09:14:05 -07:00
devops-bot[bot] 63aebe2c00 Update preview URLs in registry 2026-04-23 16:00:34 +00:00
github-actions[bot] a8b08ab49d style: auto-fix formatting 2026-04-23 08:34:37 -07:00
Sam Julien 824553b251 chore(showcase): update generated data and quickstart default integration
- 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
2026-04-23 08:34:37 -07:00
github-actions[bot] 630f6743d9 style: auto-fix formatting 2026-04-23 12:11:52 +00:00
Alem Tuzlak 968f2fe378 fix(showcase-shell): separate CLI init command from live demos
The cli-start entry in each integration's demos[] is a copy-paste CLI
command, not a runnable demo, but the profile page rendered it as a
Live Demo tile whose drawer iframe loaded ${backend_url}undefined.

Split demos into liveDemos (runnable) and commandDemos (command-only)
and render commandDemos in a new "Get Started" section above the
Live Demos grid, mirroring how the dashboard already handles them.
2026-04-23 14:08:54 +02:00
devops-bot[bot] 4ae9af088e Update preview URLs in registry 2026-04-23 02:12:08 +00:00
github-actions[bot] f5b66a4088 style: auto-fix formatting 2026-04-22 19:20:30 +00:00
devops-bot[bot] 432345485f Update preview URLs in registry 2026-04-22 18:53:07 +00:00
Jordan Ritter af35569d7d chore(showcase/packages): QA markdown parity + integration tooling
Rename hitl.md → hitl-in-chat.md across all 17 showcase packages,
add shared-state-read / shared-state-write / shared-state-streaming /
gen-ui-agent / subagents QA docs where missing, update demos/hitl
README cross-links. Refresh showcase/shell + shell-dojo registry +
demo-content JSON to match new QA shape. Update integration tooling
(audit, create-integration, bundle-demo-content, generate-registry,
validate-parity, capture-previews, manifest lib) + e2e tests to the
new parity contract.
2026-04-22 11:00:46 -07:00
Alem Tuzlak c92dde419b fix(showcase): complete open-gen-ui scrub + fix smoke-test filter regression (#4029)
## Summary
Prior PR removed the open-gen-ui feature but left several loose ends.
This PR completes the scrub:

1. **Source YAML** — removed `open` profile + `open-gen-ui` entries from
`showcase/shared/constraints.yaml` (was missed before; would have
re-introduced `open-gen-ui` on next generator run)
2. **Schema enum** — dropped `"open"` from `generative_ui` enum in
`showcase/shared/manifest.schema.json`
3. **Test fixture** — `invalid-genui-manifest.yaml` now uses
`[unknown-profile]` instead of `[open]`; tests still pass (validator
rejects unknown profiles)
4. **Manifest descriptions** — all 17
`showcase/packages/*/manifest.yaml` files: "5 GenUI rendering
strategies" → "4" (open-gen-ui was the 5th; now removed)
5. **Derived JSON regen** — `registry.json` regenerated cleanly via
`generate-registry.ts`
6. **Smoke-test filter fix** — `integration-smoke.spec.ts:383` now reads
top-level `i.deployed` instead of stale `i.starter?.deployed`. The old
filter returned 0 starters post-regen (silent CI skip every 6h); new
filter correctly gates on canonical top-level field.

## Context
- `showcase/shell/src/data/demo-content.json` is also regenerated but
NOT committed because it exceeds the lefthook 1MB binary-size cap
(pre-existing repo condition, separate from this PR).
- 3 starters (mastra, crewai-crews, claude-sdk-typescript) that had
manually-patched `starter.deployed: false` are now covered by smoke —
verified all 3 starter URLs respond HTTP 200 live.

## Test plan
- [ ] CI green
- [ ] Post-merge `starter-smoke` workflow picks up all 17 starters (not
zero, as was the silent broken state)
- [ ] No `open-gen-ui` references remain anywhere in showcase/
2026-04-22 14:34:14 +02:00