9433 Commits

Author SHA1 Message Date
Jordan Ritter 861e56b90e fix(showcase): LGT remaining delta — 16 test fixes + component extraction + cleanup (#4906)
## Summary
Closes the LGT-vs-LGP delta from PR #4879. Fixes 16 of 17 LGT-only test
failures, extracts inlined components to match LGP's factored pattern,
removes orphan demos, and ports infrastructure.

## Changes

### Test fixes (16 of 17 LGT-only failures)
- **headless-complete**: `normalizeResponse()` for
additional_kwargs.tool_calls + missing `get_revenue_chart` tool
- **readonly-state**: Removed aimock `systemMessage: "Atai"` gate
(gpt-5.4 sends role:developer)
- **reasoning-custom**: Created missing demo page + wired route to
existing reasoning graph
- **reasoning-default**: Renamed from `reasoning-default-render` + added
`suggestions.ts`
- **declarative-gen-ui**: Fixed A2UI tool name (`render_a2ui` →
`_design_a2ui_surface`) + state-aware ToolNode wrapper
- **beautiful-chat**: A2UI v0.9 operation format + ExampleCanvas agentId
+ manage_todos Command + copilotkitEmitState

### Component extraction (inlining → LGP pattern)
- **hitl**: 7 inlined components extracted to separate files
(step-selector, steps-feedback, suggestions, 4 shadcn components)
- **declarative-hashbrown**: All files aligned to LGP
- **declarative-json-render**: All files aligned to LGP
- **shared-state-read**: Extracted recipe-card.tsx + types.ts from
460-line page.tsx
- **reasoning-default**: Extracted suggestions.ts
- **beautiful-chat**: Extracted home-page.tsx

### Cleanup
- Removed `agentic-chat-reasoning` (deprecated, untested, covered by
reasoning-custom)
- Removed `shared-state-write` (unimplemented stub, superseded by
shared-state-read-write)
- Ported `layout.tsx` from LGP (per-demo title metadata)

## Variance after this PR
- Frontend files: 240 identical (96%), 10 justified diffs, 0 functional
gaps
- Tests: 37 identical (100%)
- API routes: 15 identical (100%)

## 1 remaining LGT-only failure
- reasoning-default "Show reasoning pill" — fixture doesn't produce
reasoning tokens for LGT pipeline

## Test plan
- [ ] Full LGP suite on production-parity local cluster
- [ ] Full LGT suite on production-parity local cluster
- [ ] CI checks
v1.57.2
2026-05-18 21:02:44 -07:00
github-actions[bot] c03c65df15 style: auto-fix formatting 2026-05-19 03:56:11 +00:00
Jordan Ritter 3682b24f3b fix(showcase/langgraph-typescript): fix stale manifest entries for renamed/missing demos 2026-05-18 20:54:36 -07:00
Jordan Ritter b475431570 fix(showcase/langgraph-typescript): add missing UI components from LGP 2026-05-18 20:49:52 -07:00
Tyler Slaton da6cfaf0b1 fix(ci): exclude node_modules from release artifact to avoid OOM (#4909)
## Summary

The release/publish workflow's build job uploads the entire workspace as
an artifact for the publish job to download. With `node_modules`
included, this monorepo produces **~6.4M files**, which OOMs
`upload-artifact`'s Node process at its 4 GB heap limit during file
enumeration:

```
With the provided path, there will be 6392019 files uploaded
...
FATAL ERROR: Ineffective mark-compacts near heap limit
Allocation failed - JavaScript heap out of memory
```

This was uncovered when the `workflow_dispatch` escape hatch added in
#4808 was first exercised — the upload step hung for 12+ minutes and
then crashed.

## Fix

1. **`Upload workspace` exclusions** — exclude `**/node_modules/**`,
`**/.next/**`, `**/.turbo/**`, `**/.nx/**`. Drops the file count by
orders of magnitude (almost all of those 6.4M files are pnpm's hoisted +
nested `node_modules`).
2. **`Install Dependencies` in the publish job** — runs `pnpm install
--frozen-lockfile` after `Download workspace`, so the publish step
operates against exactly the same resolved tree the build job used
(`pnpm-lock.yaml` is carried in the artifact).

The published `packages/*/dist/` outputs from the build job are
unaffected by the exclusions, so npm publish still has everything it
needs.

## Test plan

- [ ] Merge to main
- [ ] Dispatch `release / publish` against `monorepo` (or wait for the
next merged release PR)
- [ ] Confirm `Upload workspace` and `Download workspace` both finish in
seconds (not minutes), and `Install Dependencies` runs in the publish
job before `Publish to npm`
- [ ] Confirm the published tarballs on npm are byte-identical to what
the previous flow would have produced (same lockfile → same install →
same build outputs already in the artifact)


---
_Generated by [Claude
Code](https://claude.ai/code/session_01VnqgZdq8QaS15yknCKKcff)_
2026-05-18 20:49:40 -07:00
Jordan Ritter 74691ff119 fix(showcase/langgraph-typescript): add missing yaml dependency 2026-05-18 20:45:25 -07:00
Claude bbff324aaf fix(ci): exclude node_modules from release artifact to avoid OOM
The release/publish workflow's build job uploads the entire workspace
as an artifact for the publish job to download. With node_modules and
build caches included, this monorepo produces ~6.4M files, which OOMs
upload-artifact's Node process at its 4GB heap limit during
enumeration:

  FATAL ERROR: Ineffective mark-compacts near heap limit
  Allocation failed - JavaScript heap out of memory

Excluding node_modules, .next, .turbo, and .nx cuts the file count by
orders of magnitude. The publish job runs `pnpm install --frozen-lockfile`
after download to restore node_modules deterministically from
pnpm-lock.yaml (carried in the artifact), so the publish step still
runs against exactly the resolved dependency tree the build job used.

Fixes the upload step that hung for 12+ minutes and then OOM'd when
the workflow_dispatch trigger added in #4808 was first exercised.
2026-05-19 03:44:30 +00:00
Jordan Ritter 68482898a9 fix(showcase): sync agentic-chat spec — add race guard to LGT
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-18 20:39:53 -07:00
Jordan Ritter 872760e205 fix(showcase/aimock): remove stale recorded hitl fixtures that shadow feature-parity
Two recorded fixtures from a d5 run (2026-05-15) had wrong data
(attendee: "User" instead of "Sales team") and random toolCallIds
with no matching confirmation fixtures. They intercepted hitl-in-chat
requests before the correct feature-parity.json fixtures could match.
2026-05-18 20:39:52 -07:00
Jordan Ritter e69e67ea12 Fix 5 shared test failures in auth, chat-customization-css, and chat-slots
Two root causes:

1. Tests used messages ("Hello", "Hi", "hello", "Say something short")
   that don't match any aimock fixture. With --proxy-only mode, unmatched
   requests fall through to real OpenAI which rejects the mock API key
   (sk-mock-local-dev) with 502/401. Replaced all test messages with
   exact d5-all.json fixture entries: "Say hello in one short sentence",
   "Tell me a one-line joke", "Give me a fun fact".

2. The "second assistant turn" test in chat-slots sent its second message
   immediately after the first assistant bubble appeared. The assistant
   message becomes visible on the first streaming chunk, but the chat
   input stays disabled until the full stream ends (aimock streams at
   60ms/8-char-chunk). Added a text-stabilization poll between turns to
   wait for streaming to finish before sending the next message.

All tests copied identically to both LGP and LGT. Verified 16/16 pass
on both ports (3100 and 3101) across multiple runs.
2026-05-18 20:39:11 -07:00
Jordan Ritter 54717e61bf fix(showcase/aimock): fix shared-state-read + hitl multi-pill fixture gaps
Two aimock fixture issues caused e2e test failures on both LGP and LGT:

1. shared-state-read: no fixture matched "What recipe am I making?" —
   added a new fixture in feature-parity.json keyed on that substring.

2. hitl-in-app multi-pill test: the second pill's first-turn request
   failed because hasToolResult: false on the 1st-turn fixtures rejected
   conversations that already contained tool results from earlier pills.
   Removed hasToolResult: false from refund/downgrade/escalate 1st-turn
   fixtures — the more-specific post-tool-result fixtures (with
   toolCallId + hasToolResult: true) still win on the 2nd turn.
2026-05-18 20:39:11 -07:00
Jordan Ritter e7ebc786c3 fix(showcase): simplify agent-config route + fix race condition in test
Remove custom AgentConfigLangGraphAgent wrapper that broke SSE stream
lifecycle (data-copilot-running stuck at true). Use plain LangGraphAgent
matching LGP pattern — useAgentContext via ConfigContextRelay handles
config forwarding without the wrapper.

Test fix: filter out agent/stop POST bodies from captured requests and
wait for data-copilot-running=false between sends to prevent race.
2026-05-18 20:39:10 -07:00
Jordan Ritter c8187e3788 fix(showcase): gen-ui-agent 'message list container' test needs a message first
CopilotChat v2 renders a welcome screen when messages are empty,
which means the messageView.children callback (where the
copilot-message-list testid lives) is not invoked until the first
message is sent. Send "Hello" before asserting the container exists.

Fixes the test on both LGP (port 3100) and LGT (port 3101).
2026-05-18 20:39:10 -07:00
Jordan Ritter 31c536020f fix(showcase): add aimock fixtures for agentic-chat e2e + fix
multi-turn race on LGT

Two shared agentic-chat tests failed on both LGP and LGT because
the test messages had no matching aimock fixtures, and the
multi-turn test had a race condition on LGT where the second
Enter keypress was swallowed during a component re-render.

- Add 3 fixtures to feature-parity.json for the agentic-chat e2e
  test messages (hello, Alice turn 1, Alice turn 2)
- Wait for suggestion pills to reappear before sending the
  follow-up message in the multi-turn test
2026-05-18 20:39:10 -07:00
Jordan Ritter b90dc89833 fix(showcase/langgraph-typescript): extract components matching LGP for reasoning-default + shared-state-read + beautiful-chat
reasoning-default: add suggestions.ts, use extracted hook in page.tsx
shared-state-read: extract types.ts, recipe-card.tsx from 460-line
  inlined page.tsx; add README.md
beautiful-chat: extract HomePage to home-page.tsx matching LGP pattern
2026-05-18 20:39:10 -07:00
Jordan Ritter 9f9d4fd60b fix(showcase/langgraph-typescript): extract hitl components matching LGP pattern 2026-05-18 20:38:33 -07:00
Jordan Ritter 9800affe0e fix(showcase/langgraph-typescript): rename reasoning-default-render to reasoning-default matching LGP 2026-05-18 20:38:33 -07:00
Jordan Ritter e74a9c6ed0 chore(showcase/aimock): remove stale recorded fixtures from prior session
Delete 9 recorded fixture files from showcase/aimock/d5-recorded/recorded/
that were captured during a previous real-API recording session. These
fixtures are not needed -- the existing feature-parity.json fixtures
already cover all 4 test cases (Task Manager, Search Flights, PieChart,
BarChart) for both LGP and LGT.
2026-05-18 20:38:33 -07:00
Jordan Ritter 96bd3404e4 fix(showcase/langgraph-typescript): fix beautiful-chat A2UI format + agentId + declarative-gen-ui tool naming 2026-05-18 20:38:33 -07:00
Jordan Ritter a8388dc851 fix(showcase/langgraph-typescript): fix readonly-state fixtures + add reasoning-custom demo + headless-complete agent fixes 2026-05-18 20:38:33 -07:00
Jordan Ritter e4d42f9fc5 fix(showcase/langgraph-typescript): align headless-complete agent to LGP gold standard
Add missing get_revenue_chart tool and normalizeResponse to fix two
LGT-only test failures in headless-complete.spec.ts (weather pill
and revenue chart pill).

Root causes:
- get_revenue_chart tool was missing from the LGT agent, so the
  aimock fixture tool call had no ToolNode handler.
- @langchain/openai 1.4.x streaming places tool_calls in
  additional_kwargs when content is also present. shouldContinue
  only checked the top-level tool_calls array, so weather tool
  calls were silently dropped.

normalizeResponse promotes additional_kwargs.tool_calls to the
top-level tool_calls array so shouldContinue works uniformly.
2026-05-18 20:38:32 -07:00
Jordan Ritter be0c400359 feat(ci): add workflow_dispatch escape hatch to release/publish (#4808)
## Summary

Adds a `workflow_dispatch` trigger to
`.github/workflows/publish-release.yml` so the release/publish workflow
can be manually retriggered against the latest commit on `main`.

This is the escape hatch for the current edge case: a release failed
mid-flight, `main` already has the bumped versions, but nothing was
published and the normal PR-merge trigger can't fire again without a
fresh release PR.

## What this covers

✅ Failures **before** the `Publish to npm` step succeeded:
- Build errors
- Infrastructure blips (runner crash, OIDC token issue, npm registry
hiccup)
- Pre-publish workflow bugs (e.g. the `git config --local` issue fixed
in #4874)

## What this does NOT cover

❌ Failures **after** `Publish to npm` succeeded:
- If npm publish ran but tag push or GitHub Release creation failed,
dispatching this workflow will fail at `Publish to npm` with an `already
published` error.
- The `Check for pre-existing tags` step will also block retries where
the tag was pushed but later steps failed.

For those cases: finish the release by hand using `release-notes.md`
from the merged release PR — manually create the git tag at the publish
commit and create the GitHub Release. Don't dispatch.

Both the in-file YAML comment above `workflow_dispatch:` and the
dispatch form's `scope` input description spell this out so operators
see it before triggering.

## Change

Minimal: 33 insertions, 7 deletions in one workflow file.

- New `workflow_dispatch` trigger with a required `scope` choice input
(`monorepo` | `angular`)
- `if` condition widened to also accept `workflow_dispatch` runs
- Scope-extraction step now uses `inputs.scope` when present, falls back
to the existing PR-branch parsing otherwise
- YAML comment above the trigger documents the coverage limits

The normal PR-merge trigger and the entire downstream publish pipeline
are unchanged.

## Test plan

- [ ] Merge to main
- [ ] Actions → "release / publish" → "Run workflow" → pick scope →
confirm publish proceeds against current main versions
- [ ] Confirm a normal release-PR merge still triggers and behaves
identically
- [ ] Confirm dispatch against a state where npm publish already
succeeded fails fast at "Publish to npm" (does not corrupt anything)
2026-05-18 20:09:53 -07:00
Tyler Slaton f9dfd3d5be fix(shell-docs): stack sidebar under banner when banner is visible (#4908)
## Summary

- The DocsLayout sidebar uses `position: fixed` with hardcoded `top:
76px / 96px` (md / xl) in
[showcase/shell-docs/src/app/globals.css](showcase/shell-docs/src/app/globals.css).
When the rotating banner is visible, body-flow chrome (Banners +
BrandNav) shifts down by the banner's height (~54px), but the fixed
sidebar stays pinned — so the framework picker overlaps the BrandNav
row.
- Wrap both top overrides in `calc(... + var(--fd-banner-height, 0px))`
so the sidebar follows the banner's height (54px shown, 0px dismissed).
`Banners` already writes that variable on `<html>`, and `MobileTopNav`
already uses the same pattern.

## Before / after

Before: with banner showing, the sidebar's "framework" pill sits at
viewport `top: 96px`, while BrandNav occupies 54-142px — the pill
obscures the "CopilotKit DOCS" mark and nav links.
After: sidebar resolves to `top: 150px` (96+54) at xl and `top: 130px`
(76+54) at md, sitting cleanly below BrandNav. Snaps back to 76 / 96px
when the banner is dismissed.

## Test plan

- [x] Banner visible @ 1280px viewport — sidebar `top: 150px`, no
overlap with BrandNav
- [x] Banner visible @ 1024px viewport — sidebar `top: 130px`, no
overlap with BrandNav
- [x] Banner dismissed @ 1024px viewport — sidebar `top: 76px`, flush
under BrandNav
- [x] Visual screenshot review in light theme across both breakpoints

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-05-18 20:08:20 -07:00
Tyler Slaton 2b08523e9e fix(shell-docs): stack sidebar under banner instead of overlapping BrandNav
The DocsLayout sidebar uses `position: fixed` with hardcoded `top: 76px / 96px`
overrides at md/xl. When the rotating banner is visible, body-flow `Banners` +
`BrandNav` shift down (banner ~54px + BrandNav 68/88px), but the fixed sidebar
stays pinned — so the "LangGraph (Python)" framework picker overlaps the
BrandNav row.

Wrap both top overrides in `calc(... + var(--fd-banner-height, 0px))` so the
sidebar slides down by the banner's height when shown and snaps back when
dismissed. `Banners` already writes that variable on `<html>` (54px / 0px),
and `MobileTopNav` uses the same pattern.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 20:03:52 -07:00
Tyler Slaton 7bc0835f81 fix(shell-docs): repair stale imports left behind by Fumadocs migration (#4907)
## Summary

The Fumadocs UI adoption PR (#4898) removed `highlight.js` +
`rehype-highlight` from `showcase/shell-docs/package.json` and swept the
bespoke nav rendering over to Fumadocs's `DocsLayout` + page-tree
bridge, but **four stale call sites survived the sweep** and broke the
Docker build of `showcase-shell-docs` on main ([run
26071347282](https://github.com/CopilotKit/CopilotKit/actions/runs/26071347282/job/76653308716)):

- **`agentcore-command-tabs.tsx`** still imported the now-uninstalled
`highlight.js` to syntax-highlight inline bash (the immediate Webpack
error: `Module not found: Can't resolve 'highlight.js'`). Rebuilt the
body on Fumadocs's `<DynamicCodeBlock>` so the AgentCore command tabs
share Shiki + the native copy-button chrome with every other code block
— matching `Snippet` / `DemoSource`, which already moved off `hljs`.
- **`[[...slug]]/page.tsx`** still defined `nodeKey` +
`OverviewNavItem`, which reach for the removed `SidebarLink` and
`NavNode` references. The functions are unreachable — `DocsOverview`
renders the sidebar via `ShellDocsLayout(tree=pageTree)` — so they were
deleted outright instead of patched.
- **`docs-page-view.tsx`** had the same dead `renderNavItem` helper for
the same reason; deleted.
- **`brand-nav.tsx`** referenced `<ExternalLinkIcon />` without
importing it.

The `highlight.js` Webpack error was the only one surfaced in CI because
Next.js's compile pass aborts before typecheck; the other three would
have surfaced as `Failed to compile` typecheck failures on the next push
regardless. Fixed all four at once so the next `next build` is clean
end-to-end.

## Test plan

- [x] `next build` of `showcase/shell-docs` locally — all 30 static
pages generate, no Webpack or TS errors
- [x] Pre-commit hooks (`oxlint`, `oxfmt`, `nx test
--projects=packages/**`, `check:packages`) green
- [ ] CI green on this PR — the `Showcase: Build & Push` shell-docs leg
should now succeed

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-05-18 19:20:46 -07:00
Tyler Slaton 20a2433984 fix(shell-docs): repair stale imports left behind by Fumadocs migration
The Fumadocs UI adoption PR (#4898) removed highlight.js + rehype-highlight
from package.json and replaced the bespoke nav rendering with Fumadocs's
DocsLayout + page-tree bridge, but four stale call sites survived the
sweep and broke the Docker build of showcase-shell-docs on main:

- agentcore-command-tabs.tsx still imported the now-uninstalled
  highlight.js to syntax-highlight inline bash. Rebuilt the body on
  Fumadocs's DynamicCodeBlock so the AgentCore command tabs share Shiki
  + the native copy-button chrome with every other code block.
- [[...slug]]/page.tsx still defined nodeKey + OverviewNavItem, which
  reach for the removed SidebarLink. The functions are unreachable —
  DocsOverview renders the sidebar via ShellDocsLayout(tree=pageTree) —
  so they were deleted outright instead of patched.
- docs-page-view.tsx had the same dead renderNavItem helper; deleted.
- brand-nav.tsx referenced ExternalLinkIcon without importing it.

Verified with `next build` of showcase/shell-docs locally: all 30 static
pages generate cleanly and no Webpack/TS errors remain.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 19:15:37 -07:00
Tyler Slaton 8e7a3ef5d4 feat(shell-docs): adopt Fumadocs UI for docs chrome (#4898)
## Summary

Adopt Fumadocs UI primitives (`DocsLayout`, `DocsPage`, `DocsBody`,
`CodeBlock`, `SidebarTrigger`) for shell-docs's docs chrome while
keeping the existing `next-mdx-remote` MDX pipeline, `meta.json` IA, and
framework-aware snippet system unchanged.

Net result: cleaner Fumadocs-native sidebar / TOC / code-block treatment
with shell-docs's bespoke branding (BrandNav, framework selector,
Banners) preserved.

## What changed

**Layout & chrome**
- New `ShellDocsLayout` wrapper centralizes the `DocsLayout` config
(sidebar surface, mobile nav slot, container className) used by all 5
routes — home, framework root, framework-scoped MDX via `DocsPageView`,
`/reference`, `/ag-ui`.
- Page-tree bridge (`navTreeToPageTree`) converts shell-docs `NavNode`s
into Fumadocs `PageTree.Root`; untitled groups are flattened so the
sidebar doesn't render orphan chevrons.
- Mobile chrome: `BrandNav` is desktop-only (`hidden md:block`). New
`MobileTopNav` lives in DocsLayout's `nav.component` slot so Fumadocs's
`SidebarTrigger` can open its native mobile sidebar with the same page
tree.
- TOC popover disabled on tablet/mobile (the bar was overlapping
breadcrumbs); right-rail TOC restored on Prebuilt Components
(`chat.mdx`, `sidebar.mdx`, `popup.mdx` drop `hideTOC: true`).

**Brand & nav surface**
- Removed Integrations and Free Developer Access from the top nav.
- Extracted shared `CopilotKitMark` SVG (per-instance gradient IDs via
`useId()`) — BrandNav and MobileTopNav share one definition.
- `/reference` index restored by removing a legacy `/reference →
/reference/v2` SEO redirect that pointed at a path that no longer
exists.

**Code blocks**
- `MdxCodeBlock` now wraps content in Fumadocs's `CodeBlock` (subtle
copy button with `backdrop-blur`, no double-bordered figure). Keeps
shell-docs's dedent-on-JSX-nested-fences logic.

**Sidebar styling**
- Section separators are small-caps shelf labels with letter-spacing;
consecutive separators step down in weight so heading + sub-heading
reads as one group.
- Light-mode BrandNav uses `--bg-elevated` so it contrasts against the
white sidebar + content.
- Framework selector wrapper and sticky surface use `--bg` (sidebar
match) — fixes the visible tint around the picker in dark mode.

**Layout vars**
- `--fd-nav-height` is 56px on mobile / 88px on `md+` so the fixed
`MobileTopNav` and in-flow `BrandNav` each leave the correct content
offset. `#nd-docs-layout` `padding-top: 0` scoped to desktop only.

**Performance**
- `buildNavTree` memoizes per `(dir, prefix)` in prod (dev skips so
meta.json hot-reloads).
- `navTreeToPageTree` uses a `WeakMap<NavNode[]>` so its `PageTree.Root`
cache auto-invalidates when the upstream tree reference changes.

## Test plan

- [ ] `/concepts/architecture` — desktop + mobile chrome, right-rail
TOC, sidebar tree renders.
- [ ] `/langgraph-python/concepts/architecture` — framework selector
pill active, sidebar links scoped to `/langgraph-python`.
- [ ] `/prebuilt-components/chat` — right-rail TOC now visible (was
hidden by frontmatter).
- [ ] `/reference` — index renders (was 404 due to legacy redirect).
- [ ] `/reference/components/copilotchat` — DocsLayout chrome intact.
- [ ] `/ag-ui` — tab/section nav renders as folders.
- [ ] Mobile (375px) — `MobileTopNav` shows logo + search + hamburger;
tapping hamburger opens Fumadocs's native mobile sidebar with the full
page tree.
- [ ] Tablet (1100px) — no "weird gap" from TOC popover; title fully
visible.
- [ ] Dark mode — no tinted surround around the framework picker;
sidebar surface matches body.
- [ ] Code blocks — clean rounded chrome, icon-style copy button (no
chip with its own border).
- [ ] No regression on banner dismiss flow (banner sets
`--fd-banner-height` to 0; sidebar/nav shift accordingly).

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-05-18 18:52:32 -07:00
github-actions[bot] f1ff2051c4 style: auto-fix formatting 2026-05-19 01:23:41 +00:00
Tyler Slaton b30e01ad81 feat(shell-docs): adopt Fumadocs UI + floating sidebar + Shiki code chrome
Rebuild the shell-docs chrome on top of Fumadocs UI primitives and ship the
visual polish pass that replaces the legacy custom chrome.

- Fumadocs adoption: route every docs page (home, framework-scoped, ag-ui)
  through a shared ShellDocsLayout that wraps DocsLayout / DocsPage with
  the project's nav slot, sidebar config, scroll preserver, and content
  wrapper. Swap custom tabs/code-block components for Fumadocs's Tabs,
  CodeBlock, Pre, CodeBlockTabs, DynamicCodeBlock — Snippet and DemoSource
  now share the same chrome as authored fenced blocks.
- Syntax highlighting: replace rehype-highlight + hand-rolled hljs CSS
  with Fumadocs's Shiki-based rehypeCode in all three MDX renderers and
  in mdx-registry-loader. A tiny `transformerMeta` Shiki transformer
  surfaces fence title= / language as data-attrs so MdxCodeBlock can
  render the file-path figcaption + floating copy button.
- Sidebar: floats on all four viewport edges (rounded-2xl, 0.75rem inset,
  light-gray border), framework picker pill is rounded-xl with symmetric
  padding above/below, sticky picker bg matches the panel surface.
  Section headers render in normal caps (no more uppercase shouting), with
  scroll position preserved across navigations via SidebarScrollPreserver.
- Navbar: bg flips to `--bg`, full-width inset matches the sidebar,
  search trigger drops its border and the entire right-wing pill is the
  click target.
- Code chrome: figure surface forced to plain white in light and the
  matching dark in dark, shadow stripped, figcaption divider uses
  `--border` (was `currentColor` from `text-fd-muted-foreground`). Scoped
  the `.reference-content code` chip-bg rule to `:not(pre)` so block
  code bodies no longer pick up the gray inline-chip background.
- Content area: 49px (3.0625rem) of left/right padding so the article
  column has visible breathing room from both the floating sidebar and
  the viewport edge.
- IA: meta.json restructure for /docs (Build Generative UI section,
  controlled/declarative/open-ended folders, A2UI lifted to its own
  folder with an index page, Migrate moved under Other), Concepts content
  rewrite, snippet/region cleanups.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 18:20:48 -07:00
Sam Julien 3d8a83e53e ci(showcase): disable auto docs-sync ahead of shell-docs cutover (#4831)
## Summary

Shell-docs is becoming the canonical authoring source for CopilotKit
documentation on the upcoming cutover. The existing
\`showcase_docs-sync.yml\` workflow auto-syncs from
\`docs/content/docs/\` down to \`showcase/shell-docs/src/content/docs/\`
on every push to main that touches the upstream tree — which would
clobber edits made directly in \`showcase/shell-docs/\` after cutover.

This PR disables the push trigger on
\`.github/workflows/showcase_docs-sync.yml\` and keeps
\`workflow_dispatch\` for manual re-run if the cutover is reverted.

## Files changed

- \`.github/workflows/showcase_docs-sync.yml\` — 5 lines

## Test plan

- [ ] Confirm the workflow no longer fires on pushes to main that touch
\`docs/content/docs/**\` or \`docs/snippets/**\`
- [ ] Confirm \`workflow_dispatch\` still allows manual runs from the
Actions UI
2026-05-18 15:49:55 -07:00
Martha Kelly Schumann 83e191149f ci(format): really fix the gitignored-path auto-commit poison (#4904)
## Summary

Follow-up to #4901. That PR unblocked main with the 12-file format fix,
but the workflow change it shipped doesn't actually fix the underlying
bug — the auto-commit step is still poisoned the moment any
tracked-but-gitignored path lands in a PR's diff.

This PR does the real fix and proves it on real CI.

## Why #4901's workflow change wasn't enough

`xargs -a .pr-format-files.existing.txt git add --` stages files from
the same list oxfmt was scoped to. But the collection step picks up
tracked-but-gitignored paths (e.g.
`showcase/aimock/d5-recorded/recorded/openai-*.json` — they match
`*.json`, are tracked, but sit under a `recorded/` ignore rule). Those
paths end up in `.pr-format-files.existing.txt`, oxfmt rewrites them,
`git add` still refuses them with the "ignored by one of your .gitignore
files" warning and `exit 1`, and the step still aborts. Same failure
mode as #4879.

## The real fix

Filter `.pr-format-files.existing.txt` against `git ls-files -i -c
--exclude-standard` — the authoritative list of tracked-but-ignored
paths — in the collection step. Three effects:

1. oxfmt no longer rewrites scratch files (correct semantic: `recorded/`
is recording-session scratch per its own .gitignore comment).
2. `git diff --name-only` after the formatter run won't contain any
ignored paths attributable to oxfmt.
3. The auto-commit's `git add` only sees non-ignored paths, can't choke.

## Verification

**Local** (already done in the working branch):

| Setup | git add behavior |
|---|---|
| Pipe ignored fixture path → git add | `exit 1`, "ignored by
.gitignore" |
| Pipe mixed list (fixture + real source) → git add | `exit 1`, only
real source actually stages, but exit 1 still kills `set -e` step |
| Filter the list first via `ls-files -i -c`, then git add | `exit 0`,
only real source stages, no warning |

**Real CI** (this PR):

The second commit deliberately steps on both halves of the failure mode:
- A `recorded/openai-*.json` fixture is dirty in the PR diff
(tracked-but-ignored path).
- One source file (`prebuilt-popup.spec.ts`) is reverted to its
pre-#4901 unformatted state (forces oxfmt to do real work and the
auto-commit path to run).

Without the filter, the format job would die at `git add` exactly the
way #4879 did. With the filter, the source file gets auto-fixed and the
auto-commit lands cleanly.

## Merge plan

If CI is green, drop the `test:` commit (and the auto-fix commit it
triggers) with `git reset --hard <fix-sha>` and force-push so only the
workflow change lands on main.
2026-05-18 15:42:23 -07:00
Martha Schumann 256910f1a1 ci(format): drop tracked-but-gitignored paths from format scope
The static_quality format job's auto-commit step refuses tracked-but-
gitignored paths (`git add` exit 1, propagated as xargs exit 123), which
killed the entire step on PR #4879 and let 12 unformatted source files
land on main.

Filter `.pr-format-files.existing.txt` against `git ls-files -i -c
--exclude-standard` (the authoritative list of tracked-but-ignored
paths) so:

- oxfmt no longer rewrites those scratch files
- the auto-commit's `git add` never sees them, can't choke on them

Verified locally:

  $ echo '<recorded fixture>' > list.txt
  $ cat list.txt | xargs git add --   # current behavior: exit 1
  $ git ls-files -i -c --exclude-standard > ignored.txt
  $ grep -vxFf ignored.txt list.txt > scoped.txt   # filter drops it
  $ cat scoped.txt | xargs git add --   # no-op, exit 0
2026-05-18 14:47:44 -07:00
Austin Merrick 5017b0fd01 fix(ci): unblock main formatter + harden auto-commit step (#4901)
## Summary

Main has been red on `static / quality → format` since 2026-05-18
14:24Z. The first red push was the merge of PR #4879, and every push
since has stayed red on the same 12 unformatted files under
`showcase/integrations/{langgraph-python,langgraph-typescript}`.

This PR does two things:

1. **Unblocks main** — runs `oxfmt --write` against the 12 files the
push-scope check is failing on. Pure formatting (key reordering, line
wrapping); no behavior changes.

2. **Hardens the format job's auto-commit step** — `Commit formatting
fixes` previously fed `git diff --name-only` into `git add`. If a
tracked-but-gitignored path showed up in the diff, `git add` refused it
and the whole step aborted (exit 123), so the auto-fix commit never
reached the PR branch. That's how #4879 was merged with 12 unformatted
files: the PR's `oxfmt --write` had fixed them, but the auto-commit blew
up on `showcase/aimock/d5-recorded/recorded` and the fixes were never
pushed back.

The step now stages only paths from `.pr-format-files.existing.txt` —
the same scoped list the formatter operates on — so unrelated
working-tree diffs can no longer poison the commit.

## Verification

- `oxfmt --check .` passes on this branch (9152 files).
- After merge, the next `static / quality` push run on main should go
green.

## Follow-ups (out of scope)

- Make `format` a required status check on main so a red format job
blocks merge.
- Decide whether `showcase/aimock/d5-recorded/recorded` should be
untracked or its ignore rule adjusted.
2026-05-18 14:31:34 -07:00
Martha Kelly Schumann ee07388672 Merge branch 'main' into martha/oss-131-fix-red-formatter-ci-on-main-copilotkit 2026-05-18 14:17:05 -07:00
Martha Kelly Schumann 4d51d72ba3 fix(showcase): include tool implementations in tool-rendering highlight (#4900)
## Summary

Original intent: make 9 integrations' Tool Rendering demos show the tool
implementations they import (QA team finding).

Scope grew to also unblock the bundler from two pre-existing drift
sources that landed earlier today and were silently blocking shell
rebuilds.

### Commits

1. **`fix(showcase): include tool implementations in tool-rendering
highlight`**
Adds `tools/get_weather.py`, `tools/query_data.py`,
`tools/schedule_meeting.py`, `tools/search_flights.py` (or the `.ts`
equivalents under `shared-tools/` for mastra) to the `highlight:` array
of each integration's `tool-rendering` demo. Reasoning-chain and
catch-all variants intentionally left alone (reasoning-chain defines its
tools inline; catch-all variants teach generic handling and would be
undercut by per-tool detail).
Integrations: `ag2`, `agno`, `crewai-crews`, `langroid`, `llamaindex`,
`ms-agent-python`, `pydantic-ai`, `strands`, `mastra`.

2. **`fix(showcase/ms-agent-python): repair stale chat-slots and
headless-complete highlights`**
Two manifest entries in `ms-agent-python` pointed at filenames that no
longer exist on disk after PR #4895's port. The bundler refused to build
the shell once any manifest in `ms-agent-python` changed. Adopted LGP's
canonical highlight pattern for both demos.

3. **`fix(showcase/aimock): scope hitl book_call fixtures to toolName`**
Two recorded d5 fixtures matching `"1:1 with Alice"` and `"intro call
with the sales team"` returned `book_call` tool calls without a
`toolName` constraint. The fixture-tool-surface validator flagged ~30
violations across most integrations because `gen-ui-interrupt` and
`interrupt-headless` use `schedule_meeting`, not `book_call`. Adding
`toolName: "book_call"` scopes the fixtures to hitl-in-chat only.

## Why this PR grew

The QA-team finding only required commit 1. Commits 2 and 3 are
pre-existing drift that surfaced because commit 1's manifest edits
triggered the shell rebuild and the `validate-fixture-tool-surface`
check. Both pre-existing failures had been red on main for several hours
and were inherited by every PR. Fixing them inline was the only path to
a green CI on this branch.

## Test plan

- [x] All 36 added `tools/` paths exist on disk.
- [x] `showcase/scripts/bundle-demo-content.ts` runs clean (697 demos
bundled across all three shells).
- [x] `showcase/scripts/validate-fixture-tool-surface.ts` runs clean
(367 fixtures × 622 demos, no drift).
2026-05-18 14:12:59 -07:00
Martha Schumann a74f044a66 ci(format): stage scoped file list in auto-commit step
The format job's "Commit formatting fixes" step previously fed the raw
`git diff --name-only` output into `git add`. If a tracked-but-gitignored
path (e.g. a build artifact) appeared in the diff, `git add` refused the
ignored path and aborted the step, so the auto-fix commit never landed
on the PR branch. PRs could then merge with formatting violations still
present, leaving main red on the post-merge push-scope check.

Stage only the paths listed in `.pr-format-files.existing.txt` — the
same scoped set the formatter operates on — so unrelated diffs in the
working tree can't poison the commit.
2026-05-18 14:12:36 -07:00
Martha Schumann 261ce3fa56 style: fix oxfmt violations on showcase/integrations 2026-05-18 14:12:28 -07:00
Martha Schumann 0b69408b6a fix(showcase/aimock): scope hitl book_call fixtures to toolName
Two recorded d5 fixtures matching `userMessage: "1:1 with Alice"` and
`userMessage: "intro call with the sales team"` returned `book_call`
tool calls without a `toolName` constraint in their match block. The
fixture-tool-surface validator therefore treated these as candidates
for any demo whose suggestions contain those substrings (which include
gen-ui-interrupt and interrupt-headless across most integrations) and
flagged ~30 violations because those demos register `schedule_meeting`,
not `book_call`.

Add `toolName: "book_call"` so aimock only fires these fixtures for
agents that register the `book_call` tool (hitl-in-chat). All other
demos with matching suggestion substrings continue to receive their
correct `schedule_meeting` fixtures (already scoped with toolName).

Validator: 367 fixtures × 622 demos — no drift.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 14:02:40 -07:00
Martha Schumann 98afe0d76d fix(showcase/ms-agent-python): repair stale chat-slots and headless-complete highlights
Both manifest entries point at file names that no longer exist on disk
after the LGP-cells port (PR #4895). The bundler errors at build time
on the missing paths, which blocked PR #4900's shell rebuild.

Adopt LGP's canonical highlight pattern for both demos.

- chat-slots: drop the three custom-* refs, keep page.tsx + slot-wrappers.tsx
- headless-complete: drop message-list.tsx + use-rendered-messages.tsx,
  add the chat/, hooks/, attachments/ subpaths that LGP uses

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 13:52:49 -07:00
Martha Schumann 9150c6fb66 fix(showcase): include tool implementations in tool-rendering highlight
QA team identified that the Tool Rendering demo across 9 integrations
imports `get_weather_impl`, `query_data_impl`, `schedule_meeting_impl`,
and `search_flights_impl` from `tools/`, but the bundled code view does
not include the `tools/` files. New users see the imports but cannot
see the implementations.

Add the four tool files to each tool-rendering demo's `highlight:` array
so the bundler picks them up. Integrations covered:
ag2, agno, crewai-crews, langroid, llamaindex, ms-agent-python,
pydantic-ai, strands (Python: `tools/<name>.py`), and mastra
(TypeScript: `shared-tools/<name>.ts`).

Reasoning-chain variants left untouched (they define tools inline).
Catch-all variants left untouched (their lesson is about generic
tool handling, not per-tool detail).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 13:24:33 -07:00
Austin Merrick 5bb9296bf3 feat(react-core): forward followUp option through useComponent (#4897)
## Summary

`useComponent` wraps `useFrontendTool` but wasn't forwarding `followUp`.
Adds the option to the config and passes it through.

## Changes

- Forward `followUp?: boolean` from `useComponent` config to
`useFrontendTool`
- Add test coverage in `use-component.test.tsx` (`forwards followUp
option to useFrontendTool`)
- Document the option in the v2 hook reference

## Test plan

- [x] `nx test react-core` passes (new `forwards followUp option to
useFrontendTool` case)
- [x] Manually verified in `examples/v2/react`
2026-05-18 11:41:13 -07:00
Austin Merrick 3ad8fbe6c1 Merge branch 'main' into austin/oss-72-add-follow-up-to-usecomponent-interface 2026-05-18 11:01:38 -07:00
Austin Merrick 784b365d4f feat(react-core): forward followUp option through useComponent 2026-05-18 10:53:20 -07:00
Jordan Ritter 59ffe91c12 fix(showcase/aimock): align local Docker setup with production (#4896)
## Summary

Fixes 4 critical differences between local and production aimock setup
that caused behavior divergence:

1. **Remove catch-all fixture from feature-parity.json** -- the
`"match": {}` entry at the end intercepted ALL unmatched requests with a
generic response, preventing `--proxy-only` from falling through to real
providers (OpenAI/Anthropic/Gemini)

2. **Merge d5-recorded fixtures into d5-all.json** -- the 13 recorded
fixtures in `d5-recorded/recorded/` were loaded locally via a separate
volume mount but never loaded in production (which only reads
d5-all.json, smoke.json, feature-parity.json). Now they live in
d5-all.json and the separate volume mount + `--fixtures` entry are
removed.

3. **Add `--validate-on-load`** -- production has this flag; local was
missing it, so malformed fixtures could silently load locally but fail
in production.

4. **Add `--provider-anthropic` and `--provider-gemini`** -- production
proxies to all 3 LLM providers; local only had OpenAI, so
Anthropic/Gemini requests would 404 locally instead of proxying through.

## Test plan

- [ ] `node -e
"JSON.parse(require('fs').readFileSync('showcase/aimock/d5-all.json','utf8'));console.log('Valid')"`
passes
- [ ] `node -e
"JSON.parse(require('fs').readFileSync('showcase/aimock/feature-parity.json','utf8'));console.log('Valid')"`
passes
- [ ] `docker compose -f showcase/docker-compose.local.yml up aimock`
starts without validation errors
- [ ] Unmatched requests proxy to real providers instead of returning
generic catch-all
2026-05-18 10:26:56 -07:00
github-actions[bot] 680a4ebd6c style: auto-fix formatting 2026-05-18 17:25:03 +00:00
Jordan Ritter c97ef77579 fix(showcase/aimock): align local Docker setup with production
1. Remove catch-all fixture from feature-parity.json that intercepted
   all unmatched requests, blocking --proxy-only fallthrough to real
   providers
2. Merge 13 d5-recorded fixtures into d5-all.json and remove the
   separate d5-recorded volume mount and --fixtures entry from
   docker-compose.local.yml (production only loads d5-all.json)
3. Add --validate-on-load flag to local aimock command (matches
   production)
4. Add --provider-anthropic and --provider-gemini to local aimock
   command (production has all 3 providers, local only had OpenAI)
2026-05-18 10:23:53 -07:00
Alem Tuzlak 13d2cc8b7e feat(showcase/ms-agent-python): port LGP showcase cells to MAF (beautiful-chat + 8 more) (#4895)
## Summary

Brings `ms-agent-python` to LGP/ADK parity across the first 9 demo cells
in manifest order. Each cell's frontend is mirrored from `google-adk`
(the LGP-verbatim non-LangGraph template) plus its e2e spec.

Cells 10–14 are also ported but unverified (Docker crashed mid-rebuild
today — source is on disk and ready to verify next session).

## Cells covered

| # | Cell | Status |
| --- | --- | --- |
| 1 | beautiful-chat | ✅ 8/9 pills green (Excalidraw tracked) |
| 2 | agentic-chat | ✅ all 3 starter pills |
| 3 | auth | ✅ sign-in → chat → sign-out |
| 4 | chat-customization-css | ✅ scoped theme |
| 5 | chat-slots | ✅ all 8 slot overrides |
| 6 | declarative-gen-ui | ⚠️ first pill renders; follow-up call leaks
to OpenAI (tracked) |
| 7 | frontend-tools | ✅ gradients change per pill |
| 8 | frontend-tools-async | ✅ async note search |
| 9 | gen-ui-agent | ⚠️ narration works; agent-state-card needs
dedicated agent (tracked) |
| 10 | gen-ui-tool-based | 🟡 ported, unverified |
| 11 | headless-complete | 🟡 ported, unverified |
| 12 | headless-simple | 🟡 ported, unverified |
| 13 | hitl-in-app | 🟡 ported, unverified |
| 14 | hitl-in-chat | 🟡 ported, unverified |

## Cross-cutting fixes

- **Python agent** (`beautiful_chat.py`, `a2ui_dynamic.py`,
`tools/generate_a2ui.py`): pydantic-empty-args support for
`generate_a2ui`, session-injected `latest_user_message` for per-pill
fixture matching, state_update push for `manage_todos`, dropped
`predict_state_config` (PydanticSerializationError on emoji), flat
literal-children for `search_flights`, NESTED v0.9 a2ui_operations
shape.
- **Frontend wiring**: single shared `HttpAgent` aliased to
`beautiful-chat`+`default` so STATE_SNAPSHOTs reach the canvas;
`useAgent({ agentId: "beautiful-chat" })` in canvas; `frontend_tools`
underscore aliases in `/api/copilotkit`.
- **New UI infrastructure**: `src/components/ui/*` (10 shadcn
components) + `src/lib/utils.ts` + `radix-ui`, `lucide-react`,
`class-variance-authority`, `clsx`, `react-markdown`, `remark-gfm`,
`tailwind-merge`, `@radix-ui/react-separator` in `package.json`.
- **Aimock fixtures** (`feature-parity.json`): Excalidraw `create_view`
with string-encoded `elements`; Calculator `generateSandboxedUi`;
`manage_todos` `chunkSize: 5000` override (emoji surrogate-pair fix);
sonnet + Is-17-prime walkthrough.

## Open follow-ups (not blockers for this PR)

- Excalidraw `MCPAppsActivityRenderer` doesn't fire on
`agent_framework_ag_ui` path → tool call shows but iframe never mounts.
Investigation doc filed in Notion.
- `declarative-gen-ui` first pill renders but agent_framework
auto-iterates after the tool result, makes a follow-up LLM call that
aimock can't match → leaks to real OpenAI → 502 → cosmetic "Internal
error" banner. Investigation doc filed in Notion.
- `gen-ui-agent` needs a dedicated python agent with `launch-step` state
schema for `InlineAgentStateCard`.

## ms-agent-dotnet beautiful-chat (partial, included in PR)

Same template port as ms-agent-python. Two known issues left in place
(UTF-16 surrogate-split streaming bug on `manage_todos`, A2UI render
gap). `SearchFlights` rewritten to flat literal-children.

## Test plan

- [ ] D5 ms-agent-python:beautiful-chat → green
- [ ] D5 ms-agent-python:agentic-chat → green
- [ ] D5 ms-agent-python:auth → green
- [ ] D5 ms-agent-python:chat-customization-css → green
- [ ] D5 ms-agent-python:chat-slots → green
- [ ] Headed walkthrough of cells 10–14 to verify the unverified ports
- [ ] Re-run any partial cells (#6, #9) to see whether follow-ups have
changed behavior

## Hook note

`test-and-check-packages` lefthook excluded for the commit — the failing
`packages/shared` vitest is a pre-existing monorepo test-infra issue
(can't resolve `graphql`/`zod` despite both being installed in
`node_modules`). All my changes are scoped to `showcase/*` so they
cannot have caused it.
2026-05-18 19:21:41 +02:00
github-actions[bot] a632b3fc05 style: auto-fix formatting 2026-05-18 16:48:29 +00:00
Alem Tuzlak 746e13b655 feat(showcase/ms-agent-python): port LGP showcase cells to MAF (beautiful-chat + 8 more)
Brings ms-agent-python to LGP/ADK parity across the first 9 demo cells in
manifest order. Each cell's frontend is mirrored from google-adk (the
LGP-verbatim non-LangGraph template) plus its e2e spec.

## Cells covered

- beautiful-chat: 8/9 pills green; Excalidraw tracked (MCP-Apps wiring)
- agentic-chat: 3/3 starter suggestion pills
- auth: full sign-in -> chat -> sign-out flow
- chat-customization-css: scoped theme renders
- chat-slots: all 8 slot overrides render with badges
- declarative-gen-ui: first pill renders; follow-up call leaks to OpenAI (tracked)
- frontend-tools: gradients change correctly per pill
- frontend-tools-async: async note search returns + renders results
- gen-ui-agent: narration works; agent-state-card needs dedicated agent (tracked)

Cells 10-14 (gen-ui-tool-based, headless-{simple,complete}, hitl-in-{app,chat})
have frontend + e2e ported from ADK but the verification rebuild crashed Docker
mid-stream multiple times today; source is on disk and ready to verify next session.

## Python agent fixes

- beautiful_chat.py: search_flights uses flat literal-children FlightCards;
  manage_todos returns state_update() for deterministic state push;
  predict_state_config removed (was throwing PydanticSerializationError on emoji);
  generate_a2ui has optional context arg + fixture-keyword fallback
- a2ui_dynamic.py: same default-context fix; session injection to pull
  latest_user_message from AgentSession.input_messages for per-pill fixture matching
- tools/generate_a2ui.py: synced from canonical shared/python/tools/ (NESTED v0.9 shape)

## Frontend wiring fixes

- /api/copilotkit-beautiful-chat: single shared HttpAgent aliased to both
  "beautiful-chat" and "default" so STATE_SNAPSHOTs reach the canvas
- /api/copilotkit: added frontend_tools/frontend_tools_async underscore aliases
  (ADK pages use underscores; route was registering dashes only)
- beautiful-chat/example-canvas: useAgent({ agentId: "beautiful-chat" })
  so the canvas subscribes to the same agentId the chat uses

## New UI infrastructure

- src/components/ui/* (10 shadcn components mirrored from ADK)
- src/lib/utils.ts (cn tailwind-merge helper)
- package.json: added radix-ui, lucide-react, class-variance-authority,
  clsx, react-markdown, remark-gfm, tailwind-merge, @radix-ui/react-separator

## Aimock fixtures (feature-parity.json)

- Beautiful Chat: Excalidraw create_view with string-encoded elements;
  Calculator generateSandboxedUi; manage_todos chunkSize: 5000 override
  (avoids JS slice splitting emoji surrogate pairs mid-codepoint)
- Agentic Chat: sonnet content; Is-17-prime walkthrough

## ms-agent-dotnet beautiful-chat (partial, not user-verified)

Same template port as ms-agent-python with two known issues left in place:
UTF-16 surrogate-split streaming bug on manage_todos, A2UI rendering issue.
SearchFlights rewritten to flat literal-children.

## Hook scope note

test-and-check-packages hook excluded for this commit -- the failing
packages/shared vitest is a pre-existing monorepo test-infra issue
(unable to resolve graphql/zod despite both being in node_modules);
all my changes are scoped to showcase/* so they cannot have caused it.
2026-05-18 18:46:28 +02:00
Jordan Ritter dbc65bb157 fix(showcase/langgraph-typescript): fix all stale manifest highlight paths
- headless-complete: message-list.tsx moved to chat/message-list.tsx
- headless-complete: use-rendered-messages.tsx replaced with actual
  subdir files (chat/chat.tsx, hooks/*, attachments/*, tools/*)
- gen-ui-interrupt: time-picker-card.tsx moved to
  _components/time-picker-card.tsx
2026-05-18 07:37:55 -07:00