The ThreadsPanelGate renders a first-paint placeholder while the client-only
drawer mounts. It was either a bare `w-72` div (no surface → a black/white
column flash in the page bg) or a fixed 18rem inline-styled div (correct color
but, on mobile where the mounted drawer floats, the reserved 18rem collapsed on
mount → content shifted left).
Replace both with a shared `.drawerPlaceholder` class that matches the open
drawer's footprint + surface (18rem, drawer bg, hairline border) on desktop and
`display: none` below 1024px (the mobile drawer floats, so reserve no column).
Result: no color flash and no content shift on load. Applied across all 7
migrated examples (themed vs raw surface tokens per example).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Port the langgraph-python mobile-header fix to langgraph-js (same shared
canvas/header demo). Below 1024px the threads drawer's floating launcher is
fixed top-left and collided with the top-left CopilotKit header:
- max-lg:pl-24 on the header so the logo clears the launcher pill
- max-lg:pt-2.5 + pb-0 (and drop the logo span's pb-1.5 on mobile) so the
logo is vertically centered with the launcher + the Chat/App toggle
- trim the collapsed launcher's icon buttons (2rem -> 1.75rem) + tighter
padding so the pill height lines up with the toggle
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Below 1024px the in-flow threads column squeezed the demo content and the
(full-screen) CopilotSidebar chat into slivers. Raise the responsive
breakpoint from 900→1024 and make the panel a true off-canvas overlay:
- collapsed → a small floating launcher pill pinned top-left (z-1300),
above the full-screen mobile chat, so threads stay reachable
- open → a fixed full-height panel sliding in from the left (z-1300),
content + chat use the full width behind it
- default the drawer to collapsed when innerWidth ≤ 1024 on mount
Applied across all 7 integration examples' shared threads-drawer, each
adapted to its own theme tokens (themed examples use --threads-drawer-*,
raw examples use --card/--border for the launcher surface).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Below 900px the drawer already overlays the content when open (existing media
query), but it defaulted to open — so on phones the 16rem panel covered the
content + chat on load. Default isOpen from window.innerWidth (> 900) so narrow
screens start at the 3.5rem rail; the user expands to the overlay on demand.
The drawer is client-mounted, so reading window in the initializer is safe.
Applied to the shared threads-drawer.tsx across all examples + north-star.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- New thread (header + collapsed rail) now switches to a fresh threadId
(crypto.randomUUID()) instead of setting it to undefined. Setting threadId
undefined after a thread was selected did not reset the V2 chat — it kept
showing the previous conversation. A new id forces the configuration provider
to re-thread to an empty conversation.
- Collapsed-rail buttons use a native title tooltip instead of the styled
::after one, which clipped horizontally against the viewport's left edge in
the narrow rail. The wider expanded row keeps the styled tooltip.
Applied to the shared threads-drawer.tsx across all examples + north-star.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The threads-drawer had drifted into two near-identical .tsx variants (a 1-char
encoding diff) during the bespoke passes. Unify all examples onto a single
shared threads-drawer.tsx, which also propagates the mastra review fixes:
- collapsed rail: hover tooltips on the expand + new-thread buttons, and the
non-interactive decorative icon (read as a dead button) removed;
- tooltip renders below the trigger in each example's themed module.css (the
styled ::after tooltip was clipped when shown above the trigger).
Per-example theming (the module.css token values) is unchanged — only the
shared logic + the tooltip positioning rule are reconciled.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Next route handlers only declared GET/POST, so the threads REST API's
DELETE (delete thread) and PATCH (archive/restore) were 405'd by Next before
reaching the runtime — thread deletion and archive were broken in every
example. Export PATCH + DELETE → handle(app) across all 7 routes.
mastra threads-drawer review fixes:
- tooltip renders below the trigger (the styled ::after tooltip was clipped by
the drawer's overflow containers when shown above);
- collapsed rail drops a non-interactive decorative icon (read as a dead button)
and adds hover tooltips to the expand + new-thread buttons.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Root cause of the parity-check CI failures:
The 5 verbatim-tracked files in `examples/integrations/langgraph-python/`
(the north-star) all carried `typescript/consistent-type-imports` and
`react/self-closing-comp` warnings that oxlint wants to auto-fix.
The lefthook pre-commit `lint-fix` hook is scoped to staged files
and re-stages fixes via `stage_fixed: true`. So when I ran
`pnpm parity:sync --target=strands-python` and staged the synced
files, oxlint --fix rewrote them on commit to satisfy the
type-imports rule — turning `import { NextRequest }` into
`import type { NextRequest }`, etc. The north-star was never touched
by the hook (nothing staged in langgraph-python/), so it kept the
un-fixed form. The two diverged at commit time and parity:check
caught the drift.
Two prior commits (0559faf3d, 80425fcc8) tried to land the sync but
each landed empty: lefthook + stage_fixed reverted the working-tree
changes to match the north-star's un-fixed form, then the linter's
auto-fix re-applied the same delta the hook had just undone — net
zero file content but with the linter-fixed form, which the post-
commit hook then reverted again. Hard to debug because `git
commit` reported success and shortstat hid the no-op.
This commit fixes the root cause instead of the symptom:
1. Apply `pnpm exec oxlint --fix` directly to the 5 north-star
files (`docker-route-override.ts`,
`src/app/declarative-generative-ui/renderers.tsx`,
`src/components/ui/{badge,button}.tsx`, `src/lib/utils.ts`).
The fixes match what the pre-commit hook would have applied:
type-only imports → `import type`, self-closing JSX → `<X />`.
2. Re-run `pnpm parity:sync` for all three instances
(strands-python, langgraph-fastapi, langgraph-js) so they
verbatim-match the new north-star.
3. Verified `pnpm parity:check` exits 0; all four trees lint clean
(`pnpm exec oxlint examples/integrations/.../`).
Net effect: every instance now matches the north-star byte-for-byte,
and the lint-fix hook is a no-op on these files going forward.
Files touched per directory (5 each, except strands-python which had
docker-route-override.ts already synced in a prior attempt):
examples/integrations/langgraph-python/ — 5 files
examples/integrations/langgraph-fastapi/ — 5 files
examples/integrations/langgraph-js/ — 5 files
examples/integrations/strands-python/ — 4 files
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous commit bumped @langchain/langgraph to 1.3.0 but missed the
peer-dep ripple: langgraph 1.3.0 peers @langchain/core ^1.1.44. The agent
pinned core 1.1.41 and the root override pinned 1.0.1, both below the
required range, so npm install in the agent container failed with ERESOLVE.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@langchain/langgraph-api@1.2.1 (pulled transitively by langgraph-cli) imports
STREAM_EVENTS_V3_MODES from @langchain/langgraph/web, which only exists in
1.3.0. The starter's overrides + agent dep were pinning langgraph to 1.2.9,
causing the agent container to crash on startup with a SyntaxError. Bump
the override and the direct pin to 1.3.0, and pin @langchain/langgraph-cli
in the npx invocations so future cross-package drift in the LangChain
ecosystem cannot silently re-break this starter.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rewrite the langgraph-js agent to use `createAgent` from `langchain`
(matching langgraph-python) with `copilotkitMiddleware` and
`stateStreamingMiddleware` from `@copilotkit/sdk-js/langgraph-middlewares`.
Tools now use `ToolRuntime` for state and tool-call-id access. System
prompt inlined in `agent.ts`; drop the file-based `PROMPT.md`.
Replace the legacy single-stage Dockerfile with a Node-only two-stage
build that mirrors the langgraph-python Dockerfile (frontend build →
runner, HttpAgent route override for Docker, Turbopack→webpack).
Add JS-specific `entrypoint.sh` (launches `@langchain/langgraph-cli dev`
+ Next.js standalone) and `docker-compose.test.yml` (wget healthcheck
for the alpine-based agent image, STARTER=langgraph-js default). Both
added to the instance's `allowedDivergence` in the parity manifest.
Rewrite the README to drop Python/uv prerequisites and list the correct
TypeScript tool paths.
Two small changes to the parity tooling, surfaced while validating it on
the langgraph-fastapi port.
1. Drop the per-instance PROMPT.md file. The reference demo
(langgraph-python) does not load agent/PROMPT.md at runtime — it inlines
the prompt as a triple-string literal in agent/main.py. Syncing a
cosmetic PROMPT.md file to every instance created a contract the code
did not follow. Now:
- sync.ts no longer writes agent/PROMPT.md per instance.
- verify.ts greps the first non-blank line of _parity/canonical/PROMPT.md
against each instance's agent source. Inline the prompt string in
source; verifier passes.
- Deleted the now-orphaned PROMPT.md copy under langgraph-js/agent/.
2. Track Dockerfile, docker/Dockerfile.agent, and serve.py in the shared
verbatim-files list. These were previously silent "allowed divergence"
across all instances — any Docker or runtime-adapter drift shipped
unflagged. Now:
- Added to tracked.verbatimFiles in manifest.json.
- langgraph-js keeps them in allowedDivergence (Node-only stack, legit
difference from the Python-based reference).
- langgraph-fastapi drops them from allowedDivergence (same language
stack as the reference; Docker/serve.py should match).
README and the copilotkit-demo-parity skill updated to match the new
prompt contract. Verifier still supports `--target` and exits non-zero on
unexpected drift.
Align langgraph-js with examples/integrations/langgraph-python via the
parity tooling. Remove legacy app/ layout, adopt src/ layout, rewrite
the TS agent to expose the tracked tool surface (manage_todos,
get_todos, query_data, generate_a2ui, search_flights) and todos state,
and write the canonical PROMPT.md. Keeps LangGraphAgent + stategraph
runtime (allowed divergence per the manifest); brings deps,
Dockerfile.app, entrypoint, showcase metadata, and shared UI into
lockstep. Parity verifier: 88 ok / 0 error.
- langgraph-python: replace ephemeral pkg.pr.new URLs with stable @copilotkit/*@1.56.2
- mastra: wire dev to run ui + agent via concurrently (was only starting UI)
- Restore `|| scripts\setup-agent.bat` / `|| scripts\run-agent.bat` fallback across
12 starter templates so npm install + npm run dev work on Windows without Git Bash
- Add --validate-on-load to all aimock invocations (4 workflows/scripts
+ 13 integration docker-compose files)
- Replace hardcoded 2-file fixture list with dynamic discovery across
showcase/, examples/integrations/*/, scripts/doc-tests/ (16 fixtures)
- Add sanity check to prevent silent zero-test pass when discovery fails
- Extend showcase_validate.yml path filter to trigger on
examples/integrations/**/fixtures/** and scripts/doc-tests/fixtures/**
- Import and use ValidationResult type for callback parameters
- Fix scripts/doc-tests/fixtures/default.json to use { fixtures: [...] }
envelope shape
Playwright install stderr is diagnostic signal — version/network errors,
missing system libs, or browser download failures all surface here. Only
suppress stderr on the noisy npm install step. Also pin the image-tag /
client-version relationship with a code comment on one compose file so
future bumps know to keep them aligned.
The Playwright Docker image (mcr.microsoft.com/playwright:v1.52.0-noble)
ships with all Chromium system libraries and browsers pre-installed, so
`--with-deps` adds no runtime value — it only forces a redundant
`apt-get update && apt-get install` inside the tests container.
That apt-get call is the sole source of the intermittent
"Installation process exited with code: 100" / "Failed to install
browsers" failures that rotate across the 12 smoke matrix entries. The
underlying cause is transient Ubuntu archive mirror hash/size mismatches
("File has unexpected size ... Mirror sync in progress?", "Hash Sum
mismatch"), which cause apt to abort with exit 100. Because each matrix
job races apt against archive.ubuntu.com independently, the failing
subset rotates per run (run 24526747926 hit 5 starters; run 24509673514
hit a different 5; run 24495760568 hit 3) — classic flake, not a per-
starter regression.
Dropping --with-deps eliminates the apt-get call entirely. The browsers
themselves are already present at /ms-playwright/chromium-* in the base
image, and `npx playwright install chromium` remains as a cheap no-op
that self-heals if the pinned Playwright version ever drifts from the
image's bundled browser build.
- Remove @langchain/community from sdk-js peerDependencies (unused,
was blocking @langchain/core@1.x resolution)
- Add langchain@^1.0.0 to langgraph-js agent deps to prevent
transitive resolution to 0.3.x
- Add postcss.config.mjs to mcp-apps threejs-server
- Remove '|| .bat' fallback from all starter package.json scripts so
real errors on Linux/macOS are not masked by a failing .bat attempt
- Fix typos: 'isseus' -> 'issues', 'interactin' -> 'interacting'
- Fix crewai-crews README title/body saying 'Flow' instead of 'Crew'
- Fix a2a-a2ui README wrong agent name and file path
- Remove phantom lint/dev:debug scripts from README Available Scripts
sections where those scripts don't exist in package.json
- Add missing dev:ui and dev:agent to mastra README
- chmod +x all new .sh scripts so they work on Linux/macOS
- Use --ignore-scripts in langgraph-js Dockerfiles to avoid postinstall
failure (agent/ dir not yet copied during npm install stage)
- Install agent deps in production Dockerfile after COPY agent/
- Fix hardcoded pnpm commands in agent-spec README
Reorder package manager instructions to show npm first as the default.
Remove stale 'ignores lock files' notes since lock file entries were
removed from .gitignore. All starters now work with npm, pnpm, yarn,
or bun — user's choice.
Starters should not constrain users to a specific package manager.
The .gitignore gets cloned into the user's project, so ignoring
certain lock files would prevent them from committing their chosen
package manager's lock file.
Flatten langgraph-python, langgraph-js, and mcp-apps starters so
npm install && npm run dev works out of the box. Replace Turborepo
with concurrently, move apps/* to root, update Dockerfiles, READMEs,
and entrypoints. Also remove stray pnpm-lock.yaml from a2a-a2ui and
ms-agent-framework-dotnet starters.
Every starter's route.ts now reads process.env.AGENT_URL as the
primary agent endpoint, with framework-specific vars as fallback:
- AGENT_URL || "http://localhost:8000" (pydantic-ai, adk, agno, crewai,
ms-agent-python, ms-agent-dotnet, strands-python)
- AGENT_URL || LANGGRAPH_DEPLOYMENT_URL || "http://localhost:8123"
(langgraph-python, langgraph-js)
- AGENT_URL || "http://localhost:9000" (llamaindex)
Also adds .env.example with AGENT_URL to all starters.
Replace eslint and prettier with oxlint and oxfmt for faster linting
and formatting across the monorepo. Remove all eslint and prettier
configs, dependencies, and related packages. Add .oxlintrc.json and
.oxfmtrc.json for the new tooling. Update CI workflows and lefthook
hooks accordingly. Reformat codebase with oxfmt.
https://claude.ai/code/session_01GMkSf29p78HuMR1mbXn8He
Run prettier on ~1,865 files across examples/ to match the monorepo's
formatting standards. These files were imported as-is from standalone
repos that used different prettier configs.
SVG files are text-based XML averaging ~218 bytes each. LFS tracking
adds per-file HTTP fetch overhead with no storage benefit, suppresses
git diff output, and breaks tutorial clone instructions that use
GIT_LFS_SKIP_SMUDGE=1 (users get LFS pointers instead of icons).