Commit Graph

12629 Commits

Author SHA1 Message Date
Ben Taylor 94379db14a feat(vue): CopilotThreadsDrawer wrapper (Threads v2 Vue vertical) (#5792)
## Summary

Adds a public **Vue `CopilotThreadsDrawer`** — a thin wrapper over the
shared `<copilotkit-threads-drawer>` Lit element — bringing the
Threads-v2 drawer to Vue at parity with the shipped React and Angular
verticals. This is the Vue fast-follow tracked in the [CopilotDrawer —
Vue wrapper](https://app.notion.com/p/3883aa38185281fc8a2cfb69cd1dd88e)
spec.

**SDK-only PR** (`packages/vue`). Like the Angular vertical, the example
de-fork / demo route is a **separate follow-up** — the Vue examples
can't consume the drawer until `@copilotkit/web-components` + a
`react-core` release ship *and* the examples support managed
Intelligence.

Recon during planning corrected the spec's original "cheapest/thinnest
wrapper" premise: Vue is thin on element interop (native
`isCustomElement` + `v-bind`/`v-on`) but — exactly like Angular — needed
an active-thread foundation built. So this ports the full vertical, not
just a binding layer.

## What changed (SDK layers)

- **`useThreads` augmentation** (`hooks/use-threads.ts`): `enabled`
gate, `listError` (genuine list errors, excludes dev/config errors),
`isMutating`, `unarchiveThread` / `refetchThreads` / `startNewThread`;
plus **`registerThreadStore` core-registry integration** and
**`threadEndpoints` list/mutation gating** (React parity).
- **Active-thread + drawer-awareness on
`CopilotChatConfigurationProvider`**: `setActiveThreadId` /
`startNewThread` with the non-explicit-seed override (so
thread-switching + "+ New" work under `<CopilotKit>`), and `drawerOpen`
/ `setDrawerOpen` / `drawerRegistered` / `registerDrawer` with
bidirectional mobile (`<768px`) mutual-exclusion.
- **Clear-on-fresh in `CopilotChat`**: clears the conversation on a
genuine new-thread switch, guarded against initial mount and agent-store
swaps.
- **Mobile launcher in `CopilotModalHeader`**: renders only when a
drawer is registered AND the viewport is mobile.
- **The `CopilotThreadsDrawer.vue` wrapper** + barrel export.
- **SSR safety:** the wrapper imports the `<copilotkit-threads-drawer>`
Lit element **lazily** (`await import(...)` inside `onMounted`,
client-only) rather than at module scope. The element evaluates `class …
extends HTMLElement` at import time, which crashes Nuxt/Vite SSR
(`HTMLElement is not defined`) — a static import would break SSR for
**every** `@copilotkit/vue` consumer, not just drawer users. (Found via
live Nuxt testing; see Testing.)

Load-bearing behaviors carried from the React/Angular rounds: license
gate never flashes the locked view (`licensed || pending`, `loading ||
pending`) and issues no `/threads` fetch while unlicensed; provider-less
`localDrawerOpen` fallback; id-keyed per-row slot reconciliation.

## How it was built & reviewed

Executed via the `micro-task-execution` three-tier model (curator →
decomposition-reviewer → 8 waves, each opus-reviewed) → integration
review → **`cr-loop`: 4 seven-agent review rounds + 7 fix batches,
converged to zero mandatory findings + a Procedure 3 promotion-audit
with zero promotions.** The loop caught and fixed real defects the
per-wave reviews missed: a `useThreads` stuck-loading bug on
`enabled:false`, a wrong chat-input focus `data-testid` (silent a11y
failure), a `CopilotChatToggleButton` fallback regression from the
provider change, net-new lint (`no-dupe-keys`, deprecated `:slot`), and
— surfaced by the promotion audit as load-bearing on the shipped
surfaces — the `registerThreadStore` (inspector visibility) and
`threadEndpoints` gating parity gaps.

## Testing

**Automated (all green in the worktree):**
- `nx run @copilotkit/vue:test` — **99 files / 1061 tests passed**. New
coverage: full `useThreads` augmented surface incl. store registration +
endpoint gating + mutation guards + `enabled` re-arm; the wrapper's
entire 10-event routing table; license pending-vs-resolved gating;
delete-active-thread reset; clear-on-fresh (with a mutation-check
proving it's non-vacuous); bidirectional mobile mutual-exclusion;
`isMobileViewport` guards; the mobile launcher; the
`setModalOpen`-undefined contract that `CopilotChatToggleButton` depends
on.
- `nx run @copilotkit/vue:build` — succeeds (this is the real type gate:
`vue-tsc --declaration`); the compiled `dist` exports
`CopilotThreadsDrawer`.
- `nx run @copilotkit/vue:check-types` — passes.
- `pnpm install --frozen-lockfile` — passes (lockfile in sync).
- Lint: all new/changed source files are clean. (The package-wide `nx
lint` has 173 pre-existing errors, red on `main` and unrelated to this
change.)

Red-green discipline was applied to every behavioral fix (test written
to fail against the bug, then confirmed green after the fix).

**Live-verified via a throwaway hacked example** (uncommitted; the
examples can't ship managed Intelligence yet, so the committed
demo/de-fork is a follow-up): wired the Vue Nuxt demo's runtime to a
managed-Intelligence runtime (`CopilotKitIntelligence` + `licenseToken`,
creds from a CLI scaffold) and loaded `/threads`. Observed: `/info`
reports `mode:"intelligence"`, `licenseStatus:"valid"`,
`threadEndpoints:{list,inspect,mutations,realtimeMetadata: true}`; the
drawer renders the **real thread list from the platform** (licensed —
not the locked or endpoints-unavailable gates), with the Active/All
filter, "New thread", per-row Archive/Delete, and the mobile launcher;
`CopilotChat` renders beside it; no console errors.

This live run is what surfaced the SSR bug above: before the lazy-import
fix, `/threads` (and `/`) 500'd with `HTMLElement is not defined`; after
it, `/threads` → 200 and the error is gone. (Note: the added node-env
regression test `CopilotThreadsDrawer.ssr.test.ts` is a forward-looking
smoke guard — current Lit ships a Node-guarded build so vitest-node
can't reproduce Nuxt's Vite-SSR resolution; the fix's proof is the live
Nuxt run.)

## Release gate

Like the React/Angular de-forks, the wrapper depends on
`@copilotkit/web-components` being published and a
`react-core`/`web-components` release containing the drawer.
`packages/vue` publishes alongside.

## Follow-up work (separate PRs, none blocking)

Tracked in **ENT-1037** (related to ENT-1035): the cross-framework
767/768 mobile-breakpoint reconciliation, `useThreads.startNewThread`
config-error dismissal parity, an identity-guarded
`unregisterThreadStore`, and CopilotChat send/connect error-UX parity.
The Vue examples are intentionally left as-is (no Vue de-fork).

Review feedback (@marthakelly) has been addressed in-branch — see the
review reply.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-07-01 16:57:00 -05:00
Ben Taylor 5d49a83124 chore(examples): de-fork threads examples onto SDK CopilotThreadsDrawer (#5734)
## What this does

Replaces the hand-rolled `threads-drawer/` fork in **every
threads-enabled integration example** with the SDK
`<CopilotThreadsDrawer>` (shipped in `@copilotkit/react-core` 1.62.1):

- `page.tsx` → SDK `<CopilotThreadsDrawer>` inside an **uncontrolled**
`CopilotChatConfigurationProvider` (the drawer drives the active thread;
"+ New" resets). The locked-view Upgrade CTA opens the Intelligence docs
**by default** (ENT-1027), so no `onUpsell` wiring is needed.
- reserved-column `page.module.css` (no layout shift when the
client-only drawer mounts)
- no-flash theme script where the example uses a `useEffect`
`ThemeProvider`
- canvas examples: `ExampleLayout` half/half + `w-full` fix
- deleted the per-example `threads-drawer/` fork

**16 examples:** adk, agno, a2a-middleware, agentcore (Vite/AWS —
build-validated only), crewai-crews, crewai-flows, langgraph-fastapi,
langgraph-js, langgraph-python, llamaindex, mastra, mcp-apps,
ms-agent-framework-dotnet, ms-agent-framework-python, pydantic-ai,
strands-python.

All browser-validated against a live Intelligence project during the
de-fork (drawer mounts, threads list/switch, reserved column, theme, ~0
console errors) except agentcore, which is `pnpm build` exit-0 (its
Bedrock/Cognito harness can't run locally).

## Release status — ready

The drawer landed on `main` and shipped in **1.62.1** —
`@copilotkit/react-core` plus the previously-missing
`@copilotkit/web-components` (now published and pinned in lockstep at
1.62.1). Every example is bumped from `workspace:*` / `1.61.0` →
**1.62.1**.

**Retest:** a standalone `npm install` + `next build` of pydantic-ai
(copied outside the monorepo, so it consumes the published packages)
resolves `CopilotThreadsDrawer` from `@copilotkit/react-core` + the
`@copilotkit/web-components/threads-drawer` subpath and compiles clean.

## Notes

- [x] Examples bumped to the published `1.62.1` (react-core + runtime).
`@copilotkit/web-components` is pulled transitively — no direct dep
needed.
- `.env` stays local only (gitignored; validation creds are not in this
PR).
- Branch is examples-only — no `pnpm-workspace.yaml` link entries or
`pnpm-lock.yaml` churn.
- agentcore: 3 previously-undeclared `@radix-ui/*` deps were added to
its `package.json` so it builds under pnpm.

## Related

- SDK `CopilotThreadsDrawer` (renamed from the interim `CopilotDrawer`)
— shipped in 1.62.1.
- Follow-ups surfaced during this work: ENT-1004 (CI smoke-matrix ↔ CLI
threads-set drift), ENT-1005 (CopilotThreadsDrawer theming hooks).
2026-07-01 16:42:04 -05:00
Benjamin Taylor bf105ee9dd chore(examples): review cleanup — drop .bak files + restore Teams icons
Address PR review: delete the 4 stray package.json.bak files left by the
version-bump tooling, and restore examples/teams/appPackage/{color,outline}.png
to main (the de-fork commit had rewritten them into raw LFS-pointer text —
incidental fallout unrelated to this PR's scope).
2026-07-01 16:22:43 -05:00
Benjamin Taylor 6a41e4bfe5 chore(examples): align langgraph-js example-layout with parity north-star
A stray comment edit left langgraph-js's example-layout/index.tsx one line
off from the langgraph-python north-star, tripping the verbatim parity check.
Match it exactly.
2026-07-01 16:22:43 -05:00
Benjamin Taylor dded304053 chore(examples): bump de-forked threads examples to @copilotkit 1.62.1
The drawer shipped in 1.62.1 (react-core + the previously-missing
web-components package). Move the de-forked examples off the workspace:*
placeholder (and 1.61.0 runtime) onto the published 1.62.1, so they consume
the real SDK CopilotThreadsDrawer. Verified: a standalone install + next build
of pydantic-ai resolves CopilotThreadsDrawer from the published packages.
2026-07-01 16:22:42 -05:00
Benjamin Taylor 61bbe13f4f chore(examples): adapt drawer de-fork to CopilotThreadsDrawer
Rename import + usage from CopilotDrawer to CopilotThreadsDrawer across the
de-forked examples, and drop the now-redundant onUpsell handler: ENT-1027
makes the element open the Intelligence docs URL by default via licenseUrl.
Comments updated; --cpk-drawer-* tokens unchanged. Holds until the drawer
packages are published.
2026-07-01 16:22:42 -05:00
Benjamin Taylor 2155821b86 chore(examples): de-fork threads-enabled integration examples onto SDK CopilotDrawer
Replace the hand-rolled threads-drawer fork in every threads-enabled
integration example with the SDK <CopilotDrawer> (uncontrolled
CopilotChatConfigurationProvider + reserved-column layout + theme no-flash
where applicable). 16 examples; all browser/build-validated locally.

DRAFT — depends on #5707 and the subsequent npm release; not mergeable until
the SDK publishes @copilotkit/web-components and react-core bumps. Pre-merge
TODOs in the PR description.
2026-07-01 16:22:42 -05:00
Benjamin Taylor b312fc6ba8 test(vue): real SSR-eager-import guard + row-slot & scoped-focus coverage + typed element reads
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 16:11:49 -05:00
Max Korp 805e372bde feat: sync Intelligence thread runs across devices (#5741)
## Summary
- add Intelligence thread run-activity metadata normalization and
subscription support
- reconnect explicit native Intelligence chats on remote run activity
without keeping /connect or /run streams long-lived
- harden replay cursor handling, passive /connect completion, and
passive replay tool execution

## Verification
- `pnpm --dir packages/core exec vitest run
src/__tests__/threads.test.ts src/__tests__/intelligence-agent.test.ts
src/__tests__/core-run-agent-resume.test.ts
src/__tests__/core-connect-thread-switch.test.ts
src/__tests__/core-connect-passive-replay.test.ts
src/__tests__/core-follow-up.test.ts`
- `pnpm --dir packages/react-core exec vitest run
src/v2/components/chat/__tests__/CopilotChat.runActivityReconnect.test.tsx
src/v2/components/chat/__tests__/CopilotChat.absentThreadConnect.test.tsx
src/v2/components/chat/__tests__/copilot-chat-throttle.test.tsx
src/v2/hooks/__tests__/use-human-in-the-loop.e2e.test.tsx`
- `pnpm --dir packages/core run check-types`
- `pnpm --dir packages/react-core run check-types`
- `pnpm --filter @copilotkit/core run build`
- `pnpm --filter @copilotkit/react-core run build`
- pre-commit package checks passed for affected package set

## Manual testing needed before ready
- two browser tabs/devices on the same explicit Intelligence thread: tab
A sends a later run, tab B live-syncs through wake-triggered /connect
replay
- old/new compatibility smoke tests: old client with new gateway, new
client with old gateway

Draft until manual testing is complete.
2026-07-01 13:53:07 -07:00
Benjamin Taylor cdec9c67bb refactor(vue): restore elRef typo-checking, watchEffect for property push, shared mobile-breakpoint constant
- Type elRef as CopilotKitThreadsDrawerElement (drop the `& Record<string, unknown>`
  escape hatch) so every el.<prop> write is checked against the real element type.
- Replace the 12-entry watch([...]) dependency array with watchEffect, which
  auto-tracks its reads and removes the maintenance hazard of keeping the array
  in sync.
- Extract MOBILE_MAX_WIDTH_QUERY in is-mobile-viewport.ts and reuse it in
  CopilotModalHeader's matchMedia listener to remove the within-Vue duplication
  of the breakpoint literal.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 15:52:21 -05:00
Benjamin Taylor f47f4b34dc fix(vue): lazily import the drawer element so @copilotkit/vue stays SSR-safe
CopilotThreadsDrawer.vue previously imported
`@copilotkit/web-components/threads-drawer` statically at module scope.
That module defines a Lit custom element, and eagerly loading it on every
`@copilotkit/vue` import risked an `HTMLElement is not defined`-style crash
under SSR (Node has no DOM) for any consumer that imports the package on
the server, e.g. Nuxt.

Fix: import the element module lazily, inside `onMounted`, so it is only
ever evaluated client-side. `elementTag`/`mounted` are set once the dynamic
import resolves, and the template gates rendering on `mounted`.

Consequence: the wrapper now mounts the custom element asynchronously.
Updated `CopilotThreadsDrawer.test.ts` so `mountDrawer()` awaits
`flushPromises()` (resolving the dynamic import) plus a trailing
`nextTick()` (flushing the render and the `flush: "post"` property-push
watcher) before returning, and centralized this settle in the shared
helper instead of repeating ad hoc `nextTick()` calls per test.

Added `CopilotThreadsDrawer.ssr.test.ts`, a `@vitest-environment node`
regression test asserting the package entry (which re-exports
CopilotThreadsDrawer) imports without throwing when there is no
`HTMLElement` global, guarding against reintroducing an eager DOM-dependent
import into the barrel.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 14:26:24 -05:00
Maximiliano Korp 12739f9b42 fix(core): gate idle reconnect fallback by cursor 2026-07-01 11:07:07 -07:00
Maximiliano Korp 9a173f1e45 fix(core): harden Intelligence reconnect cursors 2026-07-01 11:07:07 -07:00
Maximiliano Korp c8d1c3bc53 fix: suppress duplicate wake reconnects 2026-07-01 11:07:07 -07:00
Maximiliano Korp ea0b903fb1 fix: harden passive reconnect completion gates 2026-07-01 11:07:07 -07:00
Maximiliano Korp e9df9898bd test: stabilize hitl passive replay regression 2026-07-01 11:07:06 -07:00
Maximiliano Korp ed7a1e5412 fix: isolate passive reconnect replay 2026-07-01 11:07:06 -07:00
Maximiliano Korp c606a93f44 fix: coalesce opaque thread reconnect cursors 2026-07-01 11:07:06 -07:00
Maximiliano Korp c300411619 fix: harden multidevice reconnect cursors 2026-07-01 11:07:06 -07:00
Maximiliano Korp 0fe0b4a1b2 fix: stabilize multi-device reconnect streaming 2026-07-01 11:07:06 -07:00
Maximiliano Korp 8eb9bd77cd fix: scope chat run-activity reconnects 2026-07-01 11:07:05 -07:00
Maximiliano Korp 7132026df4 fix: harden thread activity reconnects 2026-07-01 11:07:05 -07:00
Maximiliano Korp d57f9336d9 feat(react-core): reconnect native threads on run activity 2026-07-01 11:07:05 -07:00
Maximiliano Korp 2b99d96f46 test(core): guard intelligence connect completion semantics 2026-07-01 11:07:05 -07:00
Maximiliano Korp 481f67d9a8 feat(core): expose intelligence thread run activity notifications 2026-07-01 11:07:05 -07:00
Benjamin Taylor 4171319ff5 chore(vue): drop demo route from SDK PR — deferred to a follow-up
The Vue examples cannot consume the drawer until @copilotkit/web-components +
a react-core release ship AND the examples support managed Intelligence — same
constraint as the Angular vertical, which kept its demo route as a separate
follow-up PR. This PR is SDK-only (packages/vue).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 12:46:49 -05:00
Benjamin Taylor e109c350d3 fix(vue): register thread store with core + gate on threadEndpoints (React parity)
Ports two React-parity gaps (audit-flagged as user-facing) into the Vue
`useThreads` composable, mirroring react-core `use-threads.tsx`.

Fix A — register the thread store with core's single-slot registry:
- Adds a `watch([resolvedEnabled, resolvedAgentId])` that calls
  `copilotkit.value.registerThreadStore(agentId, store)` and, via the
  watch's `onCleanup`, `unregisterThreadStore(agentId)` on
  disable/agentId-change/unmount. Gated on `resolvedEnabled` so a disabled
  (unlicensed) store never evicts a co-mounted live store for the same agent.

Fix B — gate list + mutations on `copilotkit.threadEndpoints`:
- Derives `threadListEndpointSupported`/`threadMutationsSupported` via
  `!== false` (legacy runtimes advertise `undefined` => supported).
- Context-dispatch watcher skips dispatching (setContext(null)) when the
  list endpoint is unsupported, so no `/threads` fetch fires.
- Folds `threadEndpointsError` ("Thread endpoints are not available on this
  CopilotKit runtime") into `error` (NOT `listError`, which stays
  storeError-only) and factors `!threadEndpointsUnavailable` into
  `preConnectLoading` so the UI doesn't spin against an endpoint-less runtime.
- `guardMutation` wraps rename/archive/unarchive/delete to reject with
  "Thread mutations are not available on this CopilotKit runtime" when
  `threadEndpoints.mutations === false`, before touching the network.

Call sites:
- The shipped `CopilotThreadsDrawer` consumes `error` for its user-facing
  error banner (now surfaces the endpoints-unavailable message instead of
  spinning) and `listError` for genuine list-load failures (unchanged
  contract: storeError only, no config/runtime-setup leakage). Its `enabled`
  prop (unlicensed gate) already suppressed fetches; it now also correctly
  suppresses core-registry registration so a co-mounted live chat store for
  the same agent is not evicted. Mutation buttons (rename/archive/delete)
  reject locally on runtimes that don't serve mutations.

Item 3 (startNewThread configErrorDismissed) intentionally left out of scope.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 12:29:54 -05:00
Benjamin Taylor dc506c4c9b test(vue): cover CopilotThreadsDrawer event-routing table + guard findChatInput for SSR
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 12:17:33 -05:00
Mike Ryan 5bcc1d1ce0 chore: release monorepo v1.62.1 (#5791)
## Release monorepo v1.62.1

**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.62.1`
   and generated AI-enhanced release notes.

2. **CI runs on this PR** — the full test suite (unit tests, lint, type
checks, build)
   must pass before merging. This is the review gate.

3. **Review the release notes** in `release-notes.md` in this PR.
If a Notion draft was created, you can edit the release notes there
before merging.

4. **When this PR is merged**, the `release / publish` workflow
automatically:
   - Builds all packages
   - Publishes the `monorepo` packages to npm at version `1.62.1`
   - Creates git tag `monorepo/v1.62.1`
   - Creates a GitHub Release with the final release notes

### Before merging

- [ ] CI is green (tests, lint, types, build)
- [ ] Version bumps look correct
- [ ] Release notes are accurate (edit in Notion if a draft was created)

---

> **Do not merge until CI is fully green.** The full test suite runs
automatically on this PR.
v1.62.1
2026-07-01 10:10:06 -07:00
tylerslaton 617e88a069 chore: release monorepo v1.62.1 2026-07-01 17:07:44 +00:00
Benjamin Taylor 7803080713 fix(vue): keep setModalOpen undefined without backing modal state
Wave-4 introduced setModalOpenWithDrawerExclusion as an always-defined
function on configurationValue.setModalOpen. Under a bare
<CopilotChatConfigurationProvider> (no isModalDefaultOpen, no parent
providing modal state), this broke the pre-existing contract that
setModalOpen is undefined when the provider owns no backing modal
state — the function was defined but a no-op, since it delegated to
parentConfigValue?.setModalOpen, which was undefined.

CopilotChatToggleButton.vue depends on that undefined-ness: it checks
`config.value?.setModalOpen` and falls back to a local `fallbackOpen`
ref when absent. With the regression, clicks routed into the no-op
setter instead of the fallback, permanently stuck closed.

Fix: replace the standalone function with a `publicSetModalOpen`
computed that returns undefined when resolvedSetModalOpen (the real,
possibly-parent-inherited setter) is undefined, and otherwise wraps it
with the mobile drawer-exclusion behavior. This preserves the
undefined contract without touching resolvedIsModalOpen,
resolvedSetModalOpen, or the drawer-registration code.

Call-site enumeration for setModalOpen consumers (all read via
optional chaining, so all remain safe):
- CopilotChatToggleButton.vue: `config.value?.setModalOpen` — restored
  fallback-open behavior when the provider is bare, confirmed via new
  presence-contract tests plus the existing 5-test
  CopilotChatToggleButton.test.ts suite (all pass).
- CopilotModalHeader.vue: `config.value?.setModalOpen?.(false)` — only
  used inside modal-backed compositions (CopilotPopup/Sidebar), which
  always pass isModalDefaultOpen, so setModalOpen is always defined
  there; unaffected.
- CopilotSidebarViewInternal.vue / CopilotPopupViewInternal.vue: same
  pattern, same modal-backed guarantee; unaffected.

React's CopilotChatConfigurationProvider.tsx intentionally keeps
setModalOpen always-defined and always backed by internal state — a
different resolution than Vue's. This fix takes the minimal Vue-local
path (preserve the undefined contract CopilotChatToggleButton relies
on) rather than reworking resolvedIsModalOpen's backing, to avoid
changing bare-provider modal-open semantics.

Tests: added a "modal-setter presence contract" describe block
verifying (1) a bare provider exposes setModalOpen as undefined
(red-green verified: fails on pre-fix code, passes after), and (2) a
provider with isModalDefaultOpen exposes a working setModalOpen that
toggles isModalOpen. All 21 tests in the provider suite pass,
including the existing mobile drawer<->modal mutual-exclusion tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 12:04:56 -05:00
Tyler Slaton 018f64b2db fix(release): include web-components in monorepo scope (#5790)
## Summary
- Include `@copilotkit/web-components` in the shared `monorepo` release
scope.
- Remove the standalone `web-components` release scope from workflow
dispatch options and type definitions.
- Keep notification package counts aligned with the 16-package monorepo
scope.

## Why
`@copilotkit/web-components` should move with the rest of the shared
monorepo packages after its initial manual publish, not be released as a
separate scope.

## How
- Added `@copilotkit/web-components` to `release.config.json` under
`monorepo`.
- Removed standalone scope dropdown/options and npm URL handling.
- Verified dropdown parity, monorepo dry run, standalone-scope
rejection, and notification tests.
2026-07-01 10:02:33 -07:00
Austin Merrick f54e99697b fix(build): replace Unix-only commands in package.json scripts with Node.js equivalents (#5602)
## What does this PR do?

This PR fixes build failures on Windows by replacing Unix-only shell
commands (`rm -rf`, `cp`, `mkdir -p`) in `package.json` scripts with
cross-platform Node.js `fs` built-in commands.

This follows the project's existing codebase pattern for cross-platform
operations, as seen in `packages/react-ui/package.json` (line 45).

### 🛠️ Changes:
- **`packages/runtime`**: Replaced `rm -rf` in `generate-graphql-schema`
with `fs.rmSync`.
- **`packages/vue`**: Replaced `cp` in `build:types` and `rm -rf` in
`clean` with `fs.cpSync` and `fs.rmSync`.
- **`packages/angular`**: Replaced `mkdir -p` and `cp` in `build:css`
with `fs.mkdirSync` and `fs.cpSync`.
- **`examples/v1/next-openai`, `next-pages-router`, `state-machine`**:
Replaced `rm -rf` clean commands with a single Node.js loop that deletes
`.turbo`, `node_modules`, `dist`, and `.next`.

All modified packages now build successfully on Windows.

## Related PRs and Issues

- Closes #5601

## Checklist

- [x] I have read the [Contribution
Guide](https://github.com/copilotkit/copilotkit/blob/master/CONTRIBUTING.md)
- [ ] 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)
2026-07-01 09:56:00 -07:00
Tyler Slaton 7527ee64d0 fix(release): fold web-components into monorepo scope 2026-07-01 09:54:51 -07:00
Austin Merrick 66de791b40 fix(vue): inherit chat configuration agent id in useAgent (#5695)
## Summary

- Make Vue `useAgent` resolve agent IDs from explicit prop, then
surrounding chat configuration, then `DEFAULT_AGENT_ID`.
- Add regression coverage for bare `useAgent()` inside a non-default
configured chat and for explicit prop precedence.
- Update the Vue parity matrix note for the `useAgent` precedence
behavior.

Fixes #5656

## Verification

- `pnpm nx run @copilotkit/vue:test --
src/v2/hooks/__tests__/use-agent.test.ts` (failed before the fix with
`Received: "default"`, passes after)
- `pnpm --dir packages/vue exec eslint src/v2/hooks/use-agent.ts
src/v2/hooks/__tests__/use-agent.test.ts`
- `pnpm nx run @copilotkit/vue:check-types`
- `pnpm nx run @copilotkit/vue:test` (94 files / 1007 tests)
- `lefthook pre-commit test-and-check-packages` (ran `@copilotkit/vue`
test, build, publint, and attw)
- `git diff --check upstream/main...HEAD`

## Notes

- `pnpm nx run @copilotkit/vue:lint` still fails on pre-existing
unrelated Vue lint errors across untouched files; the changed files pass
eslint directly.
2026-07-01 09:54:41 -07:00
Benjamin Taylor 0399facf05 test(vue): unit-test isMobileViewport guard, reverse mobile mutual-exclusion, de-brittle clear-on-fresh
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 11:52:29 -05:00
Benjamin Taylor a3d919a995 fix(vue): resolve net-new lint (no-dupe-keys handlers, slot attr) + guard matchMedia in isMobileViewport
CopilotThreadsDrawer.vue declared local handlers `onNewThread`/`onLicensed`
with the same names as the `onNewThread`/`onLicensed` input-callback props,
tripping vue/no-dupe-keys. Renamed the handlers to `handleNewThread`/
`handleLicensed` (props left untouched) and updated their template bindings
(`@new-thread`, `@licensed`) and the one internal call site in `onDelete`
that re-implemented the new-thread flow inline.

Rewrote the per-row `:slot="`row:${t.id}`"` binding as
`v-bind="{ slot: `row:${t.id}` }"` to satisfy vue/no-deprecated-slot-attribute
without changing behavior — it still compiles to a real DOM `slot` attribute
used to project light-DOM children into the custom element's named shadow
slots (not a Vue component slot).

Added a `typeof window.matchMedia !== "function"` guard to
isMobileViewport(), matching CopilotModalHeader.vue and the React reference,
so environments where `window` exists but `matchMedia` doesn't (some test
runners, embedded webviews) don't throw when the provider opens the
drawer/modal.

CopilotModalHeader.vue:40 `_className` unused-var lint error predates this
branch (introduced in 28d07ccaa, already on main) and is left as out of
scope.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 11:47:15 -05:00
Tyler Slaton 9ed48a9dc3 fix(web-components): keep generated tokens formatted 2026-07-01 09:44:46 -07:00
Tyler Slaton 3e8e409f1f chore(release): add web-components release scope 2026-07-01 09:43:04 -07:00
Benjamin Taylor b1e1d108ef fix(vue): correct chat-input focus testid + scope lookup, add provider-less drawerOpen fallback
focusChatInput() queried `[data-testid="copilot-chat-textarea"]`, a testid
that exists nowhere in the Vue package (copied from React) — the `?.` made
the miss silent, so focus never returned to the composer after selecting a
thread. Corrected to `copilot-chat-input-textarea` (CopilotChatInput.vue)
and added React-parity scoping: `findChatInput` walks up from the drawer's
element via `closest('[data-testid="copilot-chat-view"]')` to scope the
input lookup to the enclosing chat, falling back to a document-global query
when no such ancestor exists. Sole call site: `onThreadSelected`.

Added a `localDrawerOpen` ref fallback for when there is no surrounding
`CopilotChatConfigurationProvider` (`config.value === null`): previously
`el.open` was pinned to `false` forever and `onOpenChange` was a no-op in
that case, since both routed through `config.value?.`. A `drawerOpen`
computed / `setDrawerOpen` function now pick the provider's state when
present and the local ref otherwise; both the property-push watcher and
`onOpenChange` route through them. Mirrors React's bare-drawer-starts-closed
fallback.

Documented (no behavior change) that the `row` scoped slot, unlike React's
`renderRow`, has no per-row escape hatch back to the element default — once
provided it projects for every thread.

Added tests: focus-return after thread-selected (red against the old
testid), delete-of-active-thread resets to a new thread (plus the
negative non-active case), and the provider-less drawerOpen fallback
reflecting open-change events.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 11:41:17 -05:00
Benjamin Taylor 54b33a7947 fix(vue): re-arm useThreads loading indicator on enable/reconnect + gate preConnectLoading on enabled
Call sites: `preConnectLoading` only feeds `isLoading` (returned to consumers,
e.g. CopilotThreadsDrawer's licensed-gate loading state); `hasDispatchedContext`
is read only by `preConnectLoading` and written only in the context watcher.

Without gating on `resolvedEnabled`, useThreads({ enabled: false }) left
isLoading stuck true forever (hasDispatchedContext never set). Without
resetting the flag on the disabled/no-runtimeUrl branch, toggling
enabled false->true (or runtimeUrl removed+re-added) failed to re-arm the
pre-connect loading synthesis, regressing the empty-list flash it exists
to suppress. Brings the Vue hook back in parity with the React reference's
reset behavior for these two branches.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 11:37:01 -05:00
Benjamin Taylor 3b6c7affb8 feat(vue-demo): threads route with CopilotThreadsDrawer + CopilotChat
Add examples/v2/vue/demo/pages/threads.vue demonstrating the drawer
alongside chat. The demo has no root CopilotKitProvider (app.vue only
renders <NuxtPage/>), so the page mounts its own provider chain,
matching the runtime-url + show-dev-console convention used by every
sibling demo page. CopilotChatConfigurationProvider is left
uncontrolled (no threadId) so the drawer drives the active thread.
No natural nav list exists in index.vue or elsewhere in the demo, so
no nav link was added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 11:21:50 -05:00
Benjamin Taylor 9a34ea397d chore(vue-demo): register copilotkit-threads-drawer as a custom element in Nuxt
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 11:19:57 -05:00
Benjamin Taylor d15d95804e feat(vue): export CopilotThreadsDrawer from the package entry
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 11:19:08 -05:00
Benjamin Taylor bd1289fa44 test(vue): CopilotThreadsDrawer renders element, routes thread-selected, fires onLicensed
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 11:14:19 -05:00
Benjamin Taylor 4cacf5fbd0 feat(vue): CopilotThreadsDrawer wrapper over the shared threads-drawer element
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 11:12:34 -05:00
Benjamin Taylor 989ed28762 test(vue): mobile drawer launcher visibility + toggle in CopilotModalHeader
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 11:08:38 -05:00
Benjamin Taylor aaa9916556 feat(vue): mobile drawer launcher in CopilotModalHeader
Adds a mobile-only launcher button at the leading edge of
CopilotModalHeader that toggles the drawer. It renders only when a
CopilotThreadsDrawer has registered with the chat configuration AND
the viewport is mobile (<=767px, matched via matchMedia and mirrored
from the React CopilotModalHeader implementation). Also exports
IconPanelLeftOpen from the shared icons barrel for the button's icon.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 11:06:32 -05:00
Benjamin Taylor d0c77d6d72 test(vue): cover drawer registerDrawer + mobile drawer/modal mutual-exclusion
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 11:02:50 -05:00
Benjamin Taylor e36a7c953c feat(vue): drawer-awareness state + mobile mutual-exclusion in chat config provider
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 11:01:34 -05:00