Commit Graph

621 Commits

Author SHA1 Message Date
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
github-actions[bot] e713ad2a07 style: auto-fix formatting 2026-04-22 11:20:02 +00:00
Alem Tuzlak 06d24fd8ba Merge remote-tracking branch 'origin/main' into fix/scrub-open-gen-ui
The scrub and #4084 touched the same surface: #4084 re-added an `open:`
generative_ui profile listing `open-gen-ui`/`open-gen-ui-advanced`, and
re-added both features to `constrained-explicit.allowed`. Extending the
branch's scrub to both re-additions keeps the semantic consistent with
the schema (which already dropped `open` from the approaches enum).

- `showcase/shared/constraints.yaml`: drop `open-gen-ui` +
  `open-gen-ui-advanced` from `constrained-explicit.allowed`; drop main's
  re-added `open:` profile entirely.
- `showcase/packages/langgraph-python/manifest.yaml`: drop the now-orphan
  `open-gen-ui` + `open-gen-ui-advanced` feature and demo entries
  (validator confirmed they had no allowed approach left).
- Regenerated `showcase/shell/src/data/registry.json` + sibling
  `shell-docs`/`shell-dojo` registries and `constraints.json` via
  `pnpm --dir showcase/scripts generate-registry`. All 17 integrations
  validate.

`feature-registry.json` intentionally still defines both features — the
original scrub commits (2b996c54d, 27f886e59) left it untouched, so the
demo source files on disk also stay. Follow-up deletion if desired is
out of scope for this merge.
2026-04-22 13:17:34 +02:00
Alem Tuzlak 7c00903c6a Merge remote-tracking branch 'origin/main' into jpr5/ci-workflow-optimization
# Conflicts:
#	.github/workflows/showcase_capture-previews.yml
2026-04-22 13:03:04 +02:00
Jordan Ritter d708419911 fix(showcase/langgraph-typescript): bind liveness probe before heavy module imports
PR #4140 placed the liveness probe inside server.mjs under the belief it
would bind "synchronously before any await." That is not how ES modules
work — all top-level `import` statements resolve before any module-body
code runs. `@langchain/langgraph-api/server` takes ~4m30s to cold-import
on Railway (graph eval + tsx transpile), but the watchdog's 180s grace +
3x30s strikes = 270s kills the container ~4s before the probe would have
bound. Kill-loop forever.

Split into:
- `src/agent/liveness.mjs` (new entry): binds :8124/ok immediately using
  only `node:http`, then dynamic-imports server.mjs so the heavy langgraph
  bootstrap runs AFTER :8124 is already serving 200.
- `src/agent/server.mjs`: removed the now-dead sibling-probe code; comment
  block explains why.
- `src/agent/package.json`: `start` script now runs `node --import tsx
  liveness.mjs` instead of `server.mjs`.
- `entrypoint.sh`: comments updated to describe the new ordering.

