## What
Updates the README to reflect CopilotKit's expansion beyond React:
- **New "Works With Your Stack" section** — platform table for
React/Next.js, Angular, Vue, and React Native
- **New "Beyond the Browser" section** — Slack & Microsoft Teams support
with an early access CTA
- Tagline updated to "on any framework, on any surface"
- "Chat UI" feature bullet made framework-neutral (was "React-based")
- useAgent section no longer anchors to the legacy useCoAgent hook
- AG-UI section: LangGraph → LangChain, added Mastra and PydanticAI to
named integrations
- New "How it works" bullet: one agent across web, mobile, and chat
platforms
## Before merging (draft)
- [ ] Replace `EARLY_ACCESS_FORM_LINK` placeholder with the real early
access form URL
- [ ] Point Angular / Vue / React Native quickstart links at their
framework-specific docs pages
- [ ] Confirm status labels (GA vs Supported vs Beta) for Angular / Vue
/ React Native
- [ ] Confirm `npx copilotkit create -f` accepts the new framework
values
Draft content also lives in Notion:
https://app.notion.com/p/copilotkit/New-GitHub-README-3763aa38185280788920fc81780c8ad6
## Summary
Follow-up to #5256 (the concurrent-paged initial-fetch perf fix). Trims
the live-status payload and hardens the realtime/SSE path of the
showcase Coverage dashboard.
- **Trim initial projection** — drop the heavy `signal` field from the
initial PocketBase fetch via a compiler-guarded `STATUS_LIST_FIELDS`
projection + `skipTotal` + length-based bounded-concurrency pagination.
Consumers adapted: `CellDrilldown` lazy-loads `signal` on demand
(genuine failures only), `DiscoveryAuthBanner` self-fetches detail
(identity-tagged cache), legacy `LiveBadge` degrades gracefully when
`signal` is absent.
- **Harden the realtime path** — `flushPending` teardown guards,
keyless-delete `id→key` buffer collapse (per-row last-write-wins, pure
ref+effect mirror), SSE-delta signal-presence upsert, and a `degraded`
flapping flag (clears on heartbeat success, resets on terminal error).
- **Grid/UX** — a `stale` (muted, non-authoritative) tally state
distinct from the no-rows loading state, an amber-chip/green-D5
dimension-classification fix, and `degraded` surfaced in the header
`LiveIndicator` (offline outranks degraded).
## Test plan
- [x] `tsc --noEmit` clean
- [x] `vitest run` — 879 passed / 1 skipped (56 files); +63 new
behavioral tests across the changed areas (real-SDK socket tests for
fetch/autocancel/lazy-signal, fake-timer tests for the flapping detector
and reconnect chain, exhaustive resolveCell truth-tables)
- [x] `next build` — compiled successfully, 5/5 static pages
- [x] oxfmt + oxlint clean
- [ ] CI green
- [ ] Visual verification on staging after deploy
## Known follow-ups (deferred — pre-existing / out-of-subject, not
introduced by this PR)
These were surfaced during review, verified pre-existing on `main` (or
unreachable in the shipping config), and intentionally not fixed here to
keep the PR scoped:
- Column-header tally counts deprecated features hidden from the grid
body (`computeColumnTally` iterates the full `features` list while the
body renders `visibleFeatures`) — pre-existing, header/body over-count
identical before and after. Strong candidate for a dedicated follow-up.
- `resolveCell` rollup does not suppress amber/degraded cells when
`connection === "error"` (only green is suppressed) — pre-existing
precedence.
- `formatTooltip` offline branch renders "degraded since
<transitioned_at>" for a staleness-downgraded green row.
- `LiveBadge` arms the `useLastTransition` fetch for
staleness-downgraded amber badges (no `isGenuineFailure` filter, unlike
the drilldown).
- `CellStatus` passes the raw `featureId` as the CV-badge transition
key, so mapped D5 families query a non-existent history row.
- Cosmetic: `extractSignalFields` renders `{}` for an empty-object error
field; `degraded` lacks an effect-cleanup reset on the
(production-unused) `dimension` param path; minor comment-accuracy nits
(reconnect backoff tiers, rollup-precedence JSDoc).
The check-config-files job blocked the strands-crm showcase PR
(examples/showcases/strands-crm/frontend/next.config.ts was not in
the build-config allowlist). Adding it next to strands-file-analyzer.
## Problem
CLI starters for Mastra, Agno, PydanticAI, AWS Strands, Google ADK, MS
Agent Framework, and LlamaIndex fail on `npm run dev` with:
```
Error: dependency failed to start: container copilotkit-intelligence-intelligence-1 is unhealthy
intelligence-1 | error: database "intelligence_app" does not exist
```
## Root cause
The overlay compose relied on a bind-mounted `docker/init-db/` script to
create `intelligence_app`, but the CLI's Intelligence activation copies
**only** `docker-compose.yml` into scaffolded projects. The mount source
never exists there, so Docker creates it as an empty directory, postgres
initializes with only the default DB, and the composite's migrations
fail.
`langgraph-python-threads` was unaffected because its template ships its
own compose + `docker/init-db/` in-repo.
## Why it keeps biting internal testers
The compose project name is fixed (`copilotkit-intelligence`), so
**every starter on a machine shares one `postgres-data` volume** — and
postgres only honors `POSTGRES_DB`/init scripts on first init of an
*empty* volume. One broken run poisons the volume for every subsequent
starter, regardless of framework.
## Fix (self-contained + self-healing)
- `POSTGRES_DB: intelligence_app` and drop the `docker/init-db` bind
mount + script (the shadow DB it also created is only used by repo-local
dev tooling, never by the composite)
- Add an idempotent `provision-db` one-shot (same pattern as the
existing `provision-user`) that creates `intelligence_app` when missing
— this heals already-poisoned volumes on the next `docker compose up`,
with no manual `down -v`
- Gate `intelligence` on `provision-db` completion; align the postgres
healthcheck dbname
Because the CLI fetches this overlay live from `main` at scaffold time,
merging this fixes every CLI version in the wild immediately — no CLI
release needed.
## Verification
Tested with real Docker on isolated compose projects:
1. **Poisoned volume** (reproduced by running the old compose revision
with the empty `init-db` dir the CLI leaves behind → volume with no
`intelligence_app`): new compose → `provision-db` exits 0, migrations
run, composite **Healthy**, `up -d --wait` exits 0
2. **Fresh volume**: DB created via `POSTGRES_DB`, `provision-db`
no-ops, composite **Healthy**
3. **Idempotency**: second `up -d --wait` on a running stack exits 0
🤖 Generated with [Claude Code](https://claude.com/claude-code)
## Why
New users are still finding cloud.copilotkit.ai even though they
shouldn't be. An org-wide audit found the live funnels; this PR closes
every source in this repo.
## What changed
Replaced all **user-facing web links** to `https://cloud.copilotkit.ai`
with `https://dashboard.operations.copilotkit.ai` (the same destination
the copilotkit.ai marketing CTAs already use):
- **Live docs pages** (`docs/` + `showcase/shell-docs/`) —
premium/observability/threads/oss-vs-enterprise/intelligence-platform
pages, integration quickstarts/tutorials, V1 reference pages, shared
snippets
- **`LinkToCopilotCloud` component** (both copies) — was routing through
`go.copilotkit.ai/copilot-cloud-button-docs` → cloud sign-in; now points
at the dashboard directly
- **README** — the `?ref=github_readme` CTA (label updated to "Try the
Enterprise Intelligence Platform")
- **Example READMEs** (`examples/v1/*`, showcases)
- **Shipped package code** so future releases stop reseeding the
problem: `console-styling.ts` key warnings, `usage-banner.tsx`,
`developer-console-modal.tsx`, V2 `license-warning-banner` (React +
Vue), provider JSDoc
## Deliberately untouched
- `api.cloud.copilotkit.ai` endpoints (`COPILOT_CLOUD_API_URL`,
check-for-updates, telemetry tests) — existing cloud customers depend on
these
- "Copilot Cloud" prose/product naming in docs copy — link targets only;
copy rewrite is a separate editorial pass
## Out of repo (follow-ups, not in this PR)
- `go.copilotkit.ai/GetStarted` still 302s to cloud — zero code
references org-wide, so traffic is from old emails/posts; needs
repointing at the shortener
- Already-published npm versions carry the old links forever — only a
cloud-side signup gate closes that vector
## Verification
- `nx run-many -t test,build -p @copilotkit/shared
@copilotkit/react-core @copilotkit/vue` ✅
- `@copilotkit/sqlite-runner:test` ✅ (failed initially from a stale
Node-20 `better-sqlite3` binary in the fresh worktree, unrelated to this
change)
- Zero remaining non-`api.` `cloud.copilotkit.ai` references in
docs/packages/examples
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The activation overlay's docker-compose.yml relied on a bind-mounted
docker/init-db script to create the intelligence_app database, but the
CLI copies only docker-compose.yml into scaffolded projects. The mount
source never exists there, Docker creates it as an empty directory,
postgres initializes without intelligence_app, and the composite's
migrations fail: 'database "intelligence_app" does not exist' →
'dependency failed to start: container ...intelligence-1 is unhealthy'.
Make the compose file self-contained:
- Set POSTGRES_DB: intelligence_app (drop the init-db bind mount and
the now-unused init script; the shadow DB it also created is only
used by repo-local dev tooling, never by the composite).
- Add an idempotent provision-db one-shot that creates the database
when missing. POSTGRES_DB only applies on first init of an empty
volume, and the volume is shared across all scaffolds via the fixed
compose project name — so machines that already hit the bug have a
data volume without the database. The one-shot heals those on the
next 'docker compose up' with no manual 'down -v'.
- Gate the composite on provision-db completion instead of postgres
health, and align the postgres healthcheck dbname.
New users were still discovering cloud.copilotkit.ai through docs pages,
the README, example READMEs, and in-app banners/console messages. Replace
all user-facing web links with dashboard.operations.copilotkit.ai (the
destination the marketing-site CTAs already use). Functional API endpoints
(api.cloud.copilotkit.ai) are deliberately untouched since existing cloud
customers depend on them.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
## Why
The langgraph-python template's `uv.lock` was stale: it locked
`copilotkit 0.1.87` / `ag-ui-langgraph 0.0.33` while `pyproject.toml`
pins `copilotkit==0.1.93`. Because the lock didn't match, every
scaffold's `uv sync` discarded it and re-resolved fresh against PyPI
latest.
That silent re-resolution is how fresh `copilotkit init` scaffolds
(langgraph-py / a2ui / opengenui) broke today: they picked up
`ag-ui-langgraph 0.0.39`, which imported a then-unpublished
`ag-ui-a2ui-toolkit` symbol and failed at import time (`ImportError:
cannot import name 'run_a2ui_generation_with_recovery'`). The other
python templates (langgraph-fastapi, langgraph-python-threads,
strands-python) survived precisely because their locks are in sync.
## What
Regenerated `uv.lock` with `uv lock` so it matches `pyproject.toml`. It
now locks the fixed pair published by the ag-ui maintainers:
`ag-ui-langgraph 0.0.40` + `ag-ui-a2ui-toolkit 0.0.2` (verified to
import cleanly and load the template graph). With the lock in sync,
scaffolds become deterministic — a future broken upstream release can no
longer break `copilotkit init` until the lock is deliberately updated.
Tracking the upstream release-process issue in OSS-256.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
## What
Move the langgraph A2UI demos + docs off alphas now that the stable
packages are out.
### Deps (commit 1)
- `copilotkit` `0.1.94a3` → **`0.1.94`** (langgraph-python,
langgraph-fastapi)
- `@copilotkit/*` `1.59.2` → **`1.59.4`** + `@copilotkit/sdk-js`
`1.59.3-alpha.3` → **`1.59.4`** (langgraph-typescript + agent)
- **Dropped the `@ag-ui/langgraph` override** —
`@copilotkit/runtime@1.59.4` now carries `@ag-ui/a2ui-middleware@0.0.6`
(the `injectA2UITool` forward) + `@ag-ui/langgraph@0.0.37` (the state
surface). Locks regenerated; `npm ci` in sync.
### Docs (commit 2)
- Rewrote the **dynamic-schema** A2UI pages (langgraph + deepagents +
generic) for the middleware flow:
- **prebuilt agent** → just add `CopilotKitMiddleware`
- **graph agent** → wire `get_a2ui_tools`
- `injectA2UITool` is the single on/off switch
- Removed the stale hand-rolled `render_a2ui`/`generate_a2ui` +
`a2ui_prompt` framing; corrected streamed op names
(`createSurface`/`updateComponents`/`updateDataModel`).
## Why
The merged middleware PR made A2UI opt-in via the forwarded
`injectA2UITool` flag; the showcase was pinned to alphas + a transitive
override, and the docs still described the pre-middleware design.
Our previous doc site had a fumadocs/shadcn theme that was a bit
hodge-podge. This brings all of it into one clean and visually appealing
design. The border radii are standardized, colors are standardized and
bunch of passes for mobile/tablet have been done. An added bonus is that
the header nav has been redone to feel more natural to the eyes.
<img width="1850" height="1256" alt="Screenshot 2026-06-05 at 7 48
00 AM"
src="https://github.com/user-attachments/assets/0c6032f2-e406-4e51-9c31-d69a9d258d61"
/>
Applies the updated shell-docs theme treatment to the overview cards, sample tabs, framework selectors, hero command controls, and Copilot Cloud CTAs.
Call-site enumeration:
- FrameworkSelector/FrameworkTabs/IntegrationGrid changes stay on the docs landing and framework overview surfaces that already own those controls.
- OpsPlatformCTA and LinkToCopilotCloud keep their existing call sites while switching to shared chrome variables.
Refreshes the shell docs chrome around the shared theme tokens, announcement banner, desktop and mobile navigation, search trigger, theme toggle, and sidebar footer actions.
Call-site enumeration:
- PrimaryDocsTabs: rendered by MobileTopNav for tablet header tabs and ShellDocsLayout for mobile sidebar tabs.
- MobileSidebarFooterTalk: rendered by ShellDocsLayout sidebar.footer and hidden outside mobile/tablet sidebar usage via responsive classes.
- INTELLIGENCE_CTA_HREF and TALK_TO_ENGINEER_HREF: exported from BrandNav and reused by BrandNav/MobileSidebarFooterTalk so CTA destinations stay centralized.
Northstar AI CRM — a full-featured agentic sales CRM for an enterprise
hardware seller, built with CopilotKit, the AG-UI protocol, and a
TypeScript Strands agent (@strands-agents/sdk + @ag-ui/aws-strands).
The first TypeScript Strands example under examples/.
Highlights:
- Agentic canvas: tool calls render on the workspace — quote approval
opens a quote page; analyze_team and generate_weekly_report open
dedicated report pages; frontend tools navigate the workspace.
- Generative UI cards, human-in-the-loop follow-up approval, and a live
STATE_SNAPSHOT that syncs a SQLite CRM store with the board,
dashboard, and report pages.
- Dashboard, pipeline (Kanban), products, team, and reports surfaces.
Self-contained under examples/showcases/strands-crm with an agent/ +
frontend/ split and a concurrently dev script; listed in
examples/README.md.
## Summary
Makes the `examples/showcases/banking/` SaaS demo customer-ready by
migrating it to **CopilotKit v2** and polishing it into a credible,
reliable reference. Closes the non-memory gaps from FOR-133's assessment
(FOR-138).
- **v2 migration**: v2 Hono runtime route (`BuiltInAgent` +
`createCopilotHonoHandler` + `InMemoryAgentRunner`), `CopilotKit`
provider + `CopilotPopup`, hooks moved to `@copilotkit/react-core/v2`
(`useAgentContext`, `useHumanInTheLoop`, `useComponent`, Zod params), on
`workspace:*` packages.
- **File-backed data store**: domain data in `src/data/seed.json` behind
a typed `src/lib/store.ts` (in-memory, resets to seed on restart). Clean
seam left for the memory track (FOR-137).
- **Credible identity + data**: Northwind Finance / Alex Morgan /
`@northwind.example`, refreshed transaction dates + future card
expiries, `Intl` currency formatting.
- **Dropped** the SQL page + fake-MSA RAG feature (and committed
ServiceNow secret) — focused fintech story.
- **Framework/build**: Next 16 async route `params`, Tailwind v4 (so the
v2 stylesheet imports normally), correct `next`/`react` versions, single
lockfile, accurate v2 README.
- **Tests**: LLM-free Playwright smoke test (also fails on
hydration/uncaught errors).
## Verified live (real OpenAI key)
Full golden path works end-to-end: chat renders → "show transactions for
card 4242" renders the generative-UI list → "add a card" → HITL approval
card → Approve → new card appears in the grid. 0 console errors. Build +
typecheck + smoke test green; no committed secrets.
Three v2 chat-rendering bugs were found and fixed by running it live:
use the full `CopilotKit` provider (not the low-level
`CopilotKitProvider`, which omits `ThreadsProvider`); set
`useSingleEndpoint={false}` to match the multi-endpoint route; and use
`useComponent` with a `deps` array for display-only generative UI
(avoids a stale-closure empty render).
## Non-goals (deliberately out of scope)
- Real auth.
- Conversation threads + long-term/self-learning memory → FOR-137.
- Deleting the duplicate `enterprise-brex` demo + repointing its deploy.
## Test plan
- [ ] `pnpm --filter demo-saas-copilot build` succeeds
- [ ] `pnpm --filter demo-saas-copilot exec tsc --noEmit` clean
- [ ] `pnpm --filter demo-saas-copilot test:e2e` passes
- [ ] With `OPENAI_API_KEY` set: run the golden path (transactions
gen-UI, add-card HITL → approve → grid update)
## Known minor follow-ups
- Removing deprecated `showDevConsole` surfaces the v2 Web Inspector /
announcement banner.
- Newly-added cards get a near-term generated expiry.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
It was left at false while fastapi/typescript are true. Under the opt-in
A2UI model false means no tool is injected, so the python demo rendered
no surfaces (and the docs code-tab showed no injectA2UITool). Set true to
match the other langgraph integrations.
Treat `signal` as optional on legacy LiveBadge rows (neutral 'unknown' marker
when absent), so the trimmed initial projection cannot misrender or throw.
Fetch `signal` on demand for genuinely-failing badges (excluding staleness-
downgraded greens via fail_count), with per-badge loading/error resolution that
distinguishes in-flight, partial-failure (requested-but-absent), and resolved
states. Injection-safe pb.filter OR query; object-valued fields render as JSON.
Banner visibility still derives from projection-safe key+state on the live rows;
detail copy self-fetches `signal` (via pb.filter placeholders, page size = key
count) only when omitted by the trimmed projection, with an identity-tagged cache
(id + transitioned_at) that won't serve a stale signal across content changes.
Thread a `stale` flag (muted, non-authoritative counts during reconnect-with-rows,
distinct from the no-rows loading state), fix the amber-chip/green-D5 cell to
classify into the health dimension, and surface the hook's `degraded` flag in the
header LiveIndicator (offline outranks degraded). Wire `degraded` from
useLiveStatus through to FeatureGrid in dashboard-page.
Drop the heavy `signal` field from the initial PocketBase fetch via a
STATUS_LIST_FIELDS projection + skipTotal + length-based bounded-concurrency
pagination, restoring fast first paint. Harden the realtime path: flushPending
teardown guards, keyless-delete id->key buffer collapse (last-write-wins),
SSE-delta signal-presence upsert, and a `degraded` flapping flag that clears on
heartbeat-success and resets on terminal error. ConnectionStatus deduped.
## Summary
The coverage dashboard's initial load was slow and briefly rendered
misleading data. Root cause: `useLiveStatus` fetched the entire
(growing) PocketBase `status` collection via a single `getFullList`,
which PocketBase serial-paginates at perPage≤500 — ~5 sequential
blocking round-trips before first paint. During that window the grid
rendered authoritative `D0` cells and `✓0 ~0 ✗0` column tallies (not a
loading state), and a transient amber-D5/D6 toggle flash appeared
pre-hydration.
## Changes
- **perf:** concurrent paged fetch — page 1 then `Promise.all` over
pages 2..N, merged by array index (deterministic regardless of
resolution order), with a stable `sort: "id"` on every page so
concurrent requests share one ordering. Initial `setRows` wrapped in
`startTransition` to avoid a synchronous full-matrix re-render.
Best-effort snapshot; the live SSE subscription reconciles anything
created in the brief fetch→subscribe window (PocketBase `id` is random,
not monotonic — no growth-completeness claim).
- **fix:** `connecting` + empty-map now renders a loading affordance
instead of authoritative zeros (the §5.3 "no stale-green/fake-zero lie"
guarantee); `loading` made required on the tally type; fail-safe
undefined-tally fallback defaults to loading rather than zeros.
## Test plan
- [x] Order-safety: pages merge deterministically even when page 1
resolves last (out-of-order resolution)
- [x] Stable sort forwarded to every page request (behavioral — mock
sorts before slicing)
- [x] Loading-state quadrants on both `computeColumnTally` and
`computeColumnTallyDetail` (connecting+empty → loading; connecting+rows
→ authoritative; live+empty → authoritative; error → offline)
- [x] `OverlayColumnHeader` renders loading/offline affordance, not zero
glyphs
- [x] Full dashboard suite: 827 passed / 1 skipped; tsc clean; next
build green
Restore stubbed globals (EventSource, localStorage, window config) in
afterEach via vi.stubGlobal/unstubAllGlobals + snapshot, and unmount the
hook in a finally so the 30s heartbeat interval and its pb singleton don't
leak past the test onto the about-to-close in-process server.
Also normalize the fetchInitial page merge to
[first.items, ...rest.map((r) => r.items)].flat() for clarity (behavior
identical to the prior heterogeneous flatMap).
The PocketBase JS SDK derives a request key from method+path and
auto-cancels any in-flight request that shares it. useLiveStatus's
fetchInitial fans pages 2..N out concurrently at the same path
(/api/collections/status/records), so every page after the first
cancelled its predecessor — the cancelled promises rejected, Promise.all
rejected, and the hook dropped to OFFLINE. Pass requestKey:null on the
page-1 read, every fan-out page, and the heartbeat ping so all
concurrent same-path reads complete.
Add a real-SDK regression test (the mocked suite never exercised the SDK
so it missed this): an in-process http server replays paged status
records with per-page latency, the production getPb() client drives the
real hook, and it asserts "live" with all rows. RED without requestKey:null.
A connecting status with an empty status map now renders a loading
affordance instead of authoritative checkmark-0 / D0 cells and
zeroed column tallies. Make loading required on the tally type so the
contract is explicit, and default the fail-safe undefined-tally
fallback to loading rather than fake zeros. Adds coverage for the
loading-state quadrants across computeColumnTally /
computeColumnTallyDetail and the OverlayColumnHeader affordance.
Replace the single serial-paginating getFullList with a concurrent
page-1 fetch + Promise.all fan-out over the remaining pages, merged by
array index so results are deterministic regardless of resolution
order. Forward a stable sort:"id" on every page so concurrent requests
share one ordering. Wrap the initial setRows in startTransition to
avoid a synchronous full-matrix re-render. The snapshot is best-effort;
the live SSE subscription reconciles anything created in the brief
fetch->subscribe window.
Previously this job would run on main and give pretty poor signal into
non-serious failures. We only really want this logic on PR's because
otherwise CI becomes red for non-urgent issues.
PRs will continue to run this action and fail on quality failures (like
lint or commitlint issues)
## Release monorepo v1.59.5
**Scope:** `monorepo` | **Bump:** `patch`
---
### How this release process works
1. **This PR was created automatically** by the "release / create-pr"
workflow.
It bumped the `monorepo` packages to `1.59.5`
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.59.5`
- Creates git tag `monorepo/v1.59.5`
- 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.