Commit Graph

16 Commits

Author SHA1 Message Date
Benjamin Taylor 4df1e3dccd docs(a2ui): require a literal-or-binding union for bound props (refs OSS-857)
Three findings from a LangGraph TypeScript onboarding run, plus the
supporting re-export.

The A2UI binder decides whether to resolve a `{ path }` binding by
inspecting the prop's Zod type: `scrapeSchemaBehavior` classifies a
`ZodUnion` containing an object with a `path` key as DYNAMIC and
everything else as STATIC, and STATIC returns the value untouched. A
bound prop declared as a plain `z.string()` therefore reaches the
renderer as the raw `{ path: "/origin" }` object, and the first thing
that renders it as text throws React error #31. The fixed-schema page
said the opposite — that renderer props are "plain z.string(), not a
path-or-literal union" — so the obvious declaration produced an opaque
crash. The reference cell already declares the union and carries a
comment explaining why, but that comment sits outside the
`definitions-types` region marker and so never reaches the page.

`DynamicStringSchema` is real; it lives in `@a2ui/web_core`, which is a
transitive dependency of `@copilotkit/a2ui-renderer` and so not
reliably importable from application code. Re-exported here with its
numeric/boolean/list siblings and their types.

The LangGraph quickstart's troubleshooting advice told everyone with a
connection problem to swap `localhost` for `0.0.0.0` or `127.0.0.1`.
That is backwards for the Node runtime: `langgraphjs dev` defaults to
`--host localhost`, which Node resolves to IPv6 and binds `::1` only,
so `127.0.0.1` is refused by the same running server. The Python CLI
defaults to `--host 127.0.0.1` and behaves the other way, so the advice
is now split across the page's existing Python/TypeScript language tabs
instead of stated once in shared prose.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 14:48:49 -05:00
Mark 36f2972150 fix(a2ui-renderer): bump @a2ui/web_core to 0.10.4 for the openUrl XSS advisory
GHSA-72qq-p3r5-f7wq (CVSS 9.3). web_core <= 0.10.1 passed an agent-supplied
`openUrl` argument straight to `window.open()` with no scheme allowlist, so a
Button whose `functionCall` named a `javascript:` URI executed arbitrary script
in the host origin when a user clicked it. The Basic Catalog is the default, so
no non-default configuration was required to be exposed.

We pinned 0.9.0 exactly, as a runtime dependency of two published packages
(@copilotkit/a2ui-renderer, @copilotkit/vue) and transitively of
@copilotkit/react-core and @copilotkit/angular, so downstream users could not
upgrade out of it on their own. 0.10.4 keeps the ./v0_9 and
./v0_9/basic_catalog entrypoints we import; the only symbol dropped from v0_9
is FrameworkSignal, which we never referenced.

Add regression tests over both renderers that reach the sink independently
(React and Lit). They assert that javascript: and data: URIs never reach
window.open, that https URLs still open with noopener,noreferrer, and that a
blocked scheme leaves the surface mounted rather than escaping into the click
handler. Verified they fail against 0.9.0 and pass against 0.10.4.
2026-08-03 18:43:00 +00:00
Maxim 50e0f939b9 fix(a2ui-renderer): hoist the export test's entry import out of the test body
Follow-up to 85223276fa, which fixed the ordering bug but introduced a timing
one. Importing the source entry inside the test body meant the dynamic import
transformed the whole renderer graph (lit, markdown-it, zod) while vitest's 5s
default testTimeout was running. On a warm local cache that took ~890ms and
passed; CI, cold, took 5039ms and failed:

  × filterCatalog package export > is reachable from the package entry 5039ms
    → Test timed out in 5000ms.

Moving the import to module scope pays that cost during collection, which is
not bounded by testTimeout, and leaves the assertion synchronous.

Verified under CI-like conditions this time — both vite caches moved aside AND
dist/ removed: 16/16 pass, and the test file goes from 5059ms to 4ms with the
graph cost showing up as collect 3.57s instead.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-29 16:11:20 +02:00
Maxim 85223276fa fix(a2ui-renderer): stop the filterCatalog export test depending on its own dist
The export test self-imported the package by name:

  const mod = await import("@copilotkit/a2ui-renderer");

which resolves through node_modules to dist/. Nothing guarantees dist/ exists
when the test runs: nx.json sets test.dependsOn to ["^build"], and the caret
means *dependencies'* builds, not the project's own. Under `nx run-many` the
scheduler ran a2ui-renderer:test before a2ui-renderer:build, so the import
failed with "Failed to resolve entry for package @copilotkit/a2ui-renderer".
Standalone runs passed only because an earlier build had left dist/ populated.

Nx reported the task as flaky, which it was not — it was order-dependent. The
same root cause failed check-types, since tsc resolves the dynamic import to
dist/index.d.mts.

Importing the source entry instead keeps what the test is actually for (that
src/index.ts -> react-renderer/index.ts -> ./filter-catalog re-export chain is
intact, so callers can import filterCatalog) while making it hermetic. The
package.json "exports" mapping is already covered by this package's publint and
attw targets.

