11029 Commits

Author SHA1 Message Date
Ben Taylor 71e2682790 chore: release monorepo v1.60.0 (#5390)
## 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.
v1.60.0
2026-06-11 11:40:35 -05:00
MikeRyanDev a6e8000c94 chore: release monorepo v1.60.0 2026-06-11 16:27:00 +00:00
Ben Taylor 8fbc8936f1 refactor(runtime): Update Intelligence API handlers to pass along user IDs as route params (#5389)
## 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.
2026-06-11 11:23:12 -05:00
Mike Ryan 05cb21d325 fix(runtime): pass user ids to intelligence thread reads 2026-06-11 08:27:50 -07:00
Ben Taylor 81ee31dd5a docs(packages): scrub Copilot Cloud / client license-key prop from SDK doc references (#5364)
## 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)
2026-06-11 07:43:06 -05:00
Benjamin Taylor 8d68a95bc9 docs(packages): drop client license-key prop references; Angular no longer needs a key
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>
2026-06-11 07:22:37 -05:00
Benjamin Taylor 8956c668bc docs(packages): retire Copilot Cloud framing in SDK doc references, point to the license key
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>
2026-06-11 07:22:37 -05:00
Ran Shemtov e8f9c10dbe fix: respect per-agent A2UI scoping instead of injecting catalog context into every agent's runs (#5383) 2026-06-11 09:54:05 +02:00
Mark 8ce66524f9 Merge branch 'main' into fix/5369-a2ui-context-scoping 2026-06-10 22:20:50 -07:00
Mark Fogle 326fcc77a8 chore(changeset): drop the a2ui scoping changeset (#5369) 2026-06-11 05:11:08 +00:00
Mark Fogle 66dfa753dd chore(changeset): add changeset for the a2ui context scoping fix (#5369) 2026-06-11 05:07:28 +00:00
Mark Fogle a6deb44926 fix(vue): scope the A2UI catalog context to the runtime's a2ui agents (#5369) 2026-06-11 05:07:14 +00:00
Mark Fogle c036a97efa fix(react-core): scope the A2UI catalog context to the runtime's a2ui agents (#5369) 2026-06-11 05:07:11 +00:00
Mark Fogle 47c993ccbb fix(core): scope context entries per agent and preserve the a2ui agent list (#5369) 2026-06-11 05:06:15 +00:00
Mark Fogle b9df2ecaa9 fix(runtime): forward per-agent a2ui scoping in the runtime info response (#5369) 2026-06-11 05:05:54 +00:00
Tyler Slaton 6a1039b1cf fix(shell-docs): polish docs UI pass (#5381)
## 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
2026-06-10 21:42:44 -07:00
Tyler Slaton d980837075 Merge branch 'main' of github.com:CopilotKit/CopilotKit into codex/shell-docs-latest-main
# Conflicts:
#	showcase/shell-docs/src/lib/reference-items.ts
2026-06-10 21:33:24 -07:00
Tyler Slaton 63e3557af5 fix(shell-docs): polish docs UI pass 2026-06-10 21:17:40 -07:00
Jordan Ritter 02a66490a6 fix(showcase): make beautiful-chat calculator self-contained and robust (#5376)
## 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)
2026-06-10 18:00:56 -07:00
Jordan Ritter 85cf0725ea test(showcase): pin calculator fixture ordering and repeat-click routing invariants
- 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
2026-06-10 16:57:07 -07:00
Jordan Ritter 3ac28d2cf7 docs(showcase): mark superseded recorded calculator fixtures; correct GOTCHAS matcher semantics
- 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
2026-06-10 16:57:07 -07:00
Jordan Ritter 0028d3b2e3 fix(showcase): make beautiful-chat calculator fixtures self-contained and robust
- 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).
2026-06-10 16:57:07 -07:00
Tyler Slaton 5d8be44962 docs(shell-docs): Slack platform quickstart + Bots API reference (#5368)
## 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)
2026-06-10 16:47:04 -07:00
Tyler Slaton 8c20384ea5 Merge branch 'main' into tyler/slack-platform-docs 2026-06-10 16:39:00 -07:00
Tyler Slaton a8d43a9c2e docs(shell-docs): Slack platform quickstart + Bots API reference
- 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>
2026-06-10 16:33:15 -07:00
Tyler Slaton a766fb0e9e fix(examples/slack): pin @ai-sdk/mcp to 1.0.21 (protocolVersion incompat) (#5367)
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)
2026-06-10 15:49:26 -07:00
Tyler Slaton 88a2d82e1a fix(examples/slack): pin @ai-sdk/mcp to 1.0.21 (protocolVersion incompat)
@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>
2026-06-10 15:44:58 -07:00
Ben Taylor 094d29fa16 fix(shell-docs): record location on hero_command_copied for surface attribution (#5363)
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)
2026-06-10 17:30:28 -05:00
Tyler Slaton f4f6d6a494 fix(examples/slack): consume published packages; standalone-deployable example (#5366)
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)
2026-06-10 15:13:58 -07:00
Jordan Ritter 015278b827 chore(showcase): complete @ag-ui 0.0.55 fleet sync — mastra + 12 starters (#5359)
## Summary

Completes the @ag-ui 0.0.55 fleet sync: the showcase mastra integration
plus the starter fleet under `examples/integrations/`. Consolidates two
verified branches (`feat/showcase-mastra-agui-currency`,
`feat/showcase-starter-agui-currency`) into one PR.

### Showcase mastra currency

- `@ag-ui/client` bumped to explicit `0.0.55`.
- All floating `beta` dist-tags replaced with exact pins: `@ag-ui/mastra
0.2.1-beta.2`, `@mastra/client-js 1.23.2`, `@mastra/core 1.41.0`,
`@mastra/libsql 1.1.0-alpha.2`, `@mastra/memory` pinned exact.
- `fail-baseline.json` ratcheted down 48 → 42 (validate-pins FAIL count
+ set hash updated).

### Starter fleet bumps (12 starters)

| Starter | Frontend | Agent |
|---|---|---|
| adk | `@ag-ui/client` 0.0.53 → 0.0.55 | `ag-ui-adk` floating →
`==0.6.3` |
| agno | `@ag-ui/client` 0.0.53 → 0.0.55 | — |
| crewai-crews | `@ag-ui/crewai` `^0.0.2` → `0.0.3`;
`@ag-ui/client`/`@ag-ui/core` pinned `0.0.55` | — |
| langgraph-fastapi | — | `ag-ui-langgraph[fastapi]` `==0.0.37` →
`>=0.0.40`; `copilotkit` 0.1.93 → 0.1.94 |
| langgraph-js | already current | — |
| langgraph-python | — | `copilotkit` 0.1.93 → 0.1.94 |
| llamaindex | `@ag-ui/client`/`@ag-ui/core` 0.0.53 → 0.0.55 | — |
| mastra | `@ag-ui/client` 0.0.53 → 0.0.55; `@ag-ui/mastra` `beta` →
`0.2.1-beta.2`; `@mastra/*` floating → exact pins | — |
| ms-agent-framework-dotnet | `@ag-ui/client` 0.0.53 → 0.0.55 | — |
| ms-agent-framework-python | `@ag-ui/client` 0.0.53 → 0.0.55 | — |
| pydantic-ai | `@ag-ui/client` 0.0.53 → 0.0.55 | `pydantic-ai-slim`
floating → `==1.0.18`; `ag-ui-protocol==0.1.9` added |
| strands-python | `@ag-ui/client` 0.0.53 → 0.0.55 | `copilotkit` 0.1.93
→ 0.1.94 |

## Verification

Source branches (verified by their authors): 945/945 parity, starter
smokes 4/4 across all 12 starters, validate-pins ratcheted 48 → 42.

Re-verified on the consolidated branch:
- `showcase/scripts` vitest: 50 files / 1844 tests passed (incl.
aimock-fixtures, validate-pins, validate-parity suites).
- validate-pins ratchet matches merged state exactly: `FAIL=42`, set
hash `ea4a7a66…` == baseline.
- Showcase mastra integration: clean Next.js production build.
- Spot smokes via CI invocation (`docker-compose.test.yml`): mastra 4/4,
langgraph-python 4/4, agno 4/4.
- `examples/integrations/_parity` verify: exit 0, 0 errors.
- `oxfmt --check` / `oxlint`: no issues introduced (remaining warnings
pre-exist on main, outside this diff).

## Upstream note

`@ag-ui/mastra 1.0.3` is blocked on a broken runtime snapshot peer
dependency upstream — staying on `0.2.1-beta.2` for now; follow-up
tracked on the showcase follow-up ledger.
2026-06-10 15:11:27 -07:00
Jordan Ritter c7e67b90f4 chore(showcase): ratchet validate-pins baseline 48 -> 39
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).
2026-06-10 15:02:30 -07:00
Jordan Ritter d6cb5371e5 fix(showcase): align integration requirements to fleet pins
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.
2026-06-10 15:02:30 -07:00
Jordan Ritter e8d47f6481 fix(mastra): exact-pin floating beta dist-tags
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.
2026-06-10 15:02:19 -07:00
Jordan Ritter f630372347 fix(examples): align starter agent Python pins to fleet standard
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.
2026-06-10 15:02:19 -07:00
Jordan Ritter b59b9ff797 feat(examples): bump starter fleet to @ag-ui/client 0.0.55 with single-tree overrides
Bump @ag-ui/client 0.0.53 -> 0.0.55 across 8 starter example packages and
add npm overrides pinning @ag-ui/{client,core,encoder,proto} to 0.0.55 so
each install resolves a single @ag-ui tree. The mastra starter receives the
same bump alongside its dist-tag pin fixes in a separate commit.
2026-06-10 15:02:07 -07:00
Tyler Slaton e197b1a46e fix(examples/slack): consume published packages; make the example standalone-deployable
- dependencies: workspace:* -> published ranges (@copilotkit/bot* ~0.0.1,
  @copilotkit/runtime ^1.59.5) — the example is a consumer of the released
  packages, installable and deployable with zero monorepo context
- drop the private @copilotkit/typescript-config devDep; inline the base
  compiler options into tsconfig.json (verified identical tsc result)
- commit a standalone examples/slack/pnpm-lock.yaml for isolated installs
  (root workspace installs ignore it)
- slack-app-manifest.{yaml,json}: remove assistant:write scope +
  assistant_thread_started event (Slack rejects them without an
  assistant_view feature block; the bot doesn't implement that surface),
  add the /triage slash command the bot registers

Verified: slack-example tests 38/38 against the published packages; direct
tsc --noEmit clean; standalone install + runtime/bot boot exercised in a
gitless clean-room snapshot.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 14:54:46 -07:00
Jordan Ritter 744e095243 fix(release): emit version/scope to GITHUB_OUTPUT from prerelease publishes (#5362) 2026-06-10 14:29:35 -07:00
Maxim adaeda2dc6 fix(release): enforce GHA-safe output keys and tighten publish guards
Round-2 review fixes for the GITHUB_OUTPUT helper and the release scripts
that emit through it.

emitGithubOutputs (scripts/release/lib/github-output.ts):
- Replace the key newline/CR check with a full GitHub-Actions-safe charset
  check: /^[A-Za-z_][A-Za-z0-9_-]*$/. A key containing "=" or whitespace
  would silently corrupt the key=value line; rejecting up-front is
  strictly safer. Value validation (single-line) is unchanged — "=" in
  values is legal because GitHub splits on the first "=".
- Update the docblock accordingly.

prerelease.ts:
- Remove the dead `?? getCurrentVersion(scope)` fallback. The empty-list
  guard above makes packages[0] guaranteed, and the fallback would have
  masked a package.json missing its version field by emitting a version
  divergent from what the loop publishes. Fail loudly with an explicit
  exit instead.
- Drop the now-unused getCurrentVersion import.
- Add a comment above the dry-run emitGithubOutputs call explaining that
  emitting in dry-run is safe — the publish workflow gates publish + the
  verify guard on inputs.dry-run != true, so the dry-run emission only
  serves local/e2e contract verification.

publish-release.ts:
- Hoist getPackagesForScope + empty-list guard above the prerelease-suffix
  and registry checks. A misconfigured scope now fails with the clear
  "no packages found" error instead of a misleading "not greater than
  published" one. Loop is unchanged.

github-output.test.ts:
- Loosen the key-newline assertion from the JSON.stringify-coupled
  /bad\\nkey/ to the stable /alphanumeric/ phrase from the new message.
- Add tests: "=" in key throws, space in key throws, empty key throws,
  and "=" in value is accepted and written verbatim (note=a=b).
- Move vi.restoreAllMocks() to the top of afterEach so spies cannot leak
  into env restore + rmSync cleanup.

Call sites audited:
- emitGithubOutputs: only ever called with {version, scope} (prerelease,
  publish-release) — all valid under the new charset.
- publishVersion derivation: only used inside prerelease.ts main().
- getCurrentVersion: still imported by publish-release.ts, bump-prerelease.ts,
  prepare-release.ts; only the prerelease.ts import was removed.
- getPackagesForScope hoist in publish-release.ts: `packages` was only
  read inside the publish loop below; nothing earlier depended on it.
2026-06-10 22:58:03 +02:00
Maxim e8fa74ce45 fix(release): validate GITHUB_OUTPUT values and fail loudly on empty package lists
Hardens the new GITHUB_OUTPUT emission path so a malformed value can't smuggle
extra `key=value` lines into the workflow's step outputs, and so the workflow's
"Verify publish step emitted version" guard can't be fooled by a publish that
did nothing.

emitGithubOutputs now validates every key/value for `\n`/`\r` BEFORE the
GITHUB_OUTPUT early-return — a malformed value is a caller bug and should fail
loudly even when running locally. A multi-line value would need the heredoc
form, which this helper deliberately does not support.

prerelease.ts and publish-release.ts now fail loud when getPackagesForScope
returns an empty list. Without this, the new GITHUB_OUTPUT emission would make
the workflow's "Verify publish step emitted version" guard pass on a run that
published nothing — previously the missing output made such a run fail. The
guard runs BEFORE the dry-run branch in prerelease.ts. In publish-release.ts,
the inline iteration of getPackagesForScope(scope) is hoisted to a `packages`
const so the same guard fires before the publish loop.

The "no-op when GITHUB_OUTPUT is unset" test now spies on fs.appendFileSync
and asserts it wasn't called (the previous read of the unrelated temp file
was vacuously true). New tests cover newline/CR in value and newline in key.

The prerelease.ts usage string previously advertised `[--suffix <label>]`,
but the script never parses --suffix (suffix handling lives in
bump-prerelease.ts per the header comment). Removed.

Call sites enumerated:
- emitGithubOutputs: prerelease.ts (dry-run + post-publish), publish-release.ts
- getPackagesForScope: prerelease.ts, publish-release.ts (this commit);
  bump-prerelease.ts, prepare-release.ts, versions.ts (not changed — out of
  scope for this hardening)

Verification:
- npx vitest run --config scripts/release/vitest.config.mts → 91 passed
- Red-green for the newline validation: temporarily removed the validation,
  the 3 new newline/CR tests failed (assertion: expected fn to throw); restored,
  back to green.
- E2E: GITHUB_OUTPUT="$OUT" pnpm release:prerelease:dry succeeded and the
  output file contained `version=1.59.5` and `scope=monorepo`.

Note: Fix 2's empty-list guard fires only on a misconfigured scope (no unit
test reachable — prerelease.ts is outside the vitest include glob and the
guard is boundary validation against a misconfigured scope, not a behavior
worth contriving a test harness for).
2026-06-10 22:58:02 +02:00
Maxim afef53de65 fix(release): emit version/scope to GITHUB_OUTPUT from prerelease.ts
prerelease.ts published canaries successfully but never wrote the
version output the publish-release workflow's "Verify publish step
emitted version" guard reads, so every canary dispatch ended red after
a successful publish. Extract the GITHUB_OUTPUT append (previously
inline in publish-release.ts) into a shared lib/github-output.ts helper
and call it from both publish scripts.

Call-site enumeration:
- emitGithubOutputs: declared lib/github-output.ts; called from
  prerelease.ts (dry-run path + after publish) and publish-release.ts
  (replaces the inline appendFileSync block, same version=/scope= keys).
- No symbols removed; fs import in publish-release.ts still used (3
  remaining call sites).
2026-06-10 22:58:02 +02:00
Benjamin Taylor ff2b59f934 fix(shell-docs): record location on hero_command_copied for surface attribution (closes OSS-299)
The hero_command_copied event fired by the landing-hero command cards carried
no surface discriminator. HeroStartActions renders on both the home hero and
every framework landing hero; the "onboard" card's command is byte-identical
on every page, so onboard copies could not be attributed to a surface from the
event alone (only the "create" card embeds the framework in `command`).

Add `location: window.location.pathname` to the payload, mirroring the
`cli_command_copied` event the global <CopyTracker> already emits for the same
copy so the two paired events join on the same dimension. Guarded for SSR to
match the sibling.

Adds a source-assertion guard test in the shell-docs node-env convention.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 15:52:43 -05:00
Austin Merrick d8ed70a26b feat(shell-docs): recommend create + skills onboard commands in landing heroes (#5248)
## What

Replaces the landing-page CTA with **three entry points**, framed by
situation, and renders the **identical action block on the home hero and
every framework landing hero**:

| | action |
|---|---|
| **New project** | `npx copilotkit create` |
| **Existing project** | `npx copilotkit skills onboard` |
| **Guided walkthrough** | **Quickstart** button (preserved from the
previous hero) |

- **Unified `<HeroStartActions>` block**: two equal-weight command cards
plus a quickstart row beneath, shared verbatim by the home hero and the
framework landing heroes (per review: the two surfaces previously
diverged).
- **Quickstart preserved** in its original accent treatment. On the home
hero it is the framework-picker dropdown (`<HeroQuickstartDropdown>`,
restored); on framework pages it links straight to that framework's
quickstart guide. The home hero also keeps the "Learn more about
building with agents" link in the same row.
- **Framework landing heroes** (e.g. `/langgraph-typescript`): the
create command **pre-fills the framework** via the CLI's `--framework`
flag (e.g. `--framework langgraph-js`).

**Framework-flag mapping**: docs slug to CLI `--framework` value,
verified against the CLI's `AGENT_FRAMEWORKS` enum
(`langgraph-typescript`→`langgraph-js`,
`langgraph-python`→`langgraph-py`, `google-adk`→`adk`,
`strands`→`aws-strands-py`,
`ms-agent-dotnet`→`microsoft-agent-framework-dotnet`, identical for
`mastra`/`pydantic-ai`/`llamaindex`/`agno`/`ag2`). Slugs with **no** 1:1
CLI template fall back to a bare `npx copilotkit create`, notably
`crewai-crews` (the CLI ships *CrewAI Flows*, not Crews), plus
`langgraph-fastapi`, `claude-sdk-*`, `langroid`, `spring-ai`,
`agent-spec`, `deepagents`. `skills onboard` has no framework flag, so
it is identical everywhere. Frameworks with bespoke setup (`a2a` `git
clone`, `ms-agent-dotnet`) keep the pre-cards layout: quickstart button
plus their own copy-command chip.

**Responsive, with all text always visible.** Commands **wrap, never
truncate**:

- Wraps happen at spaces only; every token is non-breaking, so
`--framework` can never split into a dangling `-` at a line edge.
- `text-wrap: balance` splits multi-line commands evenly, typically
right at the flag boundary (`npx copilotkit@latest create` /
`--framework langgraph-js`).
- The block caps at 740px with 12px mono, the narrowest cap where both
home commands fit one line with enough headroom to survive platform
mono-font width differences.
- Cards sit two-up from `sm` and stack below it; the grid (`min-w-0`,
`items-stretch`) keeps long commands inside their track and the card
pair equal-height.

## Screenshots

**Home**: two cards, quickstart dropdown, learn-more link


![home](https://raw.githubusercontent.com/CopilotKit/CopilotKit/screenshots/oss-195/home.png)

**Home, quickstart dropdown open** (framework picker preserved)

![home
dropdown](https://raw.githubusercontent.com/CopilotKit/CopilotKit/screenshots/oss-195/home-dropdown.png)

**Framework landing (LangGraph)**: same block, framework pre-filled,
create command balanced across two lines, quickstart links to the guide


![framework](https://raw.githubusercontent.com/CopilotKit/CopilotKit/screenshots/oss-195/framework-langgraph.png)

**Worst case (Microsoft Agent Framework, Python)**: longest CLI flag
value, three balanced lines, fully readable

![long
command](https://raw.githubusercontent.com/CopilotKit/CopilotKit/screenshots/oss-195/framework-msagent-long.png)

**Bespoke setup (A2A)**: quickstart button plus own command chip
(pre-cards layout preserved)


![a2a](https://raw.githubusercontent.com/CopilotKit/CopilotKit/screenshots/oss-195/a2a-bespoke.png)

**Mobile (375px)**: cards stack, quickstart goes full-width

| home | framework |
|---|---|
| ![home
mobile](https://raw.githubusercontent.com/CopilotKit/CopilotKit/screenshots/oss-195/home-mobile.png)
| ![framework
mobile](https://raw.githubusercontent.com/CopilotKit/CopilotKit/screenshots/oss-195/framework-mobile.png)
|

## Telemetry

Both hero copy buttons are now explicitly instrumented: each click
captures **`hero_command_copied`** (`command_id`: `create` | `onboard`,
full `command` string, `clipboard_blocked`), so create-vs-onboard
funnels are queryable per landing page. The pre-existing global
`cli_command_copied` (fired by `CopyTracker` on any clipboard copy)
still fires for volume metrics; the new event uses a different name so
that funnel is not double-counted. Validated locally against a live
PostHog client: each click POSTs both events (plus `$autocapture`) to
`/ingest/e` with HTTP 200.

## Notes

- Both cards equal weight; accent only on hover. Copy rows copy on click
with `aria-live` feedback plus a clipboard-blocked fallback; cursor is
`pointer`.
- Removes `agent-start-prompt.tsx` and `hero-command-copy.tsx`.
`hero-quickstart-dropdown.tsx` is back (restored unchanged after review
feedback).
2026-06-10 13:03:10 -07:00
Tyler Slaton 4296447aad fix(bot-slack): defer Bolt initialization to start()
Bolt's App constructor schedules a background auth.test that can't be
awaited or error-handled - in unit tests it phoned home to api.slack.com
with dummy tokens, leaving ~15 unhandled invalid_auth rejections racing
the run's end (the unit (20.x) flake). deferInitialization: true makes
construction genuinely side-effect-free; start() runs app.init() first,
so auth/config errors surface to the caller, followed by the existing
awaited auth.test. Test fake App grows the matching init() stub.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 12:57:13 -07:00
Tyler Slaton fe685eb46f feat(release): npm release scopes for bot(+bot-ui) and bot-slack
- release.config.json: 'bot' scope versions @copilotkit/bot and
  @copilotkit/bot-ui together (sharedVersion: true, source: bot);
  'bot-slack' is its own scope, mirroring the angular precedent
- ReleaseScope type + VALID_SCOPES arrays + usage strings extended across
  release scripts
- stable-release.yml / publish-release.yml: scope choice options
- bot, bot-ui, bot-slack manifests: drop private, add publishConfig (public),
  repository/homepage/keywords, publint/attw targets; first release v0.0.1
- internal bot-package deps use workspace:~ (tilde): caret on a 0.0.x version
  pins the exact patch, tilde tracks the 0.0.x line; core/shared stay
  workspace:^ (caret is correct at 1.x)

Verified: release-script tests 85/85; prepare-release --scope bot --dry-run
bumps bot AND bot-ui in lockstep; actionlint clean on touched lines.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 12:57:13 -07:00
Jordan Ritter bb37e5867f fix(harness): deregister before best-effort teardown on drain (#5358)
## Summary

- Live staging redeploy evidence (2026-06-10 16:37Z): 2/6 workers
completed the full SIGTERM → abandon → deregister sequence in **under 1
second**, while 4/6 were SIGKILLed mid-browser-teardown because
Railway's ~10s stop grace is shorter than the old 25s drain budget —
leaving 4 stale roster rows and a reclaim splash on every deploy.
- This PR makes abandon + deregister the **guarded, sub-second critical
path** and demotes teardown to best-effort within a composed <10s
budget, so a platform kill mid-teardown is harmless.

## Design

- `drainFleetWorker` ordering: drain → `registration.stop` → bounded
deregister → graced `worker.stop` → always-run pool shutdown, with
stop-error precedence (a pool-shutdown failure can never mask the stop
error).
- `DRAIN_DEREGISTER_TIMEOUT_MS` (3s) bounds the **whole registration
write chain**, so a hung—not failing—PocketBase cannot consume the kill
window; timeout degrades to the documented crash-path reclaim.
- `safeLog` guards every loop/stop/drain-path log: a throwing logger can
neither reject the worker loop's done-promise nor skip the roster delete
or teardown (abort-before-log in `requestDrain`; structural-caller
guards in `drainFleetWorker`).
- Drain-aware lease renewal (an abandoned job's lease lapses instead of
being re-extended), mid-drain claim skip (a claim won after the drain
decision is never run), and mid-report precision (a run that began
reporting is never logged as abandoned).
- Never-throws loop closure: loop-crash logging via `done.catch` +
`/health` 503, heartbeat and idle-poll sleep hardening with a non-busy
pacing floor, aggregate-key protocol-violation wrap.
- `WORKER_DRAIN_GRACE_MS` default 25s → 6s; the composed 3+6 < 10s
budget is **pinned by a test**; present-but-invalid overrides warn;
overrides at/above ~7s are documented as forfeiting the composed budget.
- Boot-failure teardown catches now log (no silent chromium stranding).

## Review

- 6 unbiased 7-agent CR rounds + 5 fix rounds; every behavioral change
red-green or mutation-proven; `Promise.race` loser semantics empirically
pinned by test.
- ~30 pre-existing harness findings deferred to the flap-fix follow-up
backlog (top of the next fleet-robustness PR: lease-renew
retry-on-throw, empty-registry guard/dispatch mismatch,
`registered`-flag refresh, worker `/health` async bind race, queue fetch
timeouts).

## Test plan

- [x] 2176/2176 vitest (32 new tests)
- [x] `tsc --noEmit` both configs
- [x] oxfmt clean
- [ ] CI green on this PR

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-06-10 12:39:15 -07:00
Jordan Ritter 992e0a0335 fix(harness): deregister before best-effort teardown on drain — bounded, guarded, budgeted under the platform kill window 2026-06-10 12:22:06 -07:00
Jordan Ritter df2439e487 test(harness): pin deregister-first drain ordering, guarded critical path, and the composed kill-window budget 2026-06-10 12:22:05 -07:00
Austin Merrick df191ffac4 fix(shared): drop dead LicenseMode type instead of redefining it
LicenseMode was removed from license-verifier 0.3.0 and has no consumers
anywhere in the repo; the prior re-export was already uncompilable, so no
external consumer could exist either.
2026-06-10 11:54:21 -07:00
Austin Merrick 081e076659 fix(angular): resolve workspace paths to dist first in typecheck
The paths entries pointed at sibling package sources, so the Angular
package's tsc run typechecked core and shared sources under Angular's
compiler settings — surfacing errors in files outside any Angular
change (reported on #5321). Resolve to the built declarations first,
same pattern as the Vue package; the src fallback remains for cold
checkouts.
2026-06-10 11:54:21 -07:00
Austin Merrick 6b1bb1a4af fix(shared): define license context types locally, fix check-types
@copilotkit/license-verifier dropped LicenseContextValue and
LicenseMode from its public API in 0.3.0, leaving shared re-exporting
two nonexistent members. tsdown's dts rollup never validated the
re-export, so the broken types shipped silently and check-types fails
on main. Define both types here — shared already owns the context
shape via createLicenseContextValue — using the definitions from
license-verifier 0.2.0. Also annotate the merged telemetry properties
record so string indexing typechecks.
2026-06-10 11:54:21 -07:00