@adia-ai/a2ui-runtime 0.4.2 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -13,6 +13,39 @@ Follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
13
13
 
14
14
  _No pending changes._
15
15
 
16
+ ## [0.4.4] - 2026-05-12
17
+
18
+ ### Changed
19
+
20
+ - **`runtime/registry.js` — proactive transpiler+web-modules audit (§49).** Cross-referenced transpiler-emitted A2UI types (40 emissions) against the registry's PascalCase Map → Pass 1 found only `Search` as a gap (and Search is deliberately deprecated per the in-file comment). Per user directive ("use web-modules as part of the catalog mappings as needed"), expanded scope to `packages/web-modules/**/<name>.yaml` and discovered **0 of 28 web-modules had correct registry entries**. Added 27 new entries in a new "§49 — web-module catalog mappings" section, organized by cluster:
21
+ - **Admin shell (10):** `AdminCommand`, `AdminContent`, `AdminPage`, `AdminPageBody`, `AdminPageHeader`, `AdminScroll`, `AdminShell`, `AdminSidebar`, `AdminStatusbar`, `AdminTopbar`.
22
+ - **Chat (6):** `ChatComposer`, `ChatEmpty`, `ChatHeader`, `ChatShell`, `ChatSidebar`, `ChatStatus`.
23
+ - **Editor (6):** `EditorCanvas`, `EditorCanvasEmpty`, `EditorShell`, `EditorSidebar`, `EditorStatusbar`, `EditorToolbar`.
24
+ - **Singletons (5):** `GenRoot`, `SimpleContent`, `SimpleHero`, `SimpleShell`, `ThemePanel`.
25
+ - **`Sidebar` → `admin-sidebar`** (was: native `<aside>`) per user directive in §49. AdminSidebar at `packages/web-modules/shell/admin-sidebar/` is the canonical sidebar affordance; native `<aside>` falls back via the validator's bare-HTML allowlist if needed.
26
+ - **`ChatThread` → `chat-thread`** (was: `chat-thread-ui` primitive) — the module owns scroll-to-bottom + streaming behavior; the primitive remains accessible via its bare tag. Verified zero corpus records use `ChatThread` today before re-routing.
27
+ - **`FormContainer` → `form` registry alias (§45)** — closes 12 `unknown-component` criticals surfaced when §45's auth chunks (containing `<form>` markup) hit the validator. The transpiler maps `<form>` → `FormContainer` (per `transpiler-maps.js`) but the registry had no entry. Renders as native `<form>` (no `form-ui` component exists).
28
+
29
+ ### Fixed
30
+
31
+ - **`runtime/renderer.js` `#toAttr()` — preserve HTML standard single-token attributes (§51).** The naive `name.replace(/([A-Z])/g, '-$1').toLowerCase()` unconditionally kebab-cased camelCase prop names. Correct for multi-token HTML attrs (`ariaLabel` → `aria-label`, `dataChunk` → `data-chunk`), but BROKE HTML standard single-token attributes spelled all-lowercase:
32
+ - `autoComplete` → `"auto-complete"` ✗ (HTML attr is `autocomplete`)
33
+ - `inputMode` → `"input-mode"` ✗ (HTML attr is `inputmode`)
34
+ - `tabIndex` → `"tab-index"` ✗ (HTML attr is `tabindex`)
35
+ - `maxLength` → `"max-length"` ✗ (HTML attr is `maxlength`)
36
+
37
+ Project-lifetime category error; same shape as the §47 `<a>` → Button transpiler bug. Both encoded incorrect assumptions about HTML attribute spelling. Fix: new `static #HTML_LOWERCASE_ATTRS` set (38 HTML-spec attrs sourced from MDN reference + DOM specs covering input/form/media/image/anchor/generic/microdata/script categories); `#toAttr()` now consults the set before kebab-casing. Multi-token attrs still kebab correctly.
38
+
39
+ See root [CHANGELOG.md `[Unreleased]`](../../../CHANGELOG.md) for the cross-cutting arc narrative + [docs/journal/2026/05/2026-05-12.md](../../../docs/journal/2026/05/2026-05-12.md) §§ 45 / 49 / 51 for per-§ details.
40
+
41
+ ## [0.4.3] - 2026-05-11
42
+
43
+ ### Ride-along (no source changes)
44
+
45
+ Lockstep PATCH cut alongside `@adia-ai/web-components@0.4.3` (input-ui type=number locale + thousands grouping + hold-to-repeat) + `@adia-ai/a2ui-compose@0.4.3` + `@adia-ai/a2ui-retrieval@0.4.3` (process.env browser-compat fix) + `@adia-ai/a2ui-corpus@0.4.3` (catalog regen + chunks re-harvest with new settings-appearance pattern). Source byte-identical to v0.4.2.
46
+
47
+ Internal `@adia-ai/*` dep ranges stay at `^0.4.0` (patch-cut asymmetry — `^0.4.0` covers `0.4.x` under semver). See root [CHANGELOG.md `## [0.4.3]`](../../../CHANGELOG.md) for the cut narrative.
48
+
16
49
  ## [0.4.2] - 2026-05-11