Verified with dist/ deleted: 16/16 pass and check-types is clean. Both
`nx run-many -t test` and `-t check-types` across core, react-core, runtime,
web-inspector and a2ui-renderer now pass with --skip-nx-cache.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-29 15:36:14 +02:00
github-actions[bot] 8e40a7e33c style: auto-fix formatting 2026-07-15 19:18:36 +00:00
Maxim 1e8457d889 fix(a2ui-renderer): preserve themeSchema (and functions) in filterCatalog
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 11:23:35 -07:00
Maxim 5db6ded719 chore: WIP preserve (round 2, UNVERIFIED — verify+squash pending) 2026-07-14 13:00:02 -07:00
Rainer Hahnekamp 10245a35fa fix(a2ui-renderer): guard missing catalog renderer lookup
Throw when a catalog definition has no matching renderer so createCatalog
satisfies strict check-types under Angular's tsconfig.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-17 10:49:30 -07:00
Rainer Hahnekamp e4ce502ce9 fix(a2ui-renderer): resolve web-components check-types failures
Align surface operation normalization and catalog test fixtures with the
RendererProps contract so the changed A2UI web-components pass tsc.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-17 10:49:30 -07:00
Murat Sari 6a768ab7d0 feat(angular): add a2ui for angular 2026-06-17 10:49:30 -07:00
Austin Merrick 5e3918d7e4 fix(a2ui-renderer): remove dead 0.8-era viewer files, fix check-types
A2UIViewer.tsx and theme/viewer-theme.ts were left behind by the
0.8 -> 0.9 migration: nothing imports them, they import @a2ui/lit
(no longer a dependency) and files that no longer exist, so
check-types fails on files no PR touches. Remove them along with the
now-inert @a2ui/lit external/global entries in tsdown.config.ts, and
underscore the unused type params kept on deprecated aliases for
call-site compatibility.
2026-06-10 11:54:21 -07:00
Markus Ecker 0f02aae198 fix: align A2UI schema format with v0.9 spec and improve path binding prompts
- Replace custom { name, props } schema format with spec-aligned inline
  catalog format (allOf + properties) so the LLM sees the same flat
  structure it must produce — eliminates "props" nesting confusion.
- Restructure generation prompts: inline literal values are the default,
  path binding is a narrow schema-driven exception for form inputs.
- Export InlineCatalogSchema type from a2ui-renderer.
2026-04-15 12:28:13 +02:00
Alem Tuzlak ff2093102c chore(lint): add new oxlint rules and auto-fix violations
Enable stricter oxlint rules for better code health:
- typescript/consistent-type-imports: enforce `import type` for type-only imports
- typescript/no-import-type-side-effects: prefer top-level type imports
- import/consistent-type-specifier-style: consistent type specifier placement
- typescript/no-unnecessary-type-assertion: bump to error
- react/self-closing-comp: enforce self-closing JSX components
- unicorn/prefer-optional-catch-binding: drop unused catch params
- eslint/no-useless-computed-key: simplify object keys
- unicorn/prefer-string-slice: prefer .slice() over .substring()
- unicorn/prefer-array-flat-map: prefer .flatMap() over .map().flat()

All existing violations auto-fixed via oxlint --fix.
2026-04-10 19:29:32 +02:00
Markus Ecker 93d0a76ddc feat(a2ui-renderer): A2UI v0.9 — BYOC catalogs, dark mode, component-neutral guidelines
Replace @a2ui/lit with @a2ui/web_core 0.9, introduce createCatalog() API for
custom component catalogs, add basic (18 components) and minimal (5 components)
built-in catalogs, CSS variable theming for dark mode, eliminate XSS vector
(dangerouslySetInnerHTML removed from Text component).
2026-04-08 12:48:47 -07:00
Claude 92ebd74011 fix: resolve a2ui-root CustomElementRegistry error under React Strict Mode
`@a2ui/lit` registers the "a2ui-root" custom element via Lit's
@customElement decorator as a side effect when its UI module loads.
React Strict Mode double-mounts components, and since
customElements.define() is irreversible, the second mount throws:
"the name a2ui-root has already been used with this registry"

Several a2ui-renderer files used value imports from "@a2ui/lit" when
only types were needed, pulling in the full module tree including
the custom element registration. Changed to `import type` where
possible and switched to the narrower `@a2ui/lit/0.8` subpath
(core.js only, no UI/custom element registration) where value
access is needed.

https://claude.ai/code/session_01CUPfWAF8EmLieEasaepAgp
2026-04-03 15:00:46 +00:00
Tyler Slaton 96885b5959 refactor: consolidate V1/V2 packages into flat @copilotkit/* structure
Flatten all packages from packages/v1/* and packages/v2/* into packages/* —
every package now lives directly under the @copilotkit/ scope with no v1/v2
subdirectories.

- Move all v1 packages (react-core, react-ui, runtime, shared, etc.) from
  packages/v1/* to packages/*
- Absorb v2 react code into packages/react-core/src/v2/ (exported via /v2 subpath)
- Absorb v2 agent code into packages/runtime/src/agent/ (exported via /v2 subpath)
- Move v2 packages (core, angular, demo-agents, etc.) to packages/*
- Replace all @copilotkitnext/* imports with @copilotkit/* equivalents
- Keep @copilotkitnext/angular as the sole exception (angular remains on next)
- Update CI workflows, renovate config, release scripts for flat structure
- No public API surface changes — all exports fields are preserved

Co-authored-by: Alem Tuzlak <t.zlak@hotmail.com>
Signed-off-by: Tyler Slaton <tyler@copilotkit.ai>
2026-03-28 16:45:10 -07:00