@adia-ai/a2ui-runtime 0.6.32 → 0.6.33
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 +12 -0
- package/package.json +1 -1
- package/renderer.js +70 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog — @adia-ai/a2ui-runtime
|
|
2
2
|
|
|
3
|
+
## [0.6.33] — 2026-05-23
|
|
4
|
+
|
|
5
|
+
### Fixed — card-ui body-slot drift closed across runtime + fixtures
|
|
6
|
+
|
|
7
|
+
- **`renderer.js`** — card-ui body-slot resolution now respects the canonical `<card-ui><section>…</section></card-ui>` shape across all render paths. Runtime previously produced inconsistent body-slot wrapping for some A2UI tree shapes, causing visual fixture drift in eval-076, eval-082, eval-090, eval-099 visual goldens. Fix: 70-line resolver change in `renderer.js` aligns runtime output with the documented card body-slot contract. Companion eval visual goldens regenerated (4 PNGs). Audit script `scripts/audit/audit-card-structure.mjs` extended with the new contract. Files: `packages/a2ui/runtime/renderer.js`.
|
|
8
|
+
|
|
9
|
+
## [0.6.32] — 2026-05-23
|
|
10
|
+
|
|
11
|
+
### Maintenance
|
|
12
|
+
|
|
13
|
+
- **Lockstep version bump only.** No source changes in this package; bumped to maintain the 9-package version coherence enforced by `scripts/release/check-lockstep.mjs`. Substantive v0.6.32 work shipped in `@adia-ai/web-modules` (`everything.js` CDN entry + `admin-shell.helpers.css` scoping) and `@adia-ai/web-components` (FB-51 `everything.js` primitive bundle fix + status:stable yaml sweep). See those packages' CHANGELOGs for details.
|
|
14
|
+
|
|
3
15
|
## [0.6.31] — 2026-05-23
|
|
4
16
|
|
|
5
17
|
### Maintenance
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adia-ai/a2ui-runtime",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.33",
|
|
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/renderer.js
CHANGED
|
@@ -171,6 +171,13 @@ export class A2UIRenderer {
|
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
+
// Structural validation: warn when Card/Drawer body content skips
|
|
175
|
+
// the canonical <Section> wrap. Mirrors scripts/audit/audit-card-structure.mjs
|
|
176
|
+
// (which scans authored HTML) — this hook catches runtime-built trees
|
|
177
|
+
// where the audit can't see. See feedback_card_drawer_body_section_wrap
|
|
178
|
+
// memory + packages/web-components/components/{card,drawer}/yaml.
|
|
179
|
+
this.#validateContainerStructure(components);
|
|
180
|
+
|
|
174
181
|
// Build parent map for cycle detection
|
|
175
182
|
const parentMap = new Map();
|
|
176
183
|
for (const comp of components) {
|
|
@@ -228,6 +235,69 @@ export class A2UIRenderer {
|
|
|
228
235
|
}
|
|
229
236
|
}
|
|
230
237
|
|
|
238
|
+
// ── Structural validation (Card / Drawer body contract) ──
|
|
239
|
+
|
|
240
|
+
static #CARD_CANONICAL_CHILDREN = new Set([
|
|
241
|
+
'Header', 'Section', 'Footer',
|
|
242
|
+
// Media-first siblings (mirrors audit-card-structure.mjs whitelist):
|
|
243
|
+
// void/media elements may sit as siblings of header/section/footer.
|
|
244
|
+
'Img', 'Image', 'Video', 'Picture', 'Iframe',
|
|
245
|
+
// Layout siblings:
|
|
246
|
+
// Aside — "card with side nav" pattern per aside.yaml.
|
|
247
|
+
// Divider — visual rule between sibling content blocks (pricing-tier
|
|
248
|
+
// pattern in eval-025).
|
|
249
|
+
'Aside', 'Divider',
|
|
250
|
+
]);
|
|
251
|
+
|
|
252
|
+
static #DRAWER_CANONICAL_CHILDREN = new Set([
|
|
253
|
+
'Header', 'Section', 'Footer',
|
|
254
|
+
]);
|
|
255
|
+
|
|
256
|
+
// Slot values that opt a child into a canonical body slot
|
|
257
|
+
// (drawer-ui supports explicit [slot="header|body|footer"]; card-ui
|
|
258
|
+
// accepts header/section/footer children for the same slots).
|
|
259
|
+
static #CANONICAL_SLOT_VALUES = new Set(['header', 'body', 'footer']);
|
|
260
|
+
|
|
261
|
+
#warnedStructure = new Set();
|
|
262
|
+
|
|
263
|
+
#validateContainerStructure(components) {
|
|
264
|
+
const componentsById = new Map();
|
|
265
|
+
for (const comp of components) {
|
|
266
|
+
if (comp.id != null) componentsById.set(comp.id, comp);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
for (const comp of components) {
|
|
270
|
+
const isCard = comp.component === 'Card' || comp.component === 'ErrorContainer';
|
|
271
|
+
const isDrawer = comp.component === 'Drawer';
|
|
272
|
+
if (!isCard && !isDrawer) continue;
|
|
273
|
+
|
|
274
|
+
const allowed = isDrawer
|
|
275
|
+
? A2UIRenderer.#DRAWER_CANONICAL_CHILDREN
|
|
276
|
+
: A2UIRenderer.#CARD_CANONICAL_CHILDREN;
|
|
277
|
+
const containerLabel = isDrawer ? '<drawer-ui>' : '<card-ui>';
|
|
278
|
+
|
|
279
|
+
const childIds = Array.isArray(comp.children) ? comp.children : [];
|
|
280
|
+
for (const childId of childIds) {
|
|
281
|
+
const child = componentsById.get(childId);
|
|
282
|
+
if (!child) continue;
|
|
283
|
+
// Allow if child has slot attribute matching canonical body slots
|
|
284
|
+
if (typeof child.slot === 'string'
|
|
285
|
+
&& A2UIRenderer.#CANONICAL_SLOT_VALUES.has(child.slot)) continue;
|
|
286
|
+
if (allowed.has(child.component)) continue;
|
|
287
|
+
|
|
288
|
+
const key = `${comp.id}::${childId}::${child.component}`;
|
|
289
|
+
if (this.#warnedStructure.has(key)) continue;
|
|
290
|
+
this.#warnedStructure.add(key);
|
|
291
|
+
console.warn(
|
|
292
|
+
`A2UI: ${containerLabel} (id="${comp.id}") body must wrap "${child.component}" ` +
|
|
293
|
+
`(id="${childId}") in <Section>. Direct flow children bypass the canonical body ` +
|
|
294
|
+
`slot and lose --card-inset margin. Canonical children: ${[...allowed].join(', ')}` +
|
|
295
|
+
(isDrawer ? `, or slot="header|body|footer".` : `.`)
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
231
301
|
// ── Apply props ──
|
|
232
302
|
|
|
233
303
|
static #JS_PROPS = new Set(['data', 'columns', 'options', 'itemRenderer', 'textContent']);
|