Resolve SEO redirect destinations against the docs host (SU-17); forward
the query string on SEO redirects (SU-16); match bare paths on wildcard
SEO sources (SU-19). Collapse duplicate slashes in docs-host redirect
destinations (SU-13). Regression test for /shared//evil.com open redirect
(SU-18). Emit 308 for docs-host redirects to match next.config parity
(SU-2). Add a path boundary to the api matcher exclusion (SU-15). Loud
guard when registry yields zero framework slugs (SU-20). Keep PostHog
capture alive via event.waitUntil (SU-14). Note docs-host redirects are
untracked by design (SU-8). Cover docs-host redirects at the middleware
level (SU-11).
Squash of the SEO-table + matcher-hardening cluster.
Carry backendHostPattern + docsHost in the shell runtime config (no longer
baked from registry.json at Docker build time). Derive demo backend URLs at
runtime from the pattern; issue docs-host 301s from middleware with a runtime
DOCS_HOST so a misconfigured value can no longer 500 every docs route.
Validate NEXT_PUBLIC_LOCAL_BACKENDS and empty overrides; guard the backend
host pattern against silent env misconfigs. Reword the stale demo-page
comment about backend URL derivation. Pin the registry slug set and SSR
placeholder URL composition; fix env/spy/global leaks in runtime-config
test cleanup.
Squash of the initial runtime-URL refactor cluster:
- feat(showcase): carry backendHostPattern + docsHost in shell runtime config
- fix(showcase): derive demo backend URLs at runtime instead of baked registry values
- fix(showcase): issue docs-host 301s from middleware with runtime DOCS_HOST
- fix(showcase): never let a misconfigured DOCS_HOST 500 every docs route
- fix(showcase): guard backend host pattern against silent env misconfigs
- fix(showcase): validate NEXT_PUBLIC_LOCAL_BACKENDS values and empty overrides
- docs(showcase): reword stale demo-page comment about backend URL derivation
- test(showcase): fix env/spy/global leaks in runtime-config test cleanup
- test(showcase): pin registry slug set and SSR placeholder URL composition
## What
Across the **threads-enabled integration examples**
(`examples/integrations/*`, excluding the vestigial
`langgraph-python-threads`):
1. **Drop demo-user provisioning** — removes the `provision-user`
one-shot service from the shared `_intelligence/docker-compose.yml`.
2. **Bump Intelligence → 0.5.0** —
`ghcr.io/copilotkit/intelligence/composite` `0.2.0` → `0.5.0`.
3. **Bump CopilotKit → 1.60.0** — every `@copilotkit/*` pin
(`react-core`, `react-ui`, `runtime`, `a2ui-renderer`, `sdk-js`)
`1.59.5` → `1.60.0`, with regenerated `package-lock.json` files.
## Why
The `provision-user` service existed to seed `cpki.users` (a bare id
plus a per-project `<projectId>_<userId>` alias) so the runtime's
`demo-user` identity satisfied the `threads_user_id_fkey` constraint.
The **0.5.0 composite provisions thread users on demand**, so the manual
seed is obsolete and can be dropped from the local-dev overlay.
## Scope
18 threads-enabled examples (each renders the `ThreadsDrawer` panel):
a2a-a2ui, a2a-middleware, adk, agent-spec, agentcore, agno,
crewai-crews, crewai-flows, langgraph-fastapi, langgraph-js,
langgraph-python, llamaindex, mastra, mcp-apps,
ms-agent-framework-dotnet, ms-agent-framework-python, pydantic-ai,
strands-python.
`langgraph-python-threads` is intentionally untouched (vestigial, slated
for removal).
## Notes
- The `identifyUser` demo stub in each route handler is **kept** — it
selects the demo identity; provisioning that identity is now the
composite's job.
- `_intelligence/docker-compose.yml` is not parity-tracked;
`@copilotkit` pins are — `pnpm parity:check` passes (0 errors).
- The Intelligence `0.5.0` image + on-demand provisioning is validated
at runtime (needs the image + license token + Docker), not in this PR's
static checks.
Bumps every @copilotkit/* pin (react-core, react-ui, runtime, a2ui-renderer,
sdk-js) from 1.59.5 to 1.60.0 across the threads-enabled integration examples,
and regenerates each package-lock.json to the 1.60.0 dependency closure.
Excludes the vestigial langgraph-python-threads example.
Updates the shared `_intelligence` activation overlay to the composite 0.5.0
image and removes the `provision-user` one-shot service. That service seeded
`cpki.users` (a bare id plus a per-project `<projectId>_<userId>` alias) so the
runtime's `demo-user` identity satisfied `threads_user_id_fkey`. The 0.5.0
composite provisions thread users on demand, so the manual seed is obsolete.
## What does this PR do?
Puts the Slack docs behind a shared early-access password. Gated pages
render blurred and non-interactive with an unlock card floating above
them:
- **`/slack`** — the Slack guide, plus every framework-scoped variant
(`/<framework>/slack`), opted in via an `earlyAccess: slack` frontmatter
flag
- **`/reference/bot/**`** — the entire bot reference section
(`@copilotkit/bot*` packages, the Slack adapter), gated on `version ===
"bot"`
### The unlock card
- **"Slack is in early access"** headline, a short explanation of the
gate and of what CopilotKit for Slack is, and a product screenshot (a
Slack thread with a generative-UI bot reply — stored in **git LFS**,
rendered via `next/image`).
- **"Don't have the password? Reach out to request early access to
Slack"** linking to the [beyond-the-web early-access
form](https://go.copilotkit.ai/beyond-the-web-form).
- Password input + Unlock for folks who already have it.
### How it works
- `early-access-gate.tsx` (client) blurs the page content (`inert`,
unselectable, pointer-events off) and renders the unlock card in a
**sticky scrollport-height frame**, so the card stays centered in view
while the blurred page scrolls underneath — sidebar and top nav stay
crisp and usable. On very short viewports the card caps its height and
scrolls internally.
- `src/lib/early-access.ts` is the gate registry (password, copy, CTA,
image, storage key) shared by server routes and the client component.
Unlocking persists in `localStorage`, so one unlock covers the guide and
all reference pages.
- Ungated pages never mount the client component (server-side
conditional wrappers in `docs-page-view.tsx` and the reference route).
- Light/dark theme via existing tokens; responsive down to mobile (input
row stacks to a full-width button).
### Reviewer notes
- This is a deliberate **soft gate** (early-access friction, not a
security boundary): the password ships in the client bundle, and
raw-MDX/`llms.txt`/search-index routes still expose the content.
- Verified in the running app: scroll-following card, wrong-password
error state, unlock-in-place, cross-page persistence,
mobile/tablet/desktop, dark mode.
- Tests: 6 new vitest cases (config integrity incl. form URL, SSR
locked-state markup, unknown-id pass-through).
Format/lint/typecheck/test/build all green locally.
## Related PRs and Issues
- Gates the docs introduced in #5368 (`docs(shell-docs): Slack platform
quickstart + Bots API reference`)
## Checklist
- [x] 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
- [x] "Allow edits by maintainers" is checked (lets us help iterate on
your PR directly — faster turnaround for everyone)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Blur the Slack guide (/slack and its framework-scoped variants) and the
entire bot reference section behind a client-side unlock card. The card
follows the scroll in a sticky scrollport-height frame, persists unlock
state in localStorage, and leaves the sidebar and top nav usable. Doc
pages opt in via earlyAccess frontmatter; the bot reference gates on
version === "bot". Visitors without the password get a product shot
(light/dark variants in git LFS, shown beside the form on wide cards
via container query) and a link to the beyond-the-web early-access
form.
## Release monorepo v1.60.0
**Scope:** `monorepo` | **Bump:** `minor`
---
### How this release process works
1. **This PR was created automatically** by the "release / create-pr"
workflow.
It bumped the `monorepo` packages to `1.60.0`
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 `monorepo` packages to npm at version `1.60.0`
- Creates git tag `monorepo/v1.60.0`
- 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.
## Summary
- Pass the resolved runtime `userId` through Intelligence thread reads
and message-history lookups.
- Include `userId` and `agentId` in Intelligence thread delete requests.
- Update Runtime tests to assert the new REST wire contract.
## Why
The Intelligence REST API now requires explicit app-user ownership for
direct thread reads, message reads, and destructive thread mutations.
Older Runtime code still omitted `userId` on those calls, which breaks
against the updated API even though create/list/connect/lock already
send `userId`.
## Validation
- `pnpm nx run @copilotkit/runtime:test -- --run
src/v2/runtime/intelligence-platform/__tests__/client.test.ts
src/v2/runtime/__tests__/handle-threads.test.ts
src/v2/runtime/__tests__/handle-run.test.ts`
- `git diff --check`
Skipped local package typecheck; it is known to be unreliable locally
and hit Node heap/long-running behavior in this worktree. CI should
provide the final signal.
## Why
Copilot Cloud is no longer promoted, but new users still find it through
stale links and code references — including the SDK's own JSDoc/console
messages. This scrubs the old Copilot Cloud framing **and** the client
`publicLicenseKey`/`publicApiKey` prop references from the SDK doc
surface.
Important distinction this PR is built around: the **client
`publicLicenseKey`/`publicApiKey` prop** is the header→cloud path (being
retired) and is **not** what activates the Intelligence runtime. The
Intelligence runtime license is the **server-side
`COPILOTKIT_LICENSE_TOKEN`** (Ed25519 JWT) → `licenseToken` on
`CopilotRuntime`. So the client prop is not documented here as the
premium/Intelligence enabler.
Follow-up to the link cleanup in #5258. Example-app + server-side
runtime documentation deferred ("Bucket B").
## What changed
Doc-comments / JSDoc / console strings / README prose — **no functional
code, no prop renames, no endpoint/header changes.**
- **Copilot Cloud → removed** from JSDoc/console/README across
react-core, react-ui, runtime, vue, shared, angular.
- **Client license-key prop references removed**, not reframed:
- `publicApiKey`/`publicLicenseKey` docstrings (react-core props + v2
provider) reverted to bare one-liners.
- "Requires a license key" / "premium feature" / `<CopilotKit
publicLicenseKey=…>` example notes dropped from the headless hook,
react-ui observability docs (`Chat`/`Popup`/`Sidebar`/`props`), and
runtime logging/`onError` JSDoc.
- No `npx copilotkit@latest license` guidance attached to client props
(that CLI yields the *server-side* token, not the client prop).
- **Angular**: all `licenseKey` mentions removed from the README — it's
no longer a premium feature (the license watermark is disabled) and the
key isn't needed to function.
- **Defunct features** (`guardrails_c`, `authConfig_c`,
`useCopilotAuthenticatedAction_c`) keep their code but lose their JSDoc
(`@internal Defunct`).
### Incidental (pre-commit lint-fix)
The repo's pre-commit hook auto-applied `import type` conversions on the
touched files (a pre-existing oxlint warning). Type-only, zero runtime
impact.
## Deliberately untouched
`api.cloud.copilotkit.ai` endpoint + `X-CopilotCloud-Public-Api-Key`
header (functional), prop names, gating logic, tests, CHANGELOGs, the
`#5351` skill files, and `CopilotCloudOptions`/`CopilotCloudConfig` type
identifiers.
## Out of scope (deferred — "Bucket B")
- Migrating example apps onto the
Intelligence/`COPILOTKIT_LICENSE_TOKEN` runtime model.
- Documenting the server-side `licenseToken` setup.
- Stale `CopilotCloud` watermark strings in `angular/config.ts`
(watermark is disabled; flagged for a separate cleanup).
## Verification
- `oxfmt --check` on changed files → pass
- `nx run-many build` (no cache) for
`@copilotkit/{shared,react-core,react-ui,runtime,vue}` → success
- `oxlint` on changed files → 0 errors
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Follow-up correction. The client publicLicenseKey/publicApiKey prop is the
header→cloud path and is NOT what activates the Intelligence runtime (that's
the server-side COPILOTKIT_LICENSE_TOKEN). So:
- Remove the `npx copilotkit@latest license` guidance from all client-prop
contexts — that CLI yields the server-side license token, not the client
prop value.
- Revert the client-prop docstrings (copilotkit-props, v2 CopilotKitProvider)
to bare one-liners; drop the premium/"requires a license key" framing from
the headless hook, react-ui observability docs, and runtime logging/onError
JSDoc rather than reframing.
- Angular: remove all `licenseKey` mentions from the README — it is no longer
a premium feature (the license watermark is disabled) and the key is not
needed to function.
Server-side license-token documentation remains deferred to the example/runtime
setup pass (Bucket B).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cloud is no longer promoted; the Intelligence license key is its replacement.
Scrub the old Copilot Cloud system from SDK JSDoc / doc-comments / console
messages / README prose so code references reflect how the license key is
obtained and used, mirroring examples/integrations/*:
- publicApiKey/publicLicenseKey docstrings (react-core props + v2 provider,
vue legacy types, copilot-context) describe the CopilotKit public license
key, acquired via `npx copilotkit@latest license` or the dashboard;
publicApiKey framed as the legacy alias of publicLicenseKey.
- Premium-feature docs (headless hook, react-ui Chat/Popup/Sidebar
observability, runtime logging/onError) drop "Copilot Cloud"/"requires a
publicApiKey" wording and the publicApiKey examples in favor of the public
license key + publicLicenseKey.
- console-styling messages and the angular README point at the license key
and the `npx copilotkit@latest license` command.
Defunct features (guardrails_c, authConfig_c, useCopilotAuthenticatedAction_c)
keep their code but lose their JSDoc (marked @internal defunct).
Functional surfaces untouched: api.cloud.copilotkit.ai endpoint, the
X-CopilotCloud-Public-Api-Key header, prop names, gating logic, tests,
CHANGELOGs. Example-app migration (Bucket B) deferred.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Route both the run path (agent-utils) and the /info response
(get-runtime-info) through a single isA2UIEnabled() predicate so the two
can no longer disagree on whether a2ui is on (the divergence behind #5369),
and add an optional `enabled` flag to the runtime a2ui config.
Backwards compatible: any existing a2ui config stays enabled; only an
explicit `a2ui: { enabled: false }` turns it off while keeping the rest
of the config (e.g. schema/catalog) in place.
https://claude.ai/code/session_01TYohiEJyhsU3mJS4jabdv6
Wire the legacy monolith scheduler's status writer with an explicit
writtenBy:"legacy" identity, correct the dual-writer dedupe comments
to describe the real upsert-collapse (and why it is not safe), stamp
the alert engine's synthesized cron outcome persisted:false honestly,
and align alert/orchestrator/probe test fixtures with the real
StatusWriter and OverlayWriteOutcome contracts.
Persist thrown driver errors to PB in the runDriverInputs catch,
carry WriteOutcome discriminators through the CLI summary (dropped
write counts with correct pluralization, no duplicate cause
clauses), and pin the runner/results behavior with StatusWriter
contract-typed stubs so writer contract drift is compile-checked
at the stub site.
Normalize padded projected keys to trimmed canonical form, skip
blank keys loudly, and replace ambiguous outcomes with explicit
discriminators: honest outage-skip/empty-projection semantics,
droppedCommError surfaced whenever the comm error misses the
aggregate row, trusted-negative duplicate preference scoped to
cell-vs-cell (no aggregate-row impersonation), and comm-error
identity asserts converted to discriminators so the consumer
cannot hot-loop.
Pin the writer-identity stamping, flip/foreign-write warn paths
(TTL re-warns, self-write memory cap eviction), date normalization
shapes, overlay write outcomes, idempotency latches, and error
classification against fail-loud fake-PB fixtures hardened against
silent divergence from real PocketBase behavior.
Add written_by/state_written_at columns (PB migrations) and stamp every
status write with a stable host-derived writer identity. The status
writer now detects cross-writer state flips and foreign writes (the
anti-dual-writer flap-comb defense), normalizes observedAt to PB-safe
RFC-3339 shapes before date-field writes, and classifies writer errors
honestly (401 auth vs 403 permission split, new pb_not_found reason).
## Problem
The shell docs had several visual and docs-rendering issues: cramped
responsive spacing, rough hero setup controls, off-theme reference
cards, missing standard reference page actions, and hand-rendered prop
tables.
## Why
The docs should feel consistent across the root docs and reference
areas, especially around page chrome, mobile layouts, and API reference
tables.
## Fix
- Refined shell docs spacing across mobile, medium, and sidebar-adjacent
layouts.
- Redesigned the hero setup controls and `Start using agents` dropdown.
- Updated reference overview cards to match the docs theme.
- Restored standard reference page actions, including markdown/open
options.
- Swapped reference prop rendering to Fumadocs `TypeTable`.
- Fixed reference markdown routes for generated reference pages.
Validation:
- `npm --prefix showcase/shell-docs run lint`
- `npm --prefix showcase/shell-docs run typecheck`
- `npm --prefix showcase/shell-docs run build`
- Pre-commit hook passed
- Browser checks for hero dropdown, reference actions, markdown route,
and TypeTable styling
## Summary
The beautiful-chat demo's "Calculator App (Open Generative UI)" pill
rendered a calculator whose "=" key was inert: the fixture's
`jsFunctions` called `Websandbox.connection.remote.evaluateExpression`,
a host-bridge function only the open-gen-ui-advanced demo registers —
beautiful-chat never does, so the call could never resolve. While fixing
it, review and live verification surfaced four more behavioral defects
in the same fixture family, all fixed here across all 18 integrations:
- **Self-contained evaluation**: `jsFunctions` now evaluates in-sandbox
via an allowlist-gated strict-mode `Function()` (digits/operators/`eE`
only; failures → `err`). No host bridge required.
- **Fixture shadowing**: the specific "with standard buttons" pair is
ordered before the generic "build a modern calculator" pair (aimock is
first-match-wins by load order), so the intended fixture actually serves
the pill.
- **Chained evaluation**: results in exponential notation (e.g.
`1.728e+18`) re-evaluate instead of wiping to `err` (regex allows `eE`).
- **Interleaved pills**: removed the thread-global `hasToolResult` gate
that made the calculator fall through to the live proxy (502) when
clicked after any tool-producing pill; toolCallId-anchored follow-ups
(ordered first) disambiguate legs instead.
- **Repeat clicks**: distinct `tool_call_id`s per click via
`sequenceIndex` variants + a non-sequenced fallback, fixing the
second-widget collapse (duplicate id collapsed both renders into one
slot, wiping state). Scoping caveats (per-X-Test-Id counters,
cross-integration co-increment, DEFAULT_TEST_ID degradation floor =
pre-fix behavior) are documented in the fixture comments and GOTCHAS.
Also: SUPERSEDED annotations on the unreachable recorded.json calculator
entries, GOTCHAS corrections (sequenceIndex scoping, hasToolResult
semantics, statelessness claim), and a routing-invariant unit test
pinning the entry ordering structurally and behaviorally for all 18
integrations (55 tests).
## Test plan
- [x] Local Playwright red-green on the built stack (langgraph-python):
broken "=" reproduced pre-fix; post-fix visual proof of render,
`7+8=15`, chained exponent math, calculator-after-dashboard interleave,
and two independent working widgets across repeat clicks
- [x] aimock version bisect (1.28.0/1.29.0/1.30.0) ruling out an aimock
regression before the fixture root-cause
- [x] `showcase/scripts` vitest suite: 51 files / 1899 tests green
(incl. new `calculator-fixture-routing.test.ts` 55/55, red-proofed via
mutation)
- [x] validate-parity 19/19; harness aimock-fixture-coverage 3/3;
oxfmt/oxlint/commitlint clean
- [ ] CI green on PR HEAD
Follow-ups (readonly-state matcher shadowing parity across 15
integrations, sibling-pill interleave gates, GOTCHAS accuracy pass,
aimock sequenceIndex scoping) are tracked in the showcase follow-up
ledger.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
- structural + behavioral pins for all 18 integrations (four ordering invariants; click walk
_001->_002->_003->_003 with follow-ups mirroring the server match/increment flow)
- fail-loud guards against loader error-swallowing and vacuous ordering passes
- full production pill text
- oxfmt applied
- SUPERSEDED annotations on unreachable recorded calculator entries (load-order shadowing is
the only guarantee; model gate is not a safety net)
- GOTCHAS sequenceIndex rewritten to per-X-Test-Id semantics with co-increment/eviction caveats
- hasToolResult paragraph corrected (omission = no gate, thread-global predicate)
- statelessness claim reconciled with sequence counters
- replace Websandbox host-bridge evaluateExpression (never registered in beautiful-chat) with
in-sandbox allowlist-gated Function() eval
- reorder specific calculator pair before generic (first-match-wins)
- allow exponential notation (eE) so chained evaluation of large results works
- drop thread-global hasToolResult gate that broke the pill after other tool-producing pills,
reorder toolCallId follow-ups before leg-1
- mint distinct tool_call_ids per repeat click via sequenceIndex variants + non-sequenced
fallback (fixes second-widget collapse)
- restore google-adk trailing newline
- document ordering invariants, gate tradeoffs, and sequence-counter scoping caveats in
fixture comments
Verified via local Playwright red-green (render, 7+8=15, chained exponent, interleaved pills,
repeat clicks).
## What
Documentation for the new Slack bot stack (`@copilotkit/bot`,
`@copilotkit/bot-ui`, `@copilotkit/bot-slack` — live on npm at 0.0.1),
plus the reference-picker restructure.
### 1. Slack quickstart — `/slack`
Flat **Slack** entry at the top of the **Platforms** sidebar section
(above React Native), with a flat slug matching `/react-native`. Zero →
working bot:
- Create the Slack app **from the checked-in manifest**
(`examples/slack/slack-app-manifest.yaml`), with a callout to delete the
two `assistant:write` / `assistant_thread_started` lines if present
(Slack's validator rejects them without an `assistant_view` block;
conditional phrasing stays correct once `tyler/slack-example-standalone`
lands)
- Tokens (`xoxb-` from OAuth & Permissions after install; `xapp-`
app-level token with `connections:write`), Socket Mode = no public URL
- Gotcha callouts: `/invite` before `app_mention` fires; mention
autocomplete matches the bot **user's** Default username (propagates on
reinstall; full uninstall→reinstall rotates the `xoxb-` token); slash
commands silently dropped unless declared in the app config
- One-file bot (`createBot` + `slack()` + `onMention` →
`thread.runAgent()`, run with `tsx`), then interactive JSX (Button with
inline `onClick`), then `/agent` slash command via `runAgent({ prompt
})`
- ESM-only packaging + in-memory ActionStore restart caveat, and the
production bot/agent split via `AGENT_URL` (mirrors `examples/slack`)
### 2. "Bots" tab in the reference SDK picker
Per-symbol reference modeled on the React (V2) pages (Overview →
Import/Signature → PropertyReference props → Usage → Behavior →
Related), with the sidebar **grouped by package** — each package
separator carries its mark (CopilotKit kite / Slack logo):
- **`@copilotkit/bot`** (separator + kite mark) with collapsed
kind-folders:
- *Components* (13): Message, Header, Section, Markdown, Fields,
Context, Actions, Button, Select, Input, Image, Divider, Table — each
with props, usage, and its Block Kit mapping/budget
- *Functions* (5): createBot, defineBotTool, defineBotCommand,
renderToIR, bind
- *Classes* (1): Thread · *Types* (3): ActionStore, BotNode,
InteractionContext
- **`@copilotkit/bot-slack`** (separator + Slack mark) with a closed
**Core** folder: `slack()` (the adapter — `/reference/bot/slack`),
renderBlockKit (mapping + SLACK_LIMITS budgets), markdownToMrkdwn,
defaultSlackTools, defaultSlackContext, SanitizingHttpAgent
- Wiring follows the in-file recipe (`REFERENCE_VERSIONS += "bot"`, new
`functions`/`slack` subdirs, selector label, Bots card on `/reference`)
plus a bot-specific `buildBotPageTree` for the package-grouped sidebar
### 3. Picker labels + stale SDK pages
- Labels renamed to **React (V2)** / **React (V1)** (Core unchanged)
- Deleted the retired `/reference/sdk/` pages (LangGraph SDK ×2, CrewAI
SDK, CrewAIAgent, LangGraphAGUIAgent, Remote Endpoints);
search/sitemap/llms indexes are generated from the content tree, so they
de-index with the deletion; `sdk` dropped from the v2 subdir list; the
one inbound link retargeted to its `/reference/v1` copy
## Verification
- Every API name verified against package source (`src/index.ts`, type
declarations), not READMEs — caught two README-only patterns that don't
compile (`onClick` one-liners returning `MessageRef`; in-process
`BuiltInAgent` blocked by the `@ag-ui/client` 0.0.53/0.0.56 nominal
split, hence the loopback AG-UI pattern in the quickstart)
- All quickstart/reference snippets assembled into a scratch `.tsx`
project and **typechecked clean** against the built workspace packages
(strict, `jsxImportSource: "@copilotkit/bot-ui"`)
- `npm run build` (production) ✅ · `npm run typecheck` ✅ ·
`oxlint`/`oxfmt --check` on touched app files ✅ · internal link audit:
every `/reference/bot/*` and `/slack` link resolves ✅ · old routes
(`/reference/sdk/*`, `/platform/slack`,
`/reference/bot/functions/slack`) 404, new routes 200 on the dev server
✅
- **Third-party review round**: two independent reviewer agents — a
cold-read new-user pass on the quickstart (verdict: ~25–30% verbose →
trimmed ~26%, callouts 7→4, paste-along ambiguities fixed) and a
source-level correctness audit of all 29 reference pages (~280 claims; 8
errors found and corrected, incl. honest wording for action expiry, what
crosses the wire on a click, Input’s block-level placement, and bind()’s
v1 cold-path caveat). Two of the audit findings are SDK bugs, filed
separately: Input-inside-Actions silently dropped by the Slack renderer,
and bind() `boundArgs` written to the ActionStore but never consumed on
rehydration.
- `npm test`: 90/91 — the 1 failure (`framework-overview.test.tsx`,
"Start the quickstart" CTA copy) **pre-dates this branch** (hero copy
changed in #5248) and touches no file in this diff; flagged separately
## Reviewer checklist
- [ ] `/slack` — try the quickstart against a real workspace (manifest
paste, tokens, `npx tsx bot.tsx`)
- [ ] Sidebar: **Platforms** lists Slack (flat, above React Native);
reference picker shows React (V2) / React (V1) / Core (TypeScript) /
Bots
- [ ] Bots tab sidebar: `@copilotkit/bot` separator (kite mark) with
closed Components/Functions/Classes/Types folders, then
`@copilotkit/bot-slack` separator (16px Slack mark) with a closed Core
folder of the six adapter entries
- [ ] Spot-check API accuracy: Button, slack() (`/reference/bot/slack`),
Thread, ActionStore
- [ ] Manifest callout wording still correct if
`tyler/slack-example-standalone` merges first
- [ ] Comfortable deleting the six `/reference/sdk/` pages with no
redirects (they 404 now; only inbound link was retargeted)
- [ ] OK with the quickstart's single-process loopback pattern
(BuiltInAgent served over AG-UI on :8200) until the `@ag-ui/client`
version split is healed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
- New Platforms entry: /platform/slack quickstart — manifest-based app
creation, Socket Mode tokens, minimal createBot bot run with tsx,
interactive JSX with inline onClick, slash commands, production split
- New "Bots" SDK tab in the reference picker with per-symbol pages for
@copilotkit/bot, @copilotkit/bot-ui, and @copilotkit/bot-slack
(Components / Functions / Classes / Types)
- Rename reference picker labels to React (V2) / React (V1)
- Remove the retired /reference/sdk pages (LangGraph/CrewAI SDK,
Remote Endpoints); search/sitemap/llms indexes derive from the
content tree, so they de-index with the deletion
- Retarget the one inbound link to its /reference/v1 copy
Co-Authored-By: Claude <noreply@anthropic.com>
Hotfix for the deployed Kite bot: every Linear-MCP run fails with
```
Agent error: Cannot set property protocolVersion of #<StreamableHTTPClientTransport> which has only a getter
```
**Root cause** — `@copilotkit/runtime@1.59.5` declares `@ai-sdk/mcp:
^1.0.21`. The standalone example lockfile (new in #5366) resolved
**1.0.47**, which (unlike the workspace-tested **1.0.21**) assigns
`transport.protocolVersion` after the server's initialize response — a
getter-only property on `@modelcontextprotocol/sdk@1.29.0`'s transport.
Verified by source diff of both published tarballs; the assignment
exists only in 1.0.47 (`dist/index.js:1950`).
**Fix** — `pnpm.overrides` pin to 1.0.21 in the example + regenerated
standalone lockfile (resolution verified). Workspace installs are
governed by the root manifest and unaffected.
**Upstream** — this combination breaks *any* fresh install of
`@copilotkit/runtime@1.59.5` that uses MCP; a proper compat fix in the
runtime package is filed separately.
Merging this auto-deploys the hosted bot (watch-path on
`examples/slack/**`) — live verification on Kite follows.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
@copilotkit/runtime@1.59.5 declares @ai-sdk/mcp ^1.0.21; fresh installs
resolve 1.0.47, whose MCP client assigns transport.protocolVersion after
the server's initialize response — a getter-only property on
@modelcontextprotocol/sdk@1.29.0's StreamableHTTPClientTransport. Every
MCP-enabled run then fails with:
TypeError: Cannot set property protocolVersion of
#<StreamableHTTPClientTransport> which has only a getter
The workspace-tested resolution was 1.0.21 (no such assignment — verified
by source diff of the published tarballs). Pin it via pnpm.overrides until
@copilotkit/runtime supports the newer client line.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Closes [OSS-299](https://linear.app/copilotkit/issue/OSS-299).
Follow-up to #5248 (already merged).
## Problem
The `hero_command_copied` PostHog event added in #5248
(`showcase/shell-docs/src/components/hero-start-commands.tsx`) carries
no surface discriminator. `HeroStartActions` renders on **both** the
home hero and **every** framework landing hero:
- The **create** card embeds the framework in `command` (`--framework
langgraph-js`), so it's recoverable.
- The **onboard** card's command (`npx copilotkit@latest skills
onboard`) is byte-identical on every page — so onboard copies **cannot**
be attributed to a surface from the event alone.
Every sibling event in shell-docs already carries a "where" property —
`cli_command_copied` → `location: window.location.pathname`, the nav
events → `location`, `markdown_copied`/`open_in_llm_clicked` → `path`.
`hero_command_copied` was the only one without one.
## Fix
Add `location: window.location.pathname` to the `hero_command_copied`
payload, mirroring the `cli_command_copied` event the global
`<CopyTracker>` already emits for the same copy (verified: it
monkeypatches `navigator.clipboard.writeText`, which the hero calls).
The two paired events now join cleanly on the same dimension. Guarded
for SSR (`typeof window !== "undefined"`) to match the sibling.
## Test
Adds a colocated source-assertion guard test. shell-docs vitest runs in
the `node` environment (no jsdom/RTL), so this follows the suite's
existing convention (`readFileSync` + assertions, like
`brand-nav.test.tsx`) rather than introducing a behavioral render
harness.
```
✓ src/components/__tests__/hero-start-commands.test.tsx (3 tests)
```
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The Slack example is a **consumer** of the packages we shipped today,
but its `workspace:*` deps forced every deployment to rebuild the
monorepo (and fight nx inside builders — exit-130 city). This PR makes
the example what an example should be: installable and runnable anywhere
with zero monorepo context.
## Changes
- **`workspace:*` → published ranges** (`@copilotkit/bot*` `~0.0.1`,
`@copilotkit/runtime` `^1.59.5`). In-repo it now installs from the
registry like any user's project; `tsx` runs the source directly — there
is no build step anymore, anywhere.
- **Drop the private `@copilotkit/typescript-config` devDep**, inlining
the base compiler options into the example's `tsconfig.json` (identical
`tsc` behavior, verified).
- **Standalone `pnpm-lock.yaml`** inside `examples/slack` so isolated
installs (Railway `rootDirectory`, users copying the folder) are
reproducible. Root workspace installs ignore it.
- **Slack manifest fixes** (both variants): remove the `assistant:write`
scope + `assistant_thread_started` event — Slack's manifest validator
rejects them without an `assistant_view` feature block, and the bot
doesn't implement that surface; add the `/triage` slash command the bot
actually registers (previously had to be added by hand).
## Verification
- `slack-example` tests: **38/38** against the published packages
- Direct `tsc --noEmit`: clean
- Clean-room (gitless snapshot, isolated dir): install from registry →
runtime boots to `listening`, bot boots to a loud Slack auth failure on
dummy tokens (the correct failure)
- Live deploy validation on Railway follows this merge
(rootDirectory=/examples/slack, no build command)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Pin alignment fixes 9 validate-pins FAILs; ratchet the drift baseline
count and hash accordingly. Also tighten the _comment: document the exact
hash recipe (SHA-256 of the stderr-only [FAIL] lines, LC_ALL=C sort -u)
and correct baselineDemoCount semantics (exact expected demo count per
package; deviation either direction warns).
Align showcase integration requirements.txt files (strands,
langgraph-fastapi, langgraph-python, pydantic-ai, google-adk,
crewai-crews) to the fleet pin standard, including an accurate
typing_extensions comment in crewai-crews and a trailing newline in
langgraph-python.
Replace floating "beta" dist-tags with exact versions for @ag-ui/mastra,
@mastra/{client-js,core,libsql,memory}, and mastra in both the examples
and showcase mastra packages. Showcase mastra also raises its zod floor
^3.24.0 -> ^3.25.0. The examples mastra package additionally carries the
fleet-wide @ag-ui/client 0.0.55 bump and single-tree overrides here, since
its manifest mixes both changes.
Bring the starter agents' Python dependency pins (pyproject.toml + uv.lock
for adk, langgraph-fastapi, langgraph-python, pydantic-ai, strands-python;
requirements.txt + docker override for crewai-crews) in line with the
showcase fleet pin standard.