The managed runtime's claimOnce() declared `adapters: [this.cfg.adapter]`
(defaulting to "slack"), which Intelligence used to filter claimable
deliveries by provider. A runtime serving a bot with both Slack and Teams
adapters would therefore never receive the bot's Teams deliveries — they
stayed queued forever while Slack worked.
The managed runtime is provider-agnostic: it emits abstract render frames
and Intelligence renders per the delivery's own reply target. So the claim
must not filter by provider. Drop the adapter filter from the claim body;
one config-free `intelligenceAdapter()` now serves every channel its bot
has attached.
Verified end-to-end locally against managed Teams: inbound JWT -> claim ->
agent -> render -> Bot Connector egress all succeed with this change.
Managed getHistory (app-api /api/bots/history) doesn't include the in-flight
turn — unlike native adapters whose getHistory rebuilds the live thread — so
runAgent({context}) alone runs the agent with zero messages (→ provider 400).
Pass the current message (contentParts ?? text) as `prompt`, the sanctioned
mechanism for input not in the adapter's reconstructed history. Verified live:
the managed Slack bot now returns a real answer over the Phoenix loop.
The realtime primitives (startManagedBots, connectPhoenixHostedBotChannel,
PhoenixRealtimeTransport) existed but nothing composed them into a launcher, so
the managed path defaulted to HTTP and Phoenix was never actually used.
- startManagedBotsOnChannel(bots, { channel, scope, runtimeInstanceId }) — wraps
an already-connected channel in a PhoenixRealtimeTransport (delivery source +
render sink) and starts the bots via startManagedBots. Split out so the
behavior is unit-testable against a fake channel.
- startManagedBotsOverPhoenix(bots, config) — thin glue: connect the gateway
bot-IO channel, delegate, disconnect on stop().
- phoenixEgress: fail-loud EgressSink (Phoenix routes all egress through the
render sink).
- examples/slack/app/managed.ts — a REAL consumer of the launcher: the same
Slack bot as index.ts (agent/tools/context/commands/handlers identical) run in
managed mode over Phoenix instead of the native slack() adapter. No native
index.ts changes.
Tests drive a real createBot through the full managed path over a fake channel:
delivered turn → render frame → completion INTENT (never self-ack); throwing
handler → fail intent. Live-stack E2E + manual validation are the OSS-406 proof;
scale-out (Teams, etc.) is OSS-459.
## What
Adds a pre-merge guard that prevents the
[OSS-451](https://linear.app/copilotkit/issue/OSS-451) **dead-on-load**
failure class from recurring:
- `showcase/scripts/validate-runtime-routes.ts` — static validator +
`validate-routes` npm script
- `showcase/scripts/__tests__/validate-runtime-routes.test.ts` (+
fixture integration) — regression coverage
- `.github/workflows/showcase_validate-wiring.yml` — runs it on every
`showcase/integrations/**` PR
> **Stacked on #5881** (the fix). Base branch is
`mark/oss-451-mastra-demos-404`; retarget to `main` once #5881 merges.
The guard is green *because* #5881 is present.
## Why
OSS-451 shipped because **nothing linked a demo page's `runtimeUrl`
string to the existence of the `/api` route it names.** The only
automatic pre-merge gate for `showcase/**` is `showcase_build_check.yml`
— a Docker *build* — and a page that references a non-existent route
compiles perfectly cleanly. So three demos went dead-on-load in
production undetected (the e2e specs that *would* have caught it run
on-demand only, post-deploy, and exclude TS-only Mastra).
## How it works
For every **shipped** demo — a demo directory whose slug is in its
integration's `manifest.yaml` `features` — the validator asserts every
`runtimeUrl` it declares resolves to a real route dir under
`src/app/api/`.
- Unshipped / experimental demos (not in `features`) and
`not_supported_features` are **skipped** — they aren't claimed to work,
so they don't fail the gate. Promoting one into `features` immediately
starts enforcing it (this is the safety net for the still-unshipped
`declarative-hashbrown` / `declarative-json-render`).
- A `validate-runtime-routes.baseline.json` can grandfather pre-existing
violations (same pattern as the pin-drift `fail-baseline.json`). **The
fleet is currently clean — 0 violations, no baseline needed.**
- Handles the shared `/api/copilotkit` route and catch-all routes
(`copilotkit-auth`, `copilotkit-voice`) by asserting the top-level route
dir exists.
## Verification
- `npm run validate-routes` → clean across all 21 integrations.
- Removing the 3 OSS-451 routes locally → the guard flags **exactly
those 3** and exits 1; restoring → exits 0.
- Regression test (5 cases): flags the shipped-demo-with-missing-route
shape, passes shared + dedicated routes, skips unshipped.
- Full `showcase/scripts` vitest suite: **2151 tests green**.
- Workflow YAML validated; actions pinned to SHA; `contents: read` only;
no secrets.
## Follow-up for a maintainer
Add **"Showcase: Runtime-Route Wiring (PR)"** to the branch-protection
required checks so it blocks merge like the build check does.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
## What
Adds the three missing per-demo CopilotKit runtime routes in the Mastra
showcase integration:
- `src/app/api/copilotkit-a2ui-fixed-schema/route.ts`
- `src/app/api/copilotkit-declarative-gen-ui/route.ts`
- `src/app/api/copilotkit-agent-config/route.ts`
Fixes [OSS-451](https://linear.app/copilotkit/issue/OSS-451) — three
demos are **dead on load** in production (`showcase-mastra-production`).
## Why (root cause)
Each of these demo pages sets `<CopilotKit
runtimeUrl="/api/copilotkit-<demo>">`, but those route handlers were
**never created** in the Mastra integration — the pages were mirrored
verbatim from the `langgraph-python` north-star (which *does* have
per-demo routes) without porting the backend routes. The client's
runtime-info fetch 404'd → `runtime_info_fetch_failed` → the page never
mounted. Deterministic, reproduces on every plain page load.
`git log --all` confirms these route dirs have **0 commits ever** in
Mastra; they arrived via the omnibus parity PRs #4280 / #5127.
## Approach
Dedicated routes, mirroring the proven `copilotkit-beautiful-chat`
pattern rather than repointing the pages at the shared
`/api/copilotkit`. This is required for the two A2UI demos: they pass a
client-side catalog, which makes the runtime default `injectA2UITool` to
`true`, but `weatherAgent` already owns its own `generate_a2ui` tool —
serving them from the shared route would **double-bind** the tool. So
the A2UI routes set `injectA2UITool: false` and pin `defaultCatalogId`
to the catalog the page registers (avoids "Catalog not found").
`agent-config` is a plain runtime that registers the exact agent id the
page requests (`agent-config-demo`).
Zero page edits — the pages already point at these routes.
## Scope
Page-load / 404 only, matching the ticket's explicit scope. These agents
currently alias `weatherAgent` (consistent with how every other Mastra
demo currently runs); **full behavioral parity** (dedicated Mastra
agents that emit real A2UI operations / honor agent-config context) is
tracked under OSS-381.
## Verification
- `next build` compiles all three into the route manifest
(`.next/server/app/api/copilotkit-*/route.js`).
- Runtime smoke against the built server: `POST` to each new route
returns **400** (route resolves, handler runs) — identical to the
flagship `copilotkit-beautiful-chat` — vs **404** for a nonexistent
route. No `getLocalAgent returned null` init error.
- Recommend a click-through in an aimock/real-LLM env before locking D5
regression coverage.
## Follow-ups (not in this PR)
- `declarative-hashbrown` / `declarative-json-render` are broken the
same way but are `status: unshipped` (non-navigable); they + the
`manifest.yaml` `byoc-*` drift need reconciling before they can flip to
`wired`.
- Preventing recurrence (a page→route/agent invariant in the pre-merge
gate) ships as a **separate PR**.
## Summary
Upgrades `react-syntax-highlighter` in `@copilotkit/react-ui` from
`^15.6.1` to `^16.1.1`.
The v16 line pulls `refractor@5` and `prismjs@^1.30.0`, keeping
react-ui's syntax-highlighting dependency chain current for downstream
consumers. The public API used by `CodeBlock` (the `Prism` / `Light`
exports) is unchanged.
Closes#2823.
## Changes
- `packages/react-ui/package.json` — `react-syntax-highlighter`
`^15.6.1` → `^16.1.1`
- `pnpm-lock.yaml` — regenerated
## Verification
- `nx run @copilotkit/react-ui:build` ✅
- `nx run @copilotkit/react-ui:check-types` ✅
- `nx run @copilotkit/react-ui:test` ✅ (53/53)
- Syntax highlighting renders the same across common languages (JS,
TS/TSX, CSS, JSON, Rust, shell, …)
- `pnpm install --frozen-lockfile` ✅🤖 Generated with [Claude Code](https://claude.com/claude-code)
Bumps react-syntax-highlighter from ^15.6.1 to ^16.1.1. The v16 line
pulls refractor 5 and prismjs ^1.30.0, keeping react-ui's syntax
highlighting dependency chain current for downstream consumers.
The public API used by CodeBlock (the Prism/Light exports) is unchanged,
and highlighting renders the same across common languages.
Closes#2823.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
## What does this PR do?
Adds two clonable starter templates —
`examples/integrations/claude-sdk-python` and
`examples/integrations/claude-sdk-typescript` — that show CopilotKit
driving a Claude Agent SDK agent over AG-UI, mirroring the
`langgraph-python` showcase (todos canvas, charts, A2UI flight cards +
dynamic dashboards, human-in-the-loop, theme toggle, threads drawer).
Each agent is a thin, idiomatic layer on the official `ag-ui-claude-sdk`
/ `@ag-ui/claude-agent-sdk` adapters: three backend tools (`query_data`,
`search_flights`, `generate_a2ui`) live in per-tool modules and are
wired into `ClaudeAgentAdapter`, while the shared todo board is driven
by the adapter's built-in `ag_ui_update_state` tool. The default model
is `claude-sonnet-5` and local dev uses a real `ANTHROPIC_API_KEY`
(matching the official AG-UI dojo). Both instances are registered in the
`_parity` manifest so their frontends stay synced with the north-star.
## Related PRs and Issues
- Complements the Claude Agent SDK quickstart docs (#5840)
## Checklist
- [ ] I have read the [Contribution
Guide](https://github.com/copilotkit/copilotkit/blob/master/CONTRIBUTING.md)
- [x] If the PR changes or adds functionality, I have updated the
relevant documentation
- [ ] "Allow edits by maintainers" is checked
🤖 Generated with [Claude Code](https://claude.com/claude-code)
CodeRabbit flagged that the form onSubmit added to headless-chat could submit
empty/whitespace messages. The handler now returns early on blank input and the
submit button is disabled when the message is empty. Applied to the claude-sdk
starters (where the form lives); headless-chat.tsx is already declared
allowedDivergence for these instances, so parity stays green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Revert the cross-demo parity sync from b34a9a348: langgraph-python (north-star)
and the langgraph-js / langgraph-fastapi / strands-python instances are restored
to their origin/main state — this PR should not mutate the canonical demo or its
siblings.
Instead, keep the CodeRabbit fixes on the claude-sdk-* starters and declare the
affected shared files as per-instance `allowedDivergence` in the parity manifest,
so `pnpm parity:check` passes without touching the other demos. The starters
carry fixes the north-star has not caught up to yet:
- border-3 -> border-[3px]; bg-[--x] / text-[--x] -> [var(--x)] (Tailwind v4)
- JSX.IntrinsicElements -> React.JSX.IntrinsicElements; Recharts <Bar shape> type
- tool-rendering args?: unknown; mode-toggle a11y; headless-chat <form>
- docker-route-override AGENT_URL trailing-slash normalization
next.config.ts is left matching the north-star template (its ignoreBuildErrors is
a shared build-config concern and the Docker build re-adds it regardless).
parity:check green (5/5 instances, 0 errors); claude-sdk tsc + oxfmt clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The CodeRabbit fixes in d4ef84f2c edited verbatim parity-tracked files
directly in the claude-sdk-* instances, diverging them from the north-star
(langgraph-python) and failing `pnpm parity:check`.
Move the shared-surface fixes to the north-star and propagate to every
tracked instance via `pnpm parity:sync --all`:
- border-3 -> border-[3px] (border-3 is not a Tailwind utility)
- bg-[--x] / text-[--x] -> [var(--x)] (Tailwind v4 CSS-variable syntax)
- JSX.IntrinsicElements -> React.JSX.IntrinsicElements (@types/react 19)
- Recharts <Bar shape> callback typing
- tool-rendering args?: unknown
- mode-toggle aria-pressed/type/role, headless-chat <form> + aria-label
- docker-route-override AGENT_URL trailing-slash normalization
Also revert the next.config.ts `ignoreBuildErrors` removal: next.config.ts is
a north-star template file shared across all integration demos, so the
suppression can't be dropped on a subset without breaking parity, and dropping
it template-wide would need every demo verified to build clean without it. The
two real type errors it was masking are now fixed at the north-star, so the
shared surface is type-clean regardless.
parity:check green (5/5 instances, 0 errors); claude-sdk tsc + oxfmt clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Resolve the real issues surfaced by CodeRabbit on the new claude-sdk-python /
claude-sdk-typescript starters (frontend files are shared, so most fixes apply
to both):
- Fix two type errors that `ignoreBuildErrors` was masking: `JSX.IntrinsicElements`
-> `React.JSX.IntrinsicElements` (@types/react 19) and the Recharts `<Bar shape>`
callback type; then drop the blanket `typescript.ignoreBuildErrors` from
next.config.ts so source type-checks. The Dockerfile's build-time patch still
re-adds it for the `next@latest` Docker build, so deploy behavior is unchanged.
- Fix Tailwind v4 CSS-variable syntax: `bg-[--x]` -> `bg-[var(--x)]`, and
`border-3` -> `border-[3px]` (border-3 is not a utility -> invisible spinner).
- Harden the agent tools: omit the empty ANTHROPIC_API_KEY, wrap the Anthropic
call in try/catch (TS + Python), normalize the AGENT_URL trailing slash, and
make the Flight schema's id/airlineLogo/statusIcon required to match the
"must have" tool description.
- Minor a11y: mode-toggle `aria-pressed`/`type`/`role`, headless-chat `<form>`
+ `aria-label` (Enter-to-submit).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add claude-sdk-python and claude-sdk-typescript to the Integrations table
in examples/README.md (17 → 19; total 48 → 50). The two starters were added
to examples/integrations/ but were missing from the index.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two clonable starter templates showing CopilotKit driving a Claude Agent SDK
agent over AG-UI, mirroring the langgraph-python showcase (todos canvas, charts,
flight cards, dynamic dashboards, HITL, theme, threads drawer).
Each agent is a thin, idiomatic layer on the official ag-ui-claude-sdk /
@ag-ui/claude-agent-sdk adapters: three backend tools (query_data, search_flights,
generate_a2ui) live in per-tool modules and are wired into ClaudeAgentAdapter,
while the shared todo board is driven by the adapter's built-in ag_ui_update_state
tool. The default model is claude-sonnet-5 and local dev uses a real
ANTHROPIC_API_KEY (matching the official AG-UI dojo). Both instances are
registered in the _parity manifest so their frontends stay synced with the
langgraph-python north-star.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
## Summary
SDK-emit half of **OSS-446** (lease-token fencing for hosted-bot
render/complete). The `fail` path already sends the delivery lease
token; **render-accept** and the **completion intent** did not — so
app-api fell back to the weaker instance-id + expiry check on those two
paths.
This makes the SDK send `leaseToken` on both, on **both transports**:
- **HTTP** — `HttpRenderEventSink.push` now includes `leaseToken`, via a
new `leaseTokenFor(deliveryId)` accessor on `HttpDeliverySource`
(mirrors the existing `scopeFor`). (`ack` already sent it.)
- **Phoenix** — `push` (render-accept) and `complete_requested` now
carry `leaseToken` from `DeliveryState` (`fail` already did).
## Why it's safe to ship now (ahead of the app-api "require" flip)
Verified end-to-end against the live Intelligence server:
- **Gateway** `validate_render_payload` allows `leaseToken` (optional,
`maybe_put_lease_token`) and forwards it via `accept_render_event`;
`validate_complete_payload` merges the payload through and forwards it
via `complete_delivery`.
- **app-api** fences render-accept (`$N IS NULL OR lease_token_hash =
$N`) and complete (`$N IS NULL OR ...`) **optionally** today — so
supplying the token starts fencing on it immediately, and omitting it
still works. No breakage; strictly a security improvement on the paths
that were previously unfenced.
## Scope
This is **half A** (SDK emit). **Half B** — flipping app-api's
render-accept + complete fences from optional to *required* and dropping
the instance-id/expiry fallback — is deferred until #511 (managed Teams)
settles `managed-bots/service.ts`, and follows from OSS-446's "require
*once the SDK sends it*" premise.
## Tests
- HTTP: render-accept POST asserts `leaseToken` from the claimed lease
flows into the body.
- Phoenix: render-accept + `complete_requested` payloads assert
`leaseToken`.
- Build + 95 tests green.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
SDK-emit half of OSS-446 (lease-token fencing for hosted-bot render/complete).
The fail path already sends the lease token; render-accept and the completion
intent did not, so app-api fell back to instance-id + expiry there.
- HTTP: HttpRenderEventSink.push now includes leaseToken (new leaseTokenFor()
bridge on HttpDeliverySource, mirroring scopeFor). (ack already sent it.)
- Phoenix: push (render-accept) and complete_requested now carry leaseToken
from DeliveryState (fail already did).
Optional/forward-compatible: app-api + gateway already accept and fence on the
token when present (verified render/complete validators + fencing SQL), falling
back to the old check when absent — so this deploys safely ahead of the app-api
flip-to-required (OSS-446 half B), which waits on #511 settling managed-bots
service.ts.
## Summary
Adds **Open Generative UI (OGUI)** to the Northwind banking demo: the
agent can author sandboxed, interactive UI (rendered in an isolated
iframe) that pulls **real, read-only banking data** via sandbox-function
callbacks — so every figure it shows is real app data (fetched on
demand), never fabricated, and no secret ever crosses the boundary.
- **New `src/opengen/` module** — a stable, module-scope
`sandboxFunctions` array
(`getTransactions`/`getPolicies`/`getCards`/`getKpis`) whose handlers
read a module snapshot kept fresh by a headless `<SandboxDataSync/>`
mirroring the app's live (role-filtered) `useCreditCards` view. Handlers
return **projection DTOs** — `getCards` drops `pin`/`expiry`, guarded by
a no-leak unit test.
- **Shared over-limit derivation** — extracted to
`src/lib/over-limit.ts` so the chat readable, the A2UI report renderers,
and the OGUI sandbox all agree on which charges are over limit
(behavior-preserving).
- **OGUI enabled on both runtime paths** (Intelligence + OSS) with an
**artifact-type routing fence** in the agent prompt:
`generateSandboxedUi` only for interactive/custom UI, explicitly
excluded from reports/charts *even when the user says "build"* (protects
the existing "Build a spend report on the canvas" pill), and never part
of the teach/recall arc.
- **Provider wiring** — `openGenerativeUI={{ sandboxFunctions,
designSkill: NORTHWIND_DESIGN_SKILL }}` plus two OGUI-only pills ("Build
an interactive spend explorer", "Prototype a cash-flow what-if
calculator").
- **Deterministic routing guard** — `e2e/ogui-routing.spec.ts`
(dedicated OSS-mode config, isolated ports, no docker) pins both
boundary sides: the 5 visualization pills still route to their curated
tool (no iframe), and the 2 OGUI pills render an iframe. Also fixes
stale pill assertions in `smoke.spec.ts`.
Additive only — no changes to existing curated charts, the A2UI report
canvas, or the teach/recall arc beyond the behavior-preserving
over-limit extraction.
## Test Plan
- [x] Unit suite green (65 tests) — incl. `over-limit`,
`sandbox-functions` (no-`pin`/`expiry` leak + over-limit flag + KPI
counts)
- [x] `tsc --noEmit` clean · eslint clean · `nx build` success
- [x] OGUI routing e2e: **7 passed** (OSS mode, no docker) — curated
pills + boundary + OGUI pills
- [ ] **CI**: license-gated `smoke.spec.ts` + docker-backed
`memory-learning.spec.ts` (blocked locally: no license token /
Intelligence stack; must pass unchanged in CI)
- [ ] **Manual**: render "Build an interactive spend explorer", confirm
iframe figures match the dashboard in light/dark, and no PIN is ever
shown
## Notes
- Follow-up (out of scope): additional over-limit derivation copies
remain in `proactive-notice.tsx`, `transactions-list.tsx`,
`pending-approvals-chat.tsx` — candidates to migrate onto the new shared
helper.
- The deterministic e2e pins the tool call (aimock), so it proves the
tool-rendering plumbing and that curated surfaces still work — real LLM
routing is the manual check above.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The .first() guard on the 'rendered on the canvas' handoff-pill assertion
was justified by an inaccurate comment (accumulation across exchanges). The
real cause is intra-turn: generateSandboxedUi has followUp:true, so aimock
re-serves the same fixture on the unchanged-userMessage follow-up turn in
replay -> a second identical pill. A terminating sequenceIndex follow-up
fixture was attempted but destabilized the suite (title-generation requests
substring-match the pill text and consume the sequence counter before the
real leg-1 turn), so the .first() guard remains. Test/fixtures only; no
source changes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
## Release channels-slack v0.1.1
**Scope:** `channels-slack` | **Bump:** `patch`
---
### How this release process works
1. **This PR was created automatically** by the "release / create-pr"
workflow.
It bumped the `channels-slack` packages to `0.1.1`
and generated AI-enhanced release notes.
2. **CI runs on this PR** — the full test suite (unit tests, lint, type
checks, build)
must pass before merging. This is the review gate.
3. **Review the release notes** in `release-notes.md` in this PR.
If a Notion draft was created, you can edit the release notes there
before merging.
4. **When this PR is merged**, the `release / publish` workflow
automatically:
- Builds all packages
- Publishes the `channels-slack` packages to npm at version `0.1.1`
- Creates git tag `channels-slack/v0.1.1`
- Creates a GitHub Release with the final release notes
### Before merging
- [ ] CI is green (tests, lint, types, build)
- [ ] Version bumps look correct
- [ ] Release notes are accurate (edit in Notion if a draft was created)
---
> **Do not merge until CI is fully green.** The full test suite runs
automatically on this PR.
## Problem
Claude Agent SDK docs could render malformed or missing extracted
snippets across the generated Python and TypeScript integration docs.
The generative UI pages had stale duplicate regions and generic setup
leakage, while the custom look-and-feel reasoning and slots pages
referenced demo cells or regions that did not exist for every Claude
integration.
## Why
The docs pipeline treated accidental duplicate region names across files
as intentional multi-file regions, and several authored docs pages
drifted from the actual generated showcase demo IDs/regions. That left
some pages visually correct at a glance but broken when users opened
specific extracted code snippets.
## Fix
- Move the shared `bar-chart-renderer` regions to the complete
`useComponent` call and delete stale duplicate snippet files.
- Add an explicit duplicate-region guard and verifier coverage for
accidental cross-file region collisions.
- Add line-emphasis support for extracted `<Snippet>` blocks and setup
`<DemoCode>` output.
- Scope generative UI feature pages away from generic `agent-setup`
boilerplate.
- Repair the shared reasoning-messages docs to use the generated
`reasoning-default` and `reasoning-custom` demo cells.
- Add the missing Claude Python chat-slots teaching snippet regions and
keep both Claude slot snippets self-contained.
- Broad-audit both Claude integration docs locally, then targeted-audit
the repaired reasoning/slots pages in light and dark mode.
## Problem
The published declaration files for `@copilotkit/react-core`,
`@copilotkit/react-ui`, and `@copilotkit/react-textarea` contain imports
that TypeScript cannot resolve, so **`attw` (Are The Types Wrong)
reports `InternalResolutionError` across every resolution mode**
(`node10` / `node16` / `bundler`). In `@copilotkit/react-core` this was
being **masked in CI** by `--ignore-rules internal-resolution-error` on
the package's `attw` script — so the existing `check:packages` gate
looked green while consumers under `moduleResolution:
bundler`/`node16`/`nodenext` got broken types (the symptom reported in
#3324: `has no exported member 'useAgent'`, etc.).
Two distinct artifacts leaked into the emitted `.d.ts` / `.d.cts` /
`.d.mts` (neither affects the JS bundles):
1. **Side-effect CSS imports** — `import "./index.css"` is intentionally
kept in the JS so styles auto-load for bundler consumers, but
`rolldown-plugin-dts` also left it in the declarations, where TypeScript
can't resolve a `.css` as a typed module.
2. **Extensionless relative `./context` import** —
`@copilotkit/react-core/v2/headless` re-exports the externalized context
module; the JS bundle correctly externalizes it to
`@copilotkit/react-core/v2/context`, but the declaration kept the
relative `./context`, which is invalid in ESM declarations.
> Note: this is **not** the missing-`exports.types`-condition theory
from #3324. tsdown deliberately relies on co-located `.d.mts`/`.d.cts`
siblings; `@copilotkit/core` already resolves cleanly. The real defects
are the two leaked imports above.
## Fix
A small tsdown `build:done` hook post-processes the emitted declarations
**on disk** (after every format is written, so it catches both `.d.mts`
and `.d.cts`):
- strips side-effect CSS imports from declarations (JS keeps them);
- rewrites the relative `./context` import to the
`@copilotkit/react-core/v2/context` package path (matching how the JS
bundle externalizes it).
Also:
- **Removed the `--ignore-rules internal-resolution-error` band-aid**
from `react-core`'s `attw` script so the existing CI gate validates for
real.
- **Dropped the dead `codeSplitting` option** from the UMD configs —
tsdown never reads it (it's a rolldown-only key), and it was failing
`tsc` in the configs that type-check themselves. UMD output is unchanged
(single file).
## Verification
- All three packages build; **no CSS or relative-`./context` imports
remain in any declaration**, while the JS bundles still contain them
(styles auto-load preserved).
- `attw` + `publint` pass for all packages **with no suppression**
(`react-core`'s `/v2`, `/v2/headless`, `/v2/context` are green for
node16-cjs/esm/bundler).
- Unit tests pass.
- A standalone consumer project (real tarball install, `skipLibCheck:
false`) type-checks the public APIs — including `useAgent` /
`useFrontendTool` / `useConfigureSuggestions` — cleanly under **both
`bundler` and `nodenext`**, and the headless↔context class is nominally
identical.
## Out of scope (follow-ups)
- `@copilotkit/react-native`: its `--ignore-rules
internal-resolution-error` currently suppresses nothing (no IRE) and it
has a separate `NoResolution` flag.
- `@copilotkit/vue`: a large, genuine set of `.vue`/relative-import
declaration errors unrelated to this change.
Relates to #3324.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
## Summary
- Add the new `copilotkit import` command to the shared CLI docs
rendered at `/cli` and integration CLI pages.
- Document ADK and LangGraph examples, scripted flags, source credential
env vars, `--dry-run`, and `--replace`.
- Update the shell-docs nav test expectation for de-duped `Threads`
placement in authored framework nav.
## Test Plan
- `cd showcase/shell-docs && npm run lint` (passes with existing
warnings)
- `cd showcase/shell-docs && npm run typecheck`
- `cd showcase/shell-docs && npm test`
- `cd showcase/shell-docs && npm run build`
## Release channels-teams v0.1.1
**Scope:** `channels-teams` | **Bump:** `patch`
---
### How this release process works
1. **This PR was created automatically** by the "release / create-pr"
workflow.
It bumped the `channels-teams` packages to `0.1.1`
and generated AI-enhanced release notes.
2. **CI runs on this PR** — the full test suite (unit tests, lint, type
checks, build)
must pass before merging. This is the review gate.
3. **Review the release notes** in `release-notes.md` in this PR.
If a Notion draft was created, you can edit the release notes there
before merging.
4. **When this PR is merged**, the `release / publish` workflow
automatically:
- Builds all packages
- Publishes the `channels-teams` packages to npm at version `0.1.1`
- Creates git tag `channels-teams/v0.1.1`
- Creates a GitHub Release with the final release notes
### Before merging
- [ ] CI is green (tests, lint, types, build)
- [ ] Version bumps look correct
- [ ] Release notes are accurate (edit in Notion if a draft was created)
---
> **Do not merge until CI is fully green.** The full test suite runs
automatically on this PR.