Commit Graph

12916 Commits

Author SHA1 Message Date
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
Nathan 🔶 Tarbert dedb3183d6 Merge branch 'main' into fix/issue-5533-agentid-runtime-sync 2026-07-01 16:08:55 -04: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
Alem Tuzlak 9cb929b40d feat(runtime): opt-in supersede for concurrent same-thread runs
InMemoryAgentRunner gains an opt-in { onConcurrentRun: "throw" | "supersede" }
(default "throw", so existing consumers are unchanged). In "supersede" mode a
new run for an already-running thread aborts the prior run (agent.abortRun(),
mirroring stop()) instead of throwing "Thread already running" — so a fast
follow-up turn, or one after a dropped/aborted run, cleanly replaces the
previous one.

Superseding overlaps two runs on the module-global per-thread store, so all
four finalization sites (both resets and both historicRuns.push) are guarded on
store.currentRunId === request.input.runId and stamp the run's own id. A
superseded run therefore drops its partial events rather than resetting or
mislabeling the new run's state/history.

Used by the Intelligence-hosted (managed) Slack listener. (OSS-417)
2026-07-01 19:10:54 +02:00
Alem Tuzlak 13248dda0b fix(bot): drop empty text deltas, tool status on all thread anchors, bound managed turns
Found while live-testing the Intelligence-hosted (managed) Slack bot:

- bot-intelligence: skip empty text_delta frames. The leading role-announcement
  chunk was emitted as delta:"", which the frozen render contract rejects
  (min 1 char), aborting every managed run.
- bot-slack: drive assistant.threads.setStatus ("is using `tool`…") on any
  thread anchor, not just assistant panes; keep in-message task_update rows.
- bot-intelligence: bound each managed turn in the HTTP delivery loop with
  turnTimeoutMs (default 120s) -> nack on timeout/throw, so a hung turn (a HITL
  approval that never arrives, a half-open stream) can't wedge the
  single-delivery listener. (OSS-421)
2026-07-01 19:10:14 +02: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