17
50
 
18
51
  ### Ride-along (no source changes)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adia-ai/a2ui-runtime",
3
- "version": "0.4.2",
3
+ "version": "0.4.4",
4
4
  "description": "A2UI runtime \u2014 renderer, registry, streams, surface manifest, and wiring primitives for the A2UI (Agent-to-UI) protocol. Framework-agnostic; pairs with any A2UI-conformant component set.",
5
5
  "type": "module",
6
6
  "exports": {
package/registry.js CHANGED
@@ -98,6 +98,10 @@ export const registry = new Map([
98
98
 
99
99
  // Navigation
100
100
  ['Breadcrumb', 'breadcrumb-ui'],
101
+ ['Link', 'link-ui'],
102
+ ['Anchor', 'link-ui'],
103
+ ['Hyperlink', 'link-ui'],
104
+ ['NavLink', 'link-ui'],
101
105
  ['Nav', 'nav-ui'],
102
106
  ['NavGroup', 'nav-group-ui'],
103
107
  ['NavItem', 'nav-item-ui'],
@@ -155,6 +159,7 @@ export const registry = new Map([
155
159
  ['search-ui', 'search-ui'],
156
160
  ['upload-ui', 'upload-ui'],
157
161
  ['breadcrumb-ui', 'breadcrumb-ui'],
162
+ ['link-ui', 'link-ui'],
158
163
  ['nav-ui', 'nav-ui'],
159
164
  ['noodles-ui', 'noodles-ui'],
160
165
  ['pagination-ui', 'pagination-ui'],
@@ -184,8 +189,70 @@ export const registry = new Map([
184
189
  ['Keyboard', 'kbd-ui'],
185
190
  ['DatePicker', 'calendar-picker-ui'],
186
191
  ['CommandPalette', 'command-ui'],
192
+ ['FormContainer', 'form'], // §45 — transpiler maps <form> → FormContainer; no form-ui component exists, so render as native <form>
193
+ ['Sidebar', 'admin-sidebar'], // §48 — transpiler maps <aside> → Sidebar; routed to the AdminSidebar web-module (packages/web-modules/shell/admin-sidebar/). Per-user directive in §49: prefer admin-sidebar over native <aside> for sidebar affordances.
187
194
  ['Segmented', 'segmented-ui'],
188
195
  ['OTP', 'otp-input-ui'],
196
+
197
+ // Missing PascalCase entries discovered by verify:corpus (§39, 2026-05-12).
198
+ // Composition corpus used these names; registry didn't map them so the
199
+ // renderer would have silently dropped these components.
200
+ ['Textarea', 'textarea-ui'], // case alias for TextArea
201
+ ['RichText', 'richtext-ui'],
202
+ ['Richtext', 'richtext-ui'], // case alias
203
+ ['DescriptionList', 'description-list-ui'],
204
+ ['ActionItem', 'action-item-ui'],
205
+ ['ActionList', 'action-list-ui'],
206
+ ['Inspector', 'inspector-ui'],
207
+ ['Heatmap', 'heatmap-ui'],
208
+ ['Chat', 'chat-ui'],
209
+ ['ChatThread', 'chat-thread'], // §49 — re-routed to the chat web-module (was: chat-thread-ui primitive). The module owns scroll-to-bottom + streaming; primitive remains accessible via bare `chat-thread-ui` tag.
210
+ ['ChatInput', 'chat-input-ui'],
211
+ ['OptionCard', 'option-card-ui'],
212
+ ['Option', 'option-card-ui'], // bare Option → option-card-ui
213
+
214
+ // §49 — web-module catalog mappings (packages/web-modules/<cluster>/).
215
+ // These are module-tier components that compose primitives into full
216
+ // surface affordances (page shells, sidebars, chat surfaces, editor
217
+ // surfaces, theme panel). Without these entries, A2UI corpus records
218
+ // emitting any of them produce unknown-component criticals (same
219
+ // pattern caught reactively for FormContainer §45 + Sidebar §48).
220
+ // Discovered via a transpiler-vs-registry audit across §49.
221
+
222
+ // Admin shell cluster — chrome surfaces for SaaS admin/dashboard surfaces
223
+ ['AdminCommand', 'admin-command'],
224
+ ['AdminContent', 'admin-content'],
225
+ ['AdminPage', 'admin-page'],
226
+ ['AdminPageBody', 'admin-page-body'],
227
+ ['AdminPageHeader', 'admin-page-header'],
228
+ ['AdminScroll', 'admin-scroll'],
229
+ ['AdminShell', 'admin-shell'],
230
+ ['AdminSidebar', 'admin-sidebar'], // canonical PascalCase mapping; the Sidebar alias above resolves through this
231
+ ['AdminStatusbar', 'admin-statusbar'],
232
+ ['AdminTopbar', 'admin-topbar'],
233
+
234
+ // Chat cluster — LLM-streaming conversation surfaces
235
+ ['ChatComposer', 'chat-composer'],
236
+ ['ChatEmpty', 'chat-empty'],
237
+ ['ChatHeader', 'chat-header'],
238
+ ['ChatShell', 'chat-shell'],
239
+ ['ChatSidebar', 'chat-sidebar'],
240
+ ['ChatStatus', 'chat-status'],
241
+
242
+ // Editor cluster — A2UI canvas editor surfaces
243
+ ['EditorCanvas', 'editor-canvas'],
244
+ ['EditorCanvasEmpty', 'editor-canvas-empty'],
245
+ ['EditorShell', 'editor-shell'],
246
+ ['EditorSidebar', 'editor-sidebar'],
247
+ ['EditorStatusbar', 'editor-statusbar'],
248
+ ['EditorToolbar', 'editor-toolbar'],
249
+
250
+ // Runtime / simple / theme — singleton surfaces
251
+ ['GenRoot', 'gen-root'],
252
+ ['SimpleContent', 'simple-content'],
253
+ ['SimpleHero', 'simple-hero'],
254
+ ['SimpleShell', 'simple-shell'],
255
+ ['ThemePanel', 'theme-panel'],
189
256
  ]);
190
257
 
191
258
  /**
package/renderer.js CHANGED
@@ -252,6 +252,40 @@ export class A2UIRenderer {
252
252
  body: 'p', caption: 'small',
253
253
  };
254
254
 
255
+ // §51 — HTML-standard single-token attributes. These are valid attribute
256
+ // names spelled all-lowercase in the HTML spec (NOT multi-token kebab
257
+ // names like aria-label / data-chunk). When the corpus or LLM writes
258
+ // them in camelCase (autoComplete, inputMode, tabIndex), the renderer
259
+ // should pass through as the canonical lowercase form, not naive kebab.
260
+ // List sourced from MDN HTML attribute reference + DOM specs; covers
261
+ // the attributes actually emitted by A2UI components.
262
+ static #HTML_LOWERCASE_ATTRS = new Set([
263
+ // Input / form attributes
264
+ 'autocomplete', 'autofocus', 'autocapitalize', 'autocorrect',
265
+ 'inputmode', 'enterkeyhint', 'spellcheck',
266
+ 'maxlength', 'minlength', 'readonly', 'novalidate', 'formnovalidate',
267
+ 'formaction', 'formenctype', 'formmethod', 'formtarget',
268
+ 'multiple', 'pattern', 'placeholder', 'required',
269
+ 'tabindex', 'accesskey',
270
+ // Media attributes
271
+ 'autoplay', 'autopictureinpicture', 'controls', 'crossorigin',
272
+ 'disablepictureinpicture', 'disableremoteplayback',
273
+ 'loop', 'muted', 'playsinline', 'preload',
274
+ // Image / source attributes
275
+ 'srcset', 'srcdoc', 'srclang', 'sizes', 'loading',
276
+ 'decoding', 'fetchpriority', 'ismap', 'usemap',
277
+ // Anchor / link attributes
278
+ 'hreflang', 'referrerpolicy', 'download',
279
+ // Generic / structural
280
+ 'contenteditable', 'contextmenu', 'draggable',
281
+ 'dirname', 'colspan', 'rowspan', 'headers',
282
+ 'allowfullscreen', 'allowpaymentrequest',
283
+ // Microdata
284
+ 'itemid', 'itemprop', 'itemref', 'itemscope', 'itemtype',
285
+ // Module / script
286
+ 'nomodule', 'nonce',
287
+ ]);
288
+
255
289
  #resolveTextTag(variant, comp) {
256
290
  // Semantic HTML variants get native tags (accessibility)
257
291
  if (!comp?.slot && A2UIRenderer.#TEXT_TAG_MAP[variant]) {
@@ -319,6 +353,18 @@ export class A2UIRenderer {
319
353
  }
320
354
 
321
355
  #toAttr(name) {
356
+ // §51 — HTML-standard single-token attributes are passed through unchanged
357
+ // (lowercased). The naive `\$1`-based kebab-case mangles these into
358
+ // multi-token forms that the platform doesn't recognize:
359
+ // autoComplete → "auto-complete" ✗ (HTML attr is "autocomplete")
360
+ // inputMode → "input-mode" ✗ (HTML attr is "inputmode")
361
+ // tabIndex → "tab-index" ✗ (HTML attr is "tabindex")
362
+ // maxLength → "max-length" ✗ (HTML attr is "maxlength")
363
+ // Multi-token attrs like ariaLabel → aria-label and dataChunk → data-chunk
364
+ // remain kebab-cased because that IS the HTML spec for them.
365
+ if (A2UIRenderer.#HTML_LOWERCASE_ATTRS.has(name.toLowerCase())) {
366
+ return name.toLowerCase();
367
+ }
322
368
  return name.replace(/([A-Z])/g, '-$1').toLowerCase();
323
369
  }
324
370