@adia-ai/adia-ui-forge 0.8.54 → 0.8.56

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.
@@ -114,13 +114,93 @@ stricter than the source is a defect, not documentation.
114
114
 
115
115
  Pipeline: `components.mjs` validates the shape per-yaml, cross-checks every
116
116
  referenced name against the full catalog on a full build, and forwards the
117
- lists onto `x-adiaui` → `catalog-a2ui_0_9.json`.
117
+ lists onto `x-adiaui` → `catalog-a2ui_1_0.json`.
118
118
  `scripts/build/derive-genui-catalog.mjs` then translates them into the
119
- canonical v1.0 key space (yaml `Segmented` → catalog `SegmentedControl`) on
120
- `base.json`/`adia-pack.json`, where the vendored `@genui/core` validator
121
- enforces them (`UNALLOWED_PARENT`/`UNALLOWED_CHILD`). Module-tier yamls
122
- (web-modules) carry constraints as dialect-catalog metadata only — modules
123
- have no v1.0 sidecar.
119
+ canonical v1.0 key space (yaml `Segmented` → catalog `Segmented`, canonical
120
+ per gh#2116) across the five opt-out-scoped catalogs (`adia.core.json`,
121
+ `adia.navigation.json`, `adia.data.json`, `adia.agent.json`,
122
+ `adia.shells.json`, gh#2211/ADR-0093), where the vendored `@genui/core`
123
+ validator enforces them (`UNALLOWED_PARENT`/`UNALLOWED_CHILD`). Module-tier
124
+ yamls (web-modules) now carry a v1.0 sidecar too and land in `adia.shells`.
125
+
126
+ ---
127
+
128
+ ## `examples:` field — a2ui example ids (semantic-id grammar, gh#2492)
129
+
130
+ Each `examples[].a2ui` block is a JSON array of component nodes (the same
131
+ `updateComponents.components[]` shape `.claude/docs/specs/a2ui-editor.md`
132
+ documents for the editor's live doc store). That spec's line "other
133
+ component ids are free-form (convention: `c-{n}` for generated ids)" governs
134
+ **editor-generated** ids only — ids the editor mints when a human drags a
135
+ component onto the canvas. It was never a license for **authored** ids
136
+ inside a component's own yaml examples, and treating it as one produced a
137
+ corpus-wide drift toward cryptic, positional ids (`q`, `k1`, `k1v`, `hdr`)
138
+ that don't describe what they are once an example has more than one or two
139
+ nodes — reported in gh#2492 against `blockquote.yaml`, `badge.yaml`,
140
+ `aside.yaml`, `alert.yaml`, and `anchor-bar.yaml` (the last four
141
+ corroborating it as a corpus-wide pattern, not a one-off).
142
+
143
+ **Grammar — authored `a2ui.examples[]` ids only:**
144
+
145
+ - **Kebab-case, role-descriptive.** The id names what the node IS or DOES in
146
+ the example, not its position in the array. `quote-body`, not `q` or
147
+ `node-2`.
148
+ - **Unique per example.** Scoped to one `examples[]` entry, not the whole
149
+ yaml — reusing `header` across two examples in the same file is fine;
150
+ reusing an id twice inside one example is not (the renderer's flat
151
+ `children: string[]` lookup would collide).
152
+ - **Compound ids read parent-then-role** for a node that belongs to a named
153
+ cluster: `kpi-revenue`, `kpi-revenue-value`, `kpi-revenue-label` — not
154
+ `k1`, `k1v`, `k1l`. This is what lets a reader studying the copy-paste-able
155
+ example understand the structure from the ids alone, without cross-
156
+ referencing the tree.
157
+ - **Exception — the root/wrapper id may stay short when the example has
158
+ exactly one top-level container and the short id is still a real word**,
159
+ e.g. `card`, `row`, `panel`, as long as every id it contains follows the
160
+ grammar. A single generic wrapper doesn't need `card-wrapper-root`; a
161
+ wrapper's *children* still do.
162
+ - Ids are internal wiring keys (`children: string[]` references, rendered
163
+ only as `data-a2ui-id`) — never user-visible copy — but they double as the
164
+ readable structure of the example a consumer studies, which is the whole
165
+ reason this grammar exists.
166
+
167
+ **Before / after** (`blockquote.yaml`'s `default` example, gh#2492's
168
+ reported repro):
169
+
170
+ ```jsonc
171
+ // before
172
+ [
173
+ { "id": "q", "component": "Blockquote", "cite": "…", "children": ["body"] },
174
+ { "id": "body", "component": "Text", "textContent": "Stay hungry. Stay foolish." }
175
+ ]
176
+
177
+ // after
178
+ [
179
+ { "id": "quote", "component": "Blockquote", "cite": "…", "children": ["quote-body"] },
180
+ { "id": "quote-body", "component": "Text", "textContent": "Stay hungry. Stay foolish." }
181
+ ]
182
+ ```
183
+
184
+ ```jsonc
185
+ // before (badge.yaml chart-dashboard, positional style mixed with semantic
186
+ // ids in the SAME example — k1/k1h/k1v alongside header-row/dash-title)
187
+ { "id": "k1", "component": "Card", "children": ["k1h", "k1v"] }
188
+
189
+ // after
190
+ { "id": "kpi-revenue", "component": "Card", "children": ["kpi-revenue-label", "kpi-revenue-value"] }
191
+ ```
192
+
193
+ **Enforcement**: `scripts/verify/check-example-ids.mjs` walks every yaml's
194
+ `examples[].a2ui` nodes and reports ids that fail the grammar (a bare
195
+ 1-2 char id, a `^[a-z]\d+` positional pattern like `k1`/`c2`, non-kebab-case,
196
+ or a within-example duplicate). gh#2492 Phase 2 swept the corpus-wide 526
197
+ violations across 48 files to zero and flipped the gate to `npm run
198
+ check:example-ids:strict` in the `npm run check` chain (non-zero exit on
199
+ any violation) — a new example that violates the grammar now fails the
200
+ build immediately, not just on a future sweep. Known gap: the checker's
201
+ positional-pattern regex catches `letter+digits` (`k1`, `c2`) but not a
202
+ `letter-digit-letter-digit` chain like `g1i1` — out of scope for this
203
+ sweep (nothing flagged it), left for a future refinement.
124
204
 
125
205
  ---
126
206
 
@@ -235,7 +315,7 @@ manifest format. ADR-0066 refines it three ways:
235
315
 
236
316
  - **`origin: primitive | module` on every L0 entry** — both YAML source
237
317
  roots (web-components primitives AND web-modules composites) compile into
238
- the same `catalog-a2ui_0_9.json` through one shared contract;
318
+ the same `catalog-a2ui_1_0.json` through one shared contract;
239
319
  `derive-catalog-tiers.mjs` stamps which root an entry came from onto
240
320
  `tier-index.json`. A module is legitimately a member of TWO rungs at two
241
321
  grains: its component API (props/events/slots) is L0, its assembled shell
@@ -283,6 +363,31 @@ props:
283
363
  - ghost
284
364
  ```
285
365
 
366
+ ### Synthesized universal props — `slot` / `hidden` / `ariaLive` / `traits`
367
+
368
+ `deriveProps()` (`scripts/build/derive-genui-catalog.mjs`) prepends three
369
+ props to every component's generated catalog schema before it ever reads a
370
+ yaml's own `props:` block: `slot: {type: string}`, `hidden: {type:
371
+ boolean}`, `ariaLive: {type: string}` (REQ-013 accessibility pair, gh#1353).
372
+ **No yaml SoT declares any of these** — they're synthesized, not authored,
373
+ and a sidecar that ever DOES declare one of these keys itself simply
374
+ overwrites the synthesized definition.
375
+
376
+ **Decided but not yet implemented:** ADR-0097
377
+ (`docs/ops/adr/adr-0097-traits-as-a2ui-synthesized-universal-prop.md`,
378
+ ratified via PR #2524) rules that `traits: {type: string}` becomes a fourth
379
+ member of this synthesized set, carrying the same space-separated grammar
380
+ as the existing HTML `[traits="…"]` declarative attribute
381
+ (`.claude/docs/specs/traits.md`, "Method 3" — `"ripple confetti-burst"`,
382
+ not a JSON array) — making `traits` legal on every component's A2UI wire
383
+ schema with no renderer change, and, once wired, checked by
384
+ `catalog-validator.js` against the live trait registry
385
+ (`packages/web-components/traits/_catalog.json`) with a **hard FAIL on an
386
+ unknown trait name** (the same rejection behavior the raw HTML mechanism
387
+ already has). As of this writing `deriveProps()` still synthesizes only the
388
+ three props above and `catalog-validator.js` has no trait-name check —
389
+ gh#2513 tracks the build.
390
+
286
391
  ### `required: true` field
287
392
 
288
393
  **When to use**: only for props where omitting them makes the component meaningless or inaccessible.
@@ -427,7 +532,7 @@ The build:
427
532
  **Downstream of the sidecars — two more derived artifacts (gh#970's release-PR stop):**
428
533
 
429
534
  ```bash
430
- node scripts/build/derive-genui-catalog.mjs # genui base.json + adia-pack.json derive FROM the sidecars
535
+ node scripts/build/derive-genui-catalog.mjs # genui's five opt-out-scoped catalogs derive FROM the sidecars
431
536
  npm run check:genui-catalog # the drift gate that fails PR CI if you skip the above
432
537
  ```
433
538