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.
The model answered 'show me the unapproved transactions' with one
showAndApproveTransactions call per pending transaction (parallel tool
calls). Parallel calls to the same useHumanInTheLoop tool wedge the
render at inProgress, nobody can respond, and the thread is then
poisoned — every later run fails with 'Tool results are missing for
tool calls …'. Make the tool take a comma-separated id list and
instruct the model to call it exactly once; the renderer's existing
string .includes() filter was already written for a combined call.
(An array schema renders an empty tool slot — react-core issue — so
the param stays a string.)
Verified live in OSS mode: single call streams complete args +
RUN_FINISHED, the approval card renders with per-row Approve/Deny,
deny fires the recording vignette (data-recording=true) and POSTs
/annotate; over-limit approve is rejected by the server gate as
designed. In Intelligence mode the BFF /annotate path records 200.
The unavailable-actions agent context had an unconditional "the user does
not have permission to perform these actions" description. For Admins the
list is empty, and the model read the menacing description plus "[]" as a
blanket prohibition — refusing showAndApproveTransactions and every other
gated tool even though they were forwarded with the run. Reframe the
description so an empty list explicitly means no restrictions and refusals
are only allowed for listed actions.
Verified live in Intelligence mode: before, the agent answered "you don't
have permission" as Admin; after, it calls showAndApproveTransactions
(wire capture shows the corrected context and the tool call).
## 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>
scripts/self-learning-smoke.mjs proves the banking demo's recording seam
end-to-end against a running Intelligence backend: posts four teaching
actions through the demo BFF /api/copilotkit/annotate (the platform
requires UUID clientEventIds), optionally runs one sl-worker sweep when
INTELLIGENCE_REPO is set, and asserts the distilled vendor policy reads
back through the platform /mcp knowledge tool. Wired as the
test:self-learning package script and documented in the README.
Verified live: PASS 6/6 against Intelligence @ mme/learn-from-user-activity
(records as rows 13-16, sweep editCount=0 steady-state, recall returns the
pre-cleared vendor policy).
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
next lint was removed in Next 16, so the demo's lint script failed before
linting anything. Switch to eslint . with a flat eslint.config.mjs built on
eslint-config-next's native flat exports (same shape as the other Next 16
example apps), and fix the findings the new react-hooks rules surfaced:
- actions.ts / team/actions.ts: wrap mount fetches in an async IIFE so
set-state-in-effect can see the setState calls are asynchronous
- auth-context: derive currentUser from selection ?? team[0] instead of
syncing state in an effect
- use-theme: lazy-init theme from localStorage (SSR-guarded) and apply the
DOM class in an effect keyed on theme; hoist applyTheme to module scope
- threads-drawer: copy timeout maps to locals inside the effect so cleanup
does not read refs that may have changed
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
The 'Known gap' section predated the recording fix: the hook exists as
useLearnFromUserActionInCurrentThread and record-user-action.ts is now a
real adapter. Document the /annotate flow and the backend route
requirement (/connector/annotate) instead.
Dashboard, copilot chat panel, and the learning-mode recording vignette
(the violet glow shown while an officer demonstration is being recorded).
PNGs are LFS-tracked per the repo .gitattributes.
Replace the no-op recorder shim with a real adapter over the v2 hook
(renamed from useRecordUserActionInCurrentThread in #4839/#5073): call-site
{title, description, previousData, newData, metadata} maps to the hook's
{title, description, data: {previous, next, metadata}}, with threadId
sourced from the surrounding chat config provider.
Add an optional INTELLIGENCE_USER_ID / INTELLIGENCE_USER_NAME override to
identifyUser for backends that enforce org membership of the asserted user
(e.g. a local Intelligence stack with seeded fixture users); the default
remains the derived northwind-<role> identity. Documented in the README.
Verified end-to-end against Intelligence @ mme/learn-from-user-activity
(PUT /connector/annotate): record -> cpki.sl_annotations -> sl-worker
distill -> /project knowledge file -> recall via /mcp. Recording requires a
backend that exposes /connector/annotate; the OSS default path
(InMemoryAgentRunner, no INTELLIGENCE_* env) is unchanged.
## 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>
pkg-pr-new publishes snapshot builds to pkg.pr.new, not the npm
registry, and uses no environment-scoped secrets or variables. The
job runs on every push/PR touching packages/**, so the npm
environment's tightened deployment-branch policy (main, canary/*,
release/publish/*) would block every snapshot publish. Removing the
environment association is a prerequisite for the policy.
actionlint over stable-release.yml, publish-release.yml, canary.yml,
and itself; shellcheck (severity warning) over scripts/release shell
scripts; and the release-scope-dropdown-sync job running
verify-release-scope-dropdowns.sh. Scope intentionally narrow to the
release pipelines to avoid drowning unrelated changes in lint noise.
Ported from ag-ui-protocol/ag-ui.
canary / publish: a workflow_dispatch orchestrator that mirrors the
dispatched ref to a unique short-lived canary/<slug>-<run_id>-<attempt>
branch via the GitHub API (devops-bot App token, app-id 1108748),
dispatches publish-release.yml on that ref with mode=prerelease, waits
for the delegated run (gh run watch + explicit conclusion check), and
deletes the ref afterward.
It does NOT publish to npm itself — publish-release.yml holds the
single npm OIDC trusted-publisher binding. Failure paths covered:
suffix validated before any side effect, ref kept when a dispatched
run was never located, ref deleted when the dispatch itself failed,
status-gated deletion + fresh cleanup token for cancellation/timeout
(90-min ceiling exceeds the 1h App-token TTL and queueing behind
publish-release's global concurrency group).
Ported from ag-ui-protocol/ag-ui PR #1914 with cpk adaptations
(scopes from release.config.json; dry_run -> dry-run input mapping).
Compares the workflow_dispatch scope choice dropdowns in
publish-release.yml, stable-release.yml, and canary.yml against the
authoritative .scopes keys in release.config.json, failing CI on drift.
Also validates that every explicitly-named arm in publish-release.yml's
notify-job npm-url case statement is a valid scope (catch-all makes
full coverage unnecessary). Parsers fail loud and distinct on shape
changes (anchored case detection, loose-vs-strict cross-check,
zero-options and zero-block guards) rather than silently passing.
Ported from ag-ui-protocol/ag-ui (PR #1914 wiring); config lives at
the repo root in CopilotKit.
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)