@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 +33 -0
- package/package.json +1 -1
- package/registry.js +67 -0
- package/renderer.js +46 -0
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.
|
|
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
|
|