Local smoke (docker build + run on linux/amd64): /ok returns 200 within
1.4s of container launch vs the previous ~4m34s.
2026-04-21 22:19:12 -07:00
Jordan Ritter ba578c5a29 feat(showcase): multi-stage Docker refactor across template, 17 starters, 17 packages (#4147)
## Summary
- Rewrite starter Dockerfile templates (`typescript`, `python`, `java`,
`dotnet`) as true multi-stage: builder has dev tools, runner is minimal.
No `pip`/`npm`/`pnpm`/`tsx`/`*-cli dev` in runtime stages.
- Encode prod-mode behaviors for `claude-sdk-typescript`, `mastra`,
`langgraph-typescript` directly in the TS template + generator
conditionals (folds in the pattern from #4132 for langgraph-ts; adds
parallel migration for claude-sdk-ts + mastra).
- Regenerate all 17 starter Dockerfiles.
- Rewrite all 17 package Dockerfiles to match the template shape
(multi-stage, venv builder for Python, 3-stage Python runtime, `USER
app`, etc.).
- Cold-start instrumentation on `claude-sdk-typescript` package
(absorbed from closed PR #4133).
- Pin `platforms: linux/amd64` in the showcase deploy workflow
(`docker/build-push-action` step) to match what Railway + GHCR require.
- Template `README.md` documenting multi-stage conventions, size target,
platform mandate, and the `dockerfile_hygiene` probe.
- `generate-starters.ts` strips the `langgraph-typescript` starter's
dead `server.mjs` + its `start` script (both reference deps only needed
in the package's prod-mode path).

## Why
Railway cold starts exceed the 180s watchdog grace when the runtime
stage boots via `langgraph-cli dev` / `npx mastra dev` / `npx tsx` — the
dev-mode work (TS compile, Rollup bundle, native libsql init) blocks the
health probe. #4132 proved the fix is to move this to image build time
for langgraph-ts. This PR generalizes that shape to all TS starters that
need it and reshapes every Dockerfile in the tree so runners no longer
carry dev toolchains.

Secondary outcomes:
- Smaller runtime images (pip/npm toolchain moved to builder only).
- Consistent `--platform linux/amd64` pinning end-to-end.
- No `pnpm install --frozen-lockfile` in the TS starter template
(starters are no-lockfile by design).
- `validate-pins` ratchet re-baselined to match the regenerated spec
strings.

## Test plan
- [ ] `docker build --platform linux/amd64` green for every starter (17)
and package (17) locally
- [ ] `pnpm -C showcase/scripts` vitest: 1085/1085 pass
- [ ] `tsc --noEmit -p showcase/scripts/tsconfig.json` clean
- [ ] `oxfmt --check` + `oxlint` clean on touched TS files
- [ ] validate-pins: count 110, hash matches updated baseline
- [ ] CI Showcase Validate green on PR HEAD
- [ ] Post-merge: showcase deploy for mastra + claude-sdk-typescript
goes green (currently flapping)
2026-04-21 20:14:57 -07:00
Jordan Ritter 8a39783e58 fix(showcase/langgraph-typescript): restore watchdog health probe after prod-mode migration (#4140)
## Summary

- Root cause: #4132 migrated langgraph-typescript from `langgraph-cli
dev` (which exposed `/ok` immediately) to `@langchain/langgraph-api`
`startServer`. That server DOES register `/ok` via its meta routes, but
only binds the port AFTER `registerFromEnv` imports the graph and spawns
the N workers. On Railway that window has been exceeding the watchdog's
180s startup grace + 90s strike budget, producing an infinite restart
loop (deploy `ddc88ef9` is flapping ~every 4m30s).
- Fix: move liveness off the heavy Hono path entirely. `server.mjs` now
starts a bare `node:http` server on port 8124 (configurable via
`HEALTH_PORT`) synchronously before any `await`, answering `GET /ok`
with `{"status":"ok"}`. `entrypoint.sh` watchdog now probes
`127.0.0.1:8124/ok` instead of `:8123/ok`.

## Why

The service has been 502-ing all day. Railway deploy `ddc88ef9` never
serves a single `/api/health` 200 despite `[server] LangGraph API
listening on 0.0.0.0:8123` landing in the logs — the `listening`
callback fires after the watchdog has already killed PID 4 and triggered
a restart.

Liveness on a sibling port is independent of whether :8123 has finished
its graph import, so the probe reflects what the watchdog actually cares
about: is the Node process alive and its event loop responsive. A true
hang (event loop pinned) still fails the probe and triggers container
restart, so hang-detection is preserved.

## Test plan

- [x] Local Docker build green (`--platform linux/amd64`, depot)
- [x] Local container `curl http://127.0.0.1:8124/ok` returns `HTTP=200
{"status":"ok"}` within 20s of boot
- [x] `[server] Liveness probe listening on 0.0.0.0:8124` emitted before
`[server] LangGraph API listening on 0.0.0.0:8123`
- [ ] Railway redeploy recovers `/api/health` + `/api/smoke`
2026-04-21 20:10:40 -07:00
Jordan Ritter c71641db2e chore(showcase/scripts): revert validate-pins baseline hash to CI-observed value 2026-04-21 20:10:21 -07:00
github-actions[bot] 24d0ed442c style: auto-fix formatting 2026-04-22 02:49:13 +00:00
Jordan Ritter 40adafd199 fix(showcase/scripts/generate-starters): strip langgraph-ts starter start script referencing deleted server.mjs 2026-04-21 19:38:29 -07:00
Jordan Ritter 7971aafe53 docs(showcase/template): correct Node and Temurin version references in README
Template actually pins node:22-slim for both builder and runner stages,
and eclipse-temurin:21-jre (not -jre-alpine) for spring-ai runner. README
called out node:24 + temurin:21-jre-alpine. Align docs with reality.
Node 24 bump is a separate decision not made in this body of work.
2026-04-21 19:05:50 -07:00
Jordan Ritter 98a6167de2 fix(showcase/packages): remove image-scope NODE_ENV=production from mastra/spring-ai, scope to next-start in langgraph-python entrypoint
Completes the NODE_ENV scope cleanup started in the prior Python
packages commit. Image-scope ENV NODE_ENV=production leaks into every
child process (agent subprocesses, healthchecks, shell scripts) —
several frameworks change behavior under NODE_ENV and should NOT see
'production' when running as an agent backend.

- mastra: Dockerfile drops image ENV; entrypoint.sh now invokes
  'env NODE_ENV=production npx next start' (was relying on image ENV).
- spring-ai: Dockerfile drops image ENV; entrypoint.sh now scopes
  NODE_ENV=production to the Next.js child only (Java agent never
  interpreted NODE_ENV but the scoping matches every other package).
- langgraph-python entrypoint: 'npx next start' now inherits
  NODE_ENV=production via 'env' wrapper (Dockerfile already removed
  image ENV in prior commit).
2026-04-21 19:05:45 -07:00
Jordan Ritter b9bcf2e6b6 fix(showcase/packages-python): drop to USER app across 11 Python packages, add missing /app/public COPY to langgraph-python
All 11 Python runners previously executed as root. Bring them into parity
with langroid (the one Python package that already had the pattern):

- Create uid/gid 1001 'app' user/group before any COPY
- Add --chown=app:app to runner-stage COPY directives
- USER app before EXPOSE/CMD
- langgraph-python: add the missing COPY --from=frontend /app/public line
  (every other Python package has it) plus an empty public/.gitkeep so
  the copy resolves

Packages touched: ag2, agno, claude-sdk-python, crewai-crews, google-adk,
langgraph-fastapi, langgraph-python, llamaindex, ms-agent-python,
pydantic-ai, strands.
2026-04-21 19:05:23 -07:00
Jordan Ritter 400fe8a1ae fix(showcase/starters): regenerate after generator fixes (watchdog cleanup + tsc rootDir + strip langgraph-ts server.mjs)
Mechanical regen; no hand edits. Changes:
- All 17 entrypoint.sh: add '|| true' to cleanup kill (trap + final)
- claude-sdk-typescript Dockerfile: tsc now passes --rootDir .
- langgraph-typescript/agent: remove server.mjs + prune its transitive
  deps from package-lock.json
2026-04-21 19:01:30 -07:00
Jordan Ritter c6437b3443 fix(showcase/scripts/generate-starters): emit || true on watchdog cleanup kill, preserve --rootDir ., strip dead langgraph-ts server.mjs, guard AGENT_DIR expansion
- entrypoint.template.sh: cleanup trap + final kill now tolerate no-match
  (|| true) so trap doesn't abort shell when one of the three PIDs has
  already exited. Package-level entrypoint.sh already had this shape.
- generate-starters.ts: claude-sdk-typescript tsc now uses --rootDir .
  so emitted artifact is /app/dist/agent/index.js (matches entrypoint
  expectation + runner-stage COPY). tsc was inferring agent/ as rootDir
  and stripping the prefix.
- generate-starters.ts: drop server.mjs from langgraph-typescript starter
  output. The starter uses 'npx @langchain/langgraph-cli dev' and never
  invokes server.mjs; the file imports @langchain/langgraph-api/server
  which is not in the starter's extraDependencies (resolution relied on
  transitive hoist via @langchain/langgraph-cli). The file stays in the
  PACKAGE where prod mode does use it.
- generate-starters.ts: assert agentDir non-empty / non-absolute before
  Dockerfile substitution so the 'rm -f {{AGENT_DIR}}/package*.json' line
  can never degrade into 'rm -f /package*.json' across /app.
2026-04-21 19:01:10 -07:00
Jordan Ritter 5ab3a81468 chore(showcase/starter-langgraph-typescript): sync package-lock.json after prod-mode deps 2026-04-21 18:44:03 -07:00
Jordan Ritter bff45416e7 docs(showcase): document multi-stage Dockerfile conventions
Add showcase/starters/template/README.md covering the multi-stage build
convention (builder + runtime split), the >=40% image-size reduction
target, the linux/amd64 platform requirement for local builds, and the
dockerfile_hygiene probe rules (>=2 FROM stages, no dev-dep installs in
the runtime stage).

Expand the header comment on showcase/scripts/generate-starters.ts to
document the >=40% size target, the getAgentBuildSteps/getAgentBuildCopy
handoff in more detail, and the linux/amd64 platform pin in the deploy
workflow.
2026-04-21 18:41:48 -07:00
Jordan Ritter 7febc5cf5d chore(showcase/package-claude-sdk-typescript): add cold-start instrumentation
Package-level service claims to listen on :8000 but Railway health probes
fail. Narrow the cold-start window by timestamping each phase from
entrypoint exec to first /health-serving moment:

- entrypoint.sh: print `[entrypoint] pre-node <ISO>` immediately before
  `node /app/agent_server.js`, pairing with the agent_server.ts prints
  below to chain timestamps across the exec boundary.
- agent_server.ts: print `[agent_server] module loaded <ISO>` before any
  side-effect imports (so import-time hangs surface distinctly from
  init-time hangs), `[agent_server] pre-Anthropic <ISO>` right before
  `new Anthropic(...)`, and include an ISO timestamp in the existing
  app.listen() callback so we can read the delta directly.

No behavior change — only logs added. Next deploy cycle should reveal
which phase consumes the budget and whether the failure mode is
listen-but-unreachable vs. listen-never-reached.
2026-04-21 18:39:48 -07:00
Jordan Ritter 8da71c4a0c merge: Task 3 Lane D — llamaindex/ms-agent-py/pydantic-ai/strands Dockerfiles 2026-04-21 18:38:44 -07:00
Jordan Ritter 46e0571b4c merge: Task 3 Lane C — google-adk/langgraph-fastapi/langgraph-python/langroid Dockerfiles 2026-04-21 18:38:43 -07:00
Jordan Ritter 23f4759ff3 merge: Task 3 Lane B — ag2/agno/claude-sdk-py/crewai-crews Dockerfiles 2026-04-21 18:38:43 -07:00
Jordan Ritter 6f5578d647 fix(showcase/package-ms-agent-dotnet): multi-stage Dockerfile with unprivileged user and scoped NODE_ENV 2026-04-21 18:37:59 -07:00
Jordan Ritter 95db0b8cfc fix(showcase/package-spring-ai): multi-stage Dockerfile with unprivileged user and Temurin 21 2026-04-21 18:34:46 -07:00
Jordan Ritter 67882698ea fix(showcase/package-mastra): multi-stage Dockerfile with unprivileged user 2026-04-21 18:30:52 -07:00
Jordan Ritter 55cf628341 fix(showcase/package-strands): multi-stage Dockerfile with venv builder
Split the runner image into three stages:
- frontend (node:22-slim) builds Next.js artifacts
- agent-builder (python:3.12.13) builds /opt/venv from requirements.txt
- runner (python:3.12.13-slim) installs Node.js + copies artifacts, with no
  pip and no build-essential

Mirrors the pattern already used by showcase/starters/strands/Dockerfile.
2026-04-21 18:28:57 -07:00
Jordan Ritter accfb49036 fix(showcase/package-pydantic-ai): multi-stage Dockerfile with venv builder
Split the runner image into three stages:
- frontend (node:22-slim) builds Next.js artifacts
- agent-builder (python:3.12.13) builds /opt/venv from requirements.txt
- runner (python:3.12.13-slim) installs Node.js + copies artifacts, with no
  pip and no build-essential

Mirrors the pattern already used by showcase/starters/pydantic-ai/Dockerfile.
2026-04-21 18:28:53 -07:00
Jordan Ritter a2736034c0 fix(showcase/package-ms-agent-python): multi-stage Dockerfile with venv builder
Split the runner image into three stages:
- frontend (node:22-slim) builds Next.js artifacts
- agent-builder (python:3.12.13) builds /opt/venv from requirements.txt
- runner (python:3.12.13-slim) installs Node.js + copies artifacts, with no
  pip and no build-essential

Mirrors the pattern already used by showcase/starters/ms-agent-python/Dockerfile.
2026-04-21 18:28:50 -07:00
Jordan Ritter 3fa53a5d35 fix(showcase/package-llamaindex): multi-stage Dockerfile with venv builder
Split the runner image into three stages:
- frontend (node:22-slim) builds Next.js artifacts
- agent-builder (python:3.12.13) builds /opt/venv from requirements.txt
- runner (python:3.12.13-slim) installs Node.js + copies artifacts, with no
  pip and no build-essential

Mirrors the pattern already used by showcase/starters/llamaindex/Dockerfile.
2026-04-21 18:28:47 -07:00
Jordan Ritter 64421cde1f fix(showcase/package-langgraph-typescript): multi-stage Dockerfile with unprivileged user and scoped NODE_ENV 2026-04-21 18:26:36 -07:00
Jordan Ritter e0db520506 fix(showcase/package-crewai-crews): multi-stage Dockerfile with venv builder
Split Python install into a dedicated agent-builder stage (python:3.12.13)
that produces /opt/venv, which the slim runner COPYs in. The runner no
longer runs pip install, so no compiler toolchain or build-essential bloats
the final image.

Preserves behavior: entrypoint.sh, port 10000, src/aimock_toggle.py,
shared_python/ -> /app/shared/python/ + PYTHONPATH. No image-level
NODE_ENV (entrypoint.sh scopes it to Next.js only).
2026-04-21 18:26:24 -07:00
Jordan Ritter e97096c397 fix(showcase/package-claude-sdk-python): multi-stage Dockerfile with venv builder
Split Python install into a dedicated agent-builder stage (python:3.12.13)
that produces /opt/venv, which the slim runner COPYs in. The runner no
longer runs pip install, so no compiler toolchain or build-essential bloats
the final image.

Preserves behavior: entrypoint.sh, port 10000, ENV NODE_ENV=production,
shared_python/ -> /app/shared/python/ + PYTHONPATH.
2026-04-21 18:24:15 -07:00
Jordan Ritter a94bb8bfc0 fix(showcase/package-claude-sdk-typescript): multi-stage Dockerfile with unprivileged user and scoped NODE_ENV 2026-04-21 18:22:35 -07:00
Jordan Ritter e4c567bf15 fix(showcase/package-agno): multi-stage Dockerfile with venv builder
Split Python install into a dedicated agent-builder stage (python:3.12.13)
that produces /opt/venv, which the slim runner COPYs in. The runner no
longer runs pip install, so no compiler toolchain or build-essential bloats
the final image.

Preserves behavior: entrypoint.sh, port 10000, ENV NODE_ENV=production,
shared_python/ -> /app/shared/python/ + PYTHONPATH.
2026-04-21 18:22:11 -07:00
Jordan Ritter 35dedcb961 fix(showcase/package-langroid): multi-stage Dockerfile with venv builder 2026-04-21 18:20:20 -07:00
Jordan Ritter bc264aee95 fix(showcase/package-langgraph-python): multi-stage Dockerfile with venv builder 2026-04-21 18:20:17 -07:00
Jordan Ritter ebeb6d7069 fix(showcase/package-langgraph-fastapi): multi-stage Dockerfile with venv builder 2026-04-21 18:20:11 -07:00
Jordan Ritter f527a4ae38 fix(showcase/package-google-adk): multi-stage Dockerfile with venv builder 2026-04-21 18:20:09 -07:00
Jordan Ritter 28cdb4d19b fix(showcase/package-ag2): multi-stage Dockerfile with venv builder
Split Python install into a dedicated agent-builder stage (python:3.12.13)
that produces /opt/venv, which the slim runner COPYs in. The runner no
longer runs pip install, so no compiler toolchain or build-essential bloats
the final image.

Preserves behavior: entrypoint.sh, port 10000, ENV NODE_ENV=production,
shared_python/ -> /app/shared/python/ + PYTHONPATH.
2026-04-21 18:20:00 -07:00
Jordan Ritter 6cfcde61c1 chore(showcase/scripts): re-ratchet validate-pins fail-baseline post-regen 2026-04-21 18:14:04 -07:00
Jordan Ritter dc49520513 feat(showcase/starters): regenerate 17 starter Dockerfiles for multi-stage builds 2026-04-21 18:14:00 -07:00
github-actions[bot] b241d75652 style: auto-fix formatting 2026-04-22 00:37:17 +00:00
Sam Julien 8c4d0c36f9 fix(shell-docs): remove stale 'integrations' from RESERVED_ROUTE_SLUGS
There is no app/integrations/ route, so the reservation was causing
/integrations/... URLs to 404. Without it, these paths fall through to
UnscopedDocsPage via the non-integration fallthrough in [framework].
2026-04-21 17:35:01 -07:00
Sam Julien b37a3043e6 fix(shell-docs): remove hardcoded langgraph-python from main docs MDX
Strip snippet_framework: langgraph-python from frontmatter and
integration="langgraph-python" from all InlineDemo tags in the
main docs tree (27 files). On framework-scoped pages frameworkOverride
drives Snippet and InlineDemo; on unscoped pages FrameworkGuardedContent
already hides the body until a framework is selected, so no default
is needed.
2026-04-21 17:35:01 -07:00
github-actions[bot] a043aa5ba0 style: auto-fix formatting 2026-04-21 17:35:01 -07:00
Sam Julien a265cc7d48 fix(shell-docs): skip root-flagged dirs from parent nav tree
buildNavTree now checks meta.root before including a subdirectory,
so unselected/ (and any other root:true directory) is excluded from
the main nav tree. This eliminates the flicker where SidebarLink
generated /langgraph-python/unselected/coding-agents and the
[framework] route had to server-redirect to the correct scoped URL.
2026-04-21 17:35:01 -07:00
Sam Julien 64aa05d1b8 fix(showcase/shell-docs): rewrite MDX body links to framework-scoped URLs
On framework-scoped pages, MDX links like /quickstart rendered as plain
<a href="/quickstart"> causing RouterPivot redirect flicker. Override the
MDX `a` component when frameworkOverride is set to prepend the framework
prefix to root-relative internal links.
2026-04-21 17:35:01 -07:00
Sam Julien 87fb9e8260 fix(showcase/shell-docs): fix /<slug> 404 via UnscopedDocsPage fallthrough
Next.js routes /quickstart to [framework]/[[...slug]] (dynamic segment
beats optional catch-all), where "quickstart" is not a registered
integration, causing notFound(). Fix by:

- Extracting the unscoped doc rendering logic into UnscopedDocsPage
- Falling through to it in [framework] when the slug is not a framework
- Simplifying [[...slug]]/page.tsx to handle only the root overview
2026-04-21 17:35:01 -07:00
Sam Julien bb0b14702c fix(showcase/shell-docs): eliminate URL flicker on unscoped navigation
SidebarLink now uses storedFramework as fallback so links on the
overview page go directly to /<framework>/<slug> without a RouterPivot
redirect. OverviewNavItem and section cards now use SidebarLink for the
same reason. FrameworkSelector "Clear selection" was navigating to
/docs/<slug> (broken); fixed to /<slug>. hrefFor now preserves the
current slug when switching frameworks from an unscoped page.
2026-04-21 17:35:01 -07:00
github-actions[bot] 5e7e1be672 style: auto-fix formatting 2026-04-21 17:35:01 -07:00
Sam Julien 3218c54cc1 fix(showcase/shell-docs): remove remaining /docs/ hardcoded hrefs
SidebarLink fallback, framework-scoped backLink, "framework-agnostic
version" banner link, FrameworkLandingPage sidebar, and brand-nav
all still pointed at /docs/* which routes to 404 via the [framework]
catch-all. Switch all to / or /<slug>.
2026-04-21 17:35:01 -07:00