CR-loop confirmation-round #4 findings:
- validator: `resolvesForMode` (renamed from `typesCoversMode`) now applies to
EVERY condition, not just `types`. A partial object under `node`/`default`
(active in both modes) no longer silently covers the mode it lacks —
resolution falls through to the sibling, catching the untyped-JS #3324 shape
there. This completes the per-mode model.
- helper: `withTypesConditions` throws on a non-object `exports` (bare string /
array) instead of iterating it into a corrupt map; `typedTarget` now warns
loudly when a JS target has no adjacent declaration (was silent, contradicting
the helper's own fail-loud contract); idempotency skips only the helper's own
`{ types: <string>, ... }` output, so a hand-authored types-first PARTIAL
object is normalized (its untyped sibling gets a `types`). UMD / `.d.mts` docs
corrected; `ctx.pkg: unknown` documented as intentional (weak-type constraint).
- tests: node/default partial fall-through regression; types-first-partial
normalization; a helper->validator round-trip; a console.warn assertion for
the missing-declaration path; split the untouched-target test into silent
(non-JS) and warning (JS) cases.
- react-native: dropped a pre-existing duplicate `@ag-ui/client` external.
Call sites: resolvesForMode (internal, walk + recursion; grep-confirmed no
`typesCoversMode` refs); withTypesConditions signature unchanged, and the new
throw/warn never fire on tsdown's real input (object map, packageJsonPath
present, dts:true).
36 tests pass; validator typechecks; validate:exports exits 0; native-loader
builds of react-core + react-native unchanged.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CR-loop confirmation-round findings on the #3324 guard:
- validator: replace the single-`typesIndex` model with per-mode resolution.
import- and require-mode resolve independently (each picks the first present
of {types, <mode>, node, default} in object order), so a trailing
`default`/`node` shadowed by a typed `import` + `require` is no longer a false
positive, while a genuinely misordered/absent `types` is still flagged.
- helper: make `withTypesConditions` idempotent (skip an object that already
carries a `types` key, so re-application never re-nests `default`) and
optional-chain `ctx` so a missing context hits the fail-loud message.
- CI: run scripts/__tests__/tsdown-exports.test.ts in the guard workflow (the
helper is the mechanism that injects the types conditions, and its test ran
in NO workflow) and add it to the trigger `paths`; note the standalone gate
validates committed artifacts, not build output.
- tests: assert `types` is emitted FIRST via serialization (toEqual is
key-order-insensitive and missed a types-last regression); add idempotency and
trailing-default regression cases.
- react-native: document why its exports map is hand-maintained (no tsdown
`exports` hook) and guarded by validate:exports.
Call sites enumerated:
- walk / findExportsTypeViolations — internal to the validator + its tests;
signatures unchanged. JS_CONDITIONS removed (grep-confirmed no refs); replaced
by RESOLUTION_MODES + isActiveCondition.
- withTypesConditions — 13 tsdown configs via customExports; signature
unchanged, tsdown always supplies ctx.pkg.packageJsonPath and never re-applies
or emits null/array, so the new guards never fire on current input.
28 tests pass; validator typechecks; real 25-package validate:exports exits 0.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Under moduleResolution bundler/node16/nodenext, TypeScript ignores the
top-level "types" field once an "exports" map exists, so strict-exports
tooling (e.g. the Backstage CLI) resolves no type declarations and reports
every named export as "has no exported member". tsdown does not emit a
types condition in the exports map it generates.
Add one — first, per import/require, ESM to .d.mts and CJS to .d.cts — via
a shared withTypesConditions helper (scripts/tsdown-exports.ts) wired into
each tsdown config, and directly in the hand-maintained react-native map.
Add a regression guard, since attw and publint do NOT catch this (TS's
adjacent-file fallback masks it): scripts/validate-package-exports-types.ts,
unit + all-package tests, a validate:exports npm script, and a CI workflow
that fail if any publishable package's exports map lacks a types condition.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Repairs TypeScript check-types across the monorepo and adds a CI gate so
regressions are caught going forward:
- core: bundler module resolution and strict-mode fixes
- sdk-js: bundler module resolution; keep codegen, formatter, packaging working
- react-core: fixes across components, hooks, and tests
- react-native: restore catch binding referenced by TypeError cause
- runtime: repair check-types and bound AI SDK schema inference
- web-inspector: nodenext import extensions, export Anchor
- remaining packages and node example: assorted check-types repairs
- deps: add missing type-only devDependencies
- license context driven from /info licenseStatus
- ci: run check-types in the static quality workflow
Squashed from 12 commits for a single, easily-revertable change.
Adds the AG-UI standard interrupt flow (RUN_FINISHED outcome:interrupt + resume array) alongside the legacy on_interrupt path.
- core: forward the standard resume array through runAgent.
- react-core / vue / react-native: useInterrupt handles standard interrupts with resolve()/cancel(), surfaces the primary + full interrupt set, and persists each resolved tool-backed interrupt as a tool-result message so multi-turn conversations stay well-formed (no dangling tool call -> no tool-call loop).
- runtime BuiltInAgent: native interrupts for the aisdk + tanstack factory paths via each SDK's needsApproval primitive (tool-approval-request / CUSTOM approval-requested -> outcome:interrupt); classic interrupt-tool emission + ctx.interrupt() factory primitive; idempotent resume injection mapped to each SDK's native tool-result; getCapabilities advertises humanInTheLoop.interrupts.
- docs: document standard interrupt support.
Verified across core/react-core/runtime unit suites and a real-model multi-turn run on both aisdk and tanstack.
Bump @ag-ui/core, @ag-ui/client, @ag-ui/encoder from 0.0.53 to 0.0.56
across all packages.
@ag-ui/client 0.0.56 changed runHttpRequest from (url, requestInit) to a
fetch-thunk signature (() => Promise<Response>). Update the single-route
and connect transport paths in ProxiedCopilotRuntimeAgent to wrap the
request in () => this.fetch(url, init), restoring the broken envelope
transports.
Add @ag-ui/core, client, encoder, proto to minimum-release-age-exclude
in .npmrc so the freshly published 0.0.56 (under the 24h release-age
gate) installs in CI.
Matches the explicit-import convention used by sibling tests in this
package (e.g. copilot-chat-agentid.test.tsx, streaming-fetch.test.ts).
Removes 3 tsc "Cannot find name 'describe'/'it'/'expect'" errors
without changing runtime behavior — vitest globals already provided
at runtime via vitest.config.mjs (globals: true).
Adds purely additive data-testid markers to the error and loading UI
surfaces across the frontend framework packages (react-core, react-ui,
react-native, angular, vue) so e2e tests can deterministically detect
errored-out vs still-loading states. Without these, e2e probes hit
~30-60s timeouts instead of failing fast.
Testids (aligned with existing repo convention; copilot-<kebab>):
- copilot-error-banner on react-core BannerErrorDisplay (toast
provider) and UsageBanner, plus react-ui legacy in-chat ErrorMessage.
- copilot-loading-cursor on react-ui legacy LoadingIcon sites
(Messages.tsx, AssistantMessage.tsx), angular
CopilotChatMessageViewCursor, react-native TypingIndicator (via
RN testID convention), and vue CopilotChatMessageView. The v2
react-core Cursor already exposed this testid; this change broadens
it to every frontend framework so a single selector works across all.
Vue's prior copilot-chat-cursor testid is renamed to
copilot-loading-cursor for cross-framework consistency; the two e2e
tests in packages/vue that referenced the old name are updated.
No behavior, rendering, or styling changes. Adds small static
source-asserting tests in each touched package that verify the markers
stay in place.
Add peer dependencies, export new components and hooks from package entry point, integrate RenderToolProvider into CopilotKitProvider, configure vitest and tsdown, add usage documentation.
FlatList-based chat interface and bottom-sheet modal overlay. Includes suggestion pills, keyboard avoidance, custom FlatList support, and comprehensive test coverage.
Hook for rendering custom tool UIs in React Native with a store-based context provider. Includes tests for register/unregister, subscriber notification, and error handling.
Message bubble components with streaming markdown support, typing indicator animation, and timestamp formatting. Includes unit tests and edge case coverage.
## Release monorepo v1.57.2
**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.57.2`
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.57.2`
- Creates git tag `monorepo/v1.57.2`
- 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.
15+ type re-exports from headless layer. expo-document-picker and
expo-file-system as optional peer deps. InterruptEvent,
ReactFrontendTool, ReactHumanInTheLoop added to headless.ts.
XHR callbacks deferred to JS thread to prevent iOS crash. agentId
prop added for consistency with web SDK. Dynamic headers function
and credentials prop on CopilotKitProvider.
Add to monorepo scope in release.config.json. Set version to 1.56.5,
correct ESM extensions in exports map, add check-types/publint/attw
scripts, align tsdown to ^0.20.3. Add react-native example glob to
pnpm-workspace.yaml. Regenerate lockfile preserving zod@3 and
langchain dependency versions.
Headless React Native wrapper for CopilotKit. Provides a lightweight
CopilotKitProvider and re-exports platform-agnostic hooks from
react-core without pulling web dependencies (no DOM, CSS, Radix,
Lit, A2UI). Includes XHR-based streaming fetch polyfill for Hermes
and granular polyfills for streams, encoding, crypto, DOM, and
location APIs.