@cool-ai/beach-a2ui
v0.3.0
Published
A2UI v0.9 wire-type re-exports plus Beach-specific glue (id-order tracker, host-fit conventions). Authoring and rendering live in @a2ui/web_core / @a2ui/lit.
Readme
@cool-ai/beach-a2ui
A2UI v0.9 wire-type re-exports plus Beach-specific glue (id-order tracker, host-fit conventions). Authoring and rendering live in the A2UI ecosystem itself; this package is a thin bridge.
Home: cool-ai.org · Documentation: cool-ai.org/docs
Install
npm install @cool-ai/beach-a2ui @a2ui/web_core@a2ui/web_core is a peer dependency. Consumers using only the bridge or host-fit subpaths (no wire-shape types) need not install it.
What this package contains
The package narrowed in CAIB-101 (2026-05-01). What used to ship a parallel typed-component layer + DOM/HTML renderers now ships only Beach-specific glue and re-exports from @a2ui/web_core/v0_9. This is the consequence of the "no parallel walker" architectural commitment — A2UI's catalogue model is the canonical authoring surface, @a2ui/lit is the canonical browser renderer, and Beach contributes only what is genuinely Beach-specific.
| Subpath | What it ships |
|---|---|
| @cool-ai/beach-a2ui | Wire-shape type re-exports (SurfaceCommand, CreateSurfaceCommand, …) and SurfaceInteractionEvent from @a2ui/web_core/v0_9 |
| @cool-ai/beach-a2ui/bridge | createIdOrderTracker — Beach-specific glue for paged-update patterns (updateDataModel against indexed paths) |
| @cool-ai/beach-a2ui/host-fit | parseHostConfig + breakpoint constants — Beach's --beach-host-config viewport conventions for catalogue components |
Authoring A2UI surfaces
Author components against A2UI v0.9's open catalogue shape. Either use object literals directly:
import type { SurfaceCommand } from '@cool-ai/beach-a2ui';
const surface: SurfaceCommand[] = [
{ version: 'v0.9', createSurface: { surfaceId: 'flight-results', catalogId: 'basic' } },
{ version: 'v0.9', updateComponents: { surfaceId: 'flight-results', components: [
{ component: 'Heading', text: 'Flights to Paris', level: 2 },
{ component: 'List', items: { path: '/flights' }, template: {
component: 'Card',
children: [
{ component: 'Text', text: { path: 'flightNumber' }, variant: 'bold' },
{ component: 'Text', text: { path: 'pricePerPerson' } },
],
} },
] } },
];Or compose against catalogue-specific helpers from @cool-ai/beach-a2ui-basics, which extends @a2ui/web_core's basic catalogue with Beach-shaped primitives (Pill, etc.) registered via the catalogue mechanism.
Rendering
Browser DOM rendering is delegated entirely to @a2ui/lit:
import { A2UIClient } from '@a2ui/lit';
const client = new A2UIClient(document.getElementById('workspace')!);
client.handle(surface);Server-side HTML / plain-text rendering (for email, WhatsApp, SMS, voice) is the subject of CAIB-100 Phase 3 — @cool-ai/beach-a2ui/render-server will run @a2ui/lit under a server DOM shim (happy-dom) and serialise the resulting DOM tree per channel. Until that ships, consumers wire their own A2UI → HTML / text rendering through A2uiContentRenderer from @cool-ai/beach-format.
bridge — id-order tracker
Some progressive-update patterns receive a list of IDs early (a discover-grid populated with destinations) and per-ID detail later (hotel results for one destination). To target the later updates with a JSON-Pointer updateDataModel path, the integration layer needs the index of each ID within the original ordered list. createIdOrderTracker is the small piece of Beach-specific glue that records and looks up that mapping.
import { createIdOrderTracker } from '@cool-ai/beach-a2ui/bridge';
const tracker = createIdOrderTracker();
tracker.set('discover-grid', ['Paris', 'Rome', 'Tokyo', 'Lima']);
const idx = tracker.indexOf('discover-grid', 'Rome'); // 1
// updateDataModel path: `/destinations/${idx}/hotels`Tiny, no external dependencies, scope-it-however-the-consumer-wants.
host-fit — viewport conventions
Catalogue components that adapt to their host (chat panel vs. full-page surface vs. modal) need a uniform way to discover the host's intended sizing. parseHostConfig reads the --beach-host-config CSS custom property — a JSON blob describing breakpoints, container types, and other host hints — and returns a typed config consumers can read inside their components.
import { parseHostConfig, BREAKPOINT_NARROW } from '@cool-ai/beach-a2ui/host-fit';
const config = parseHostConfig(myComponent);
if (config.maxWidth !== undefined && config.maxWidth < BREAKPOINT_NARROW) {
// narrow-host layout
}CAIB-159 introduced this convention so catalogue components could use @container queries against the surface's allocated inline size, not the viewport. The renderer no longer applies container-type: inline-size automatically — that lived in the deleted Beach renderer; consumers who use @a2ui/lit apply the same CSS in their own stylesheet (.a2ui-surface { container-type: inline-size; }).
Coexisting with bespoke part renderers
A consumer with stateful or proprietary UI (an itinerary builder with slot-bound state, a multi-centre timeline) runs their own renderer alongside @a2ui/lit. The pattern is to dispatch envelope parts by partType:
envelopeStream.on('part', (part) => {
switch (part.partType) {
case 'a2ui-surface':
a2uiClient.handle(part.data); // @a2ui/lit
break;
case 'ta.itinerary-slot-state':
itineraryRenderer.apply(part.data); // consumer-owned
break;
}
});a2ui-surface and consumer-defined types are siblings in the envelope. Both reach the browser via the same SSE stream, dispatched by partType. Beach's scope here is the dispatch + the bridge helpers above; the actual rendering is Google's reference renderer plus consumer-owned bespoke renderers.
What this package no longer contains
CAIB-101 retired Beach's parallel A2UI layer. Specifically removed:
- Typed component constructors (
text,heading,card,button, …). Author component object literals directly or use@cool-ai/beach-a2ui-basics's catalogue helpers. - The closed
SurfaceComponentdiscriminated union (TextComponent,HeadingComponent, …). A2UI v0.9 is catalogue-driven; properties are checked at runtime against the catalogue's schema. - The vanilla-DOM
A2UIRendererandrenderHtmlserver-side renderer. Browser rendering uses@a2ui/lit; server-side rendering (HTML, plain text) lands with CAIB-100 Phase 3. - The
./builder,./renderer, and./htmlsubpath exports.
For the architectural reasoning, see the change plan at documentation/changePlans/cr-100-101-a2ui-consolidation.md.
Not in this package
- The envelope builder that includes the surface part (
@cool-ai/beach-protocol). - Channel delivery of surface messages (
@cool-ai/beach-transport). - Browser rendering (
@a2ui/lit, Google's reference). - Catalogue extensions (
@cool-ai/beach-a2ui-basics, plus consumer-defined catalogues).
Consumers
Any agent with a UI. Pure API-serving agents skip this package.
Related
- A2UI spec — the protocol this package re-exports types from.
@a2ui/web_core— the canonical type and catalogue source.@a2ui/lit— Google's reference browser renderer.@cool-ai/beach-a2ui-basics— Beach-shaped catalogue extensions.- https://cool-ai.org/docs/envelope — how surface messages travel in the envelope.
