189 Commits

Author SHA1 Message Date
Lukas Moschitz c1086fe5fa fix(docs): index reachable pages across docs build contexts 2026-09-05 03:05:49 +02:00
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
Jordan Ritter 069501d6dc chore(showcase): upgrade CopilotKit to 1.68.2 (lands #6576 readiness fix) 2026-08-19 20:16:28 -07:00
Mark 1232f71495 fix(showcase): sync shell lockfile for strict npm install 2026-08-15 21:27:04 -07:00
Mark db22a686cc chore(showcase): upgrade CopilotKit to 1.68.1 2026-08-15 18:46:53 -07: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 d1b07d4513 fix(showcase): stage catalog-flatten in generator envs
generate-registry.ts imports the catalog cross-join/flatten fold from
../harness/src/shared/catalog/catalog-flatten.ts, which does
`import yaml from "js-yaml"`. The generator's build/test environments did
not stage that file (or its module-resolution scope), so the fold could
not resolve.

- Dockerfiles (shell, shell-dashboard, shell-docs, shell-dojo): COPY the
  shared catalog source + harness/package.json (its `"type":"module"` is
  required so catalog-flatten resolves as ESM and its named exports bind)
  and provide a node_modules for js-yaml resolution.
- generate-registry-pattern.test.ts (makeHarness): stage catalog-flatten.ts
  and harness/package.json at the exact relative path the generator
  resolves, and symlink the scripts node_modules onto the harness tree so
  the ESM `import yaml from "js-yaml"` resolves.
- js-yaml + @types/js-yaml added to showcase/scripts (package.json and the
  npm package-lock.json), and the root pnpm-lock.yaml regenerated to add
  the matching importer entries for showcase/scripts (js-yaml >=4.1.1 via
  the root override, @types/js-yaml ^4.0.9) so `pnpm install
  --frozen-lockfile` stays in sync.
2026-07-20 22:36:14 -07:00
Ran Shem Tov 24a93672f1 feat(showcase): bump CopilotKit 1.61.1 -> 1.61.2 and adopt A2UI catalog auto-inject (#5611)
Bump the canonical CopilotKit pin across all showcase integrations + shell
to 1.61.2 (canonical-pins.json, every package.json + package-lock.json),
which carries CopilotKit#5611: passing a catalog to the provider
(`<CopilotKit a2ui={{ catalog }}>`) now auto-enables A2UI and defaults tool
injection on, so the runtime no longer needs an explicit `a2ui` config.

Demonstrate the feature on the A2UI dynamic (declarative-gen-ui) demos by
removing the now-redundant runtime `a2ui` block (`injectA2UITool: true` +
`defaultCatalogId`) from:
  - langgraph-python, langgraph-fastapi, langgraph-typescript
  - strands, strands-typescript
  - google-adk

The forwarded catalog supplies its own catalogId (sdk-js A2UI middleware
auto-derives `defaultCatalogId` from it), so the previous "Catalog not found"
fallback no longer applies.

Verified: validate-pins drift ratchet unchanged (38 / same hash);
langgraph-python D6 `gen-ui-declarative` green end-to-end (no Catalog-not-found).
2026-06-25 14:03:36 +02:00
Ran Shem Tov 9b77e8eeed chore(showcase): upgrade @copilotkit packages to 1.61.1
Bump every @copilotkit/* dependency across the showcase integrations and
the shell from 1.60.2 (and stray "latest" override pins) to an exact
1.61.1 pin, and move the canonical pin source of truth to match.
Regenerate each standalone npm package-lock.json with the same
--legacy-peer-deps flag the Dockerfiles use for "npm ci".

- showcase/integrations/*/package.json + package-lock.json
- showcase/integrations/langgraph-typescript/src/agent/*
- showcase/shell/package.json + package-lock.json
- showcase/scripts/showcase-canonical-pins.json: canonical 1.60.2 to 1.61.1

aimock stays on its own version line (1.26.1). The Python copilotkit SDK
was already 0.1.94 across every requirements.txt, so no change there.

validate-pins ratchet is unchanged (FAIL=38, identical hash);
validate-parity, validate-fixture-tool-surface, and the showcase/scripts
vitest suite (2102 tests) all pass.
2026-06-24 10:39:59 +02:00
Ran Shem Tov 8768c8a7e7 Merge remote-tracking branch 'origin/main' into claude/trusting-babbage-f4d48a 2026-06-22 16:11:21 +02:00
Ran Shem Tov 0e5b2189e7 feat(showcase): add strands-typescript integration with base demos
Add a new node/TypeScript-backed AWS Strands showcase integration at
showcase/integrations/strands-typescript.

Backend: a node/TS agent server (src/agent/) built on @strands-agents/sdk
`Agent`/`tool` wrapped in @ag-ui/aws-strands `StrandsAgent` and served via
@ag-ui/aws-strands/server (`createStrandsApp`/`addStrandsExpressEndpoint`),
modeled on the upstream ag-ui aws-strands TS example server and the
langgraph-typescript infra. A single shared agent at "/" serves most demos
(tools, shared state via toolBehaviors/stateContextBuilder, HITL,
sub-agents), with tool-free specialized agents mounted at /voice,
/byoc-hashbrown, /byoc-json-render. model-factory targets OpenAI chat
completions and honors OPENAI_API_KEY / OPENAI_BASE_URL so it works behind
the showcase aimock proxy. Node-based Dockerfile + entrypoint run the agent
server (:8000) alongside the Next.js frontend.

Frontend mirrors the strands (Python) sibling's demo set and the
langgraph-typescript conventions, with HttpAgent routes proxying to the TS
agent server.

Scope: base integration + standard demos only. A2UI / declarative-gen-ui /
a2ui-fixed-schema is intentionally excluded (no A2UI agents, routes, demos,
or deps) and layered on later.

Platform wiring (mirrors langgraph-typescript): docker-compose local/dev
services on host port 3119, local-ports.json, packages.json, slug-map.ts
(born-in-showcase), showcase_build.yml matrix + path filter + metadata,
shell-docs/dashboard registries, and a logo asset. The python strands
integration is untouched.
2026-06-19 17:38:02 +02:00
Jordan Ritter fc2f6263f9 fix: pin showcase/shell @copilotkit deps to ^1.60.2 for a coherent reproducible v2 set 2026-06-18 16:38:17 -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 9340724370 fix(showcase): re-declare COMMIT_SHA/BRANCH ARG in shell and shell-dojo runner stages
runner-stage ENV NEXT_PUBLIC_COMMIT_SHA/BRANCH expanded empty because Docker ARGs are
per-stage; re-declaring them in the runner stage (mirroring shell-docs) restores build-arg
values at runtime. Verified via local buildx.
2026-05-29 11:45:15 -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 b2a8b415f0 fix(showcase): sync shell package-lock with vitest+jsdom devDeps 2026-05-29 11:45:08 -07:00
Jordan Ritter 8b02ebbaa1 refactor(showcase): drop NEXT_PUBLIC_BASE_URL freeze from shell next.config
Removes the env:{NEXT_PUBLIC_BASE_URL} entry that re-bakes the
build-time value of NEXT_PUBLIC_BASE_URL into every chunk (defeats
runtime injection). NEXT_PUBLIC_LOCAL_BACKENDS stays — it is computed
from shared/local-ports.json (a JSON file on disk, not an env var)
and only used in local-dev.

Refs plan-B §B10.3.
2026-05-29 11:45:08 -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
Jordan Ritter a30be17798 fix(showcase): pin @copilotkit deps to latest instead of stale next tag
The "next" dist-tag was a workaround for Docker builds that can't resolve
workspace:* — but "next" has gone stale (1.55.2-next.1) while "latest" is
at 1.56.5. Renovate doesn't cover showcase/, so these never auto-bumped.
Switch all 19 showcase package.json files to "latest".
2026-05-22 12:06:17 -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
Jordan Ritter 6bc0db6a25 fix: harden showcase packages — dep pins + Docker image pins
Dependency version floors:
- next: ^15.0.0 → ^15.5.15 across all 19 showcase packages (CVE-2025-29927)
- express: ^4.21.0 → ^4.21.2 in claude-sdk-typescript (open redirect fix)
- hono: ^4.0.0 → ^4.6.0 in shell (path traversal fix)

Docker base image pins:
- node:20-slim → node:20.19-slim (18 Dockerfiles)
- python:3.12-slim → python:3.12.11-slim (12 Dockerfiles)
- aimock:latest → aimock:1.13.0 (1 Dockerfile)

Part of CPK-7320
2026-04-28 10:33:06 -07:00
Jordan Ritter d4736a911a fix(showcase): update CI workflows, Dockerfiles, and configs
for integrations/ rename

Update GitHub Actions workflows to reference
showcase/integrations/ instead of showcase/packages/.
Fix Dockerfiles to dereference symlinks during COPY.
Remove obsolete showcase_template-drift workflow.
Update docker-compose, shell Dockerfiles, and registry paths.
2026-04-28 07:51:06 -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
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 72381f81bc fix(showcase): ensure all build/dev/test/Docker paths generate data
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)
2026-04-23 21:13:21 -07: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