@adia-ai/adia-ui-forge 0.8.41 → 0.8.43
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/.claude-plugin/plugin.json +2 -2
- package/CHANGELOG.md +18 -0
- package/package.json +1 -1
- package/skills/a2ui-maintenance/SKILL.md +17 -0
- package/skills/a2ui-maintenance/references/surface-lifecycle.md +73 -0
- package/skills/demo-audit/references/admin-shell-anatomy.md +1 -1
- package/skills/gen-ui-review/references/corpus-html-patterns.md +3 -3
- package/skills/gen-ui-review/scripts/gen-review-decompose.mjs +1 -1
- package/skills/primitive-authoring/references/primitive-audit.md +1 -1
- package/skills/primitive-authoring/references/svg-authoring.md +27 -22
- package/skills/primitive-authoring/references/token-contract.md +46 -1
- package/skills/primitive-authoring/references/yaml-contract.md +74 -1
- package/skills/site-deployment/references/deploy-playbooks.md +12 -4
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "adia-ui-kit-forge",
|
|
3
|
-
"version": "0.8.
|
|
4
|
-
"description": "Maintain the adia-ui (@adia-ai) framework itself \u2014 author primitives and shells, run the A2UI generation pipeline and its corpus, review gen-UI quality, sweep QA, cut releases, deploy. The maintainer counterpart to adia-factory (the consumer/app-author plugin).",
|
|
3
|
+
"version": "0.8.43",
|
|
4
|
+
"description": "Maintain the adia-ui (@adia-ai) framework itself \u2014 author primitives and shells, run the A2UI generation pipeline and its corpus, review gen-UI quality, sweep QA, cut releases, deploy. The maintainer counterpart to adia-ui-kit-factory (the consumer/app-author plugin).",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Kim",
|
|
7
7
|
"email": "kim.granlund@adia.ai"
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Changelog — adia-ui-kit-forge
|
|
2
2
|
|
|
3
|
+
## [0.8.43] — 2026-08-18
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
- Knowledge packs harvested for ADR-0061..0074: surface-lifecycle reference (a2ui-maintenance), site-package-registry playbook, attribute-grammar/role-class/tier-model sections, disabled-state token convention (gh#1564, #1609, #1625).
|
|
7
|
+
- primitive-authoring/gen-ui-review references migrated off cut attributes (`hide-*` → `no-*`) so agent-authored demos stop reintroducing them (gh#1617, #1626).
|
|
8
|
+
- token-selection references regenerated for the `--a-ui-bg-disabled` container-low retarget (gh#1596, #1599).
|
|
9
|
+
|
|
10
|
+
### Maintenance
|
|
11
|
+
- **`.claude-plugin/plugin.json` version bump** — moves in lockstep with package.json (the `/plugin update` cache key).
|
|
12
|
+
- **`skills/` touched in this release window** (5 file(s), e.g. `references/corpus-html-patterns.md`) — carried by the entries above.
|
|
13
|
+
|
|
14
|
+
## [0.8.42] — 2026-08-17
|
|
15
|
+
|
|
16
|
+
### Maintenance
|
|
17
|
+
- Knowledge packs harvest the ADR-0061..0070 ratifications (PR #1564: gen-ui-wiring + wave-coordination corpora); rename-wave W2 doc migration (PR #1567).
|
|
18
|
+
- **`.claude-plugin/plugin.json` version bump** — moves in lockstep with package.json (the `/plugin update` cache key).
|
|
19
|
+
- **`skills/` touched in this release window** (7 file(s), e.g. `a2ui-maintenance/SKILL.md`) — carried by the entries above.
|
|
20
|
+
|
|
3
21
|
## [0.8.41] — 2026-08-17
|
|
4
22
|
|
|
5
23
|
### Added
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adia-ai/adia-ui-forge",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.43",
|
|
4
4
|
"description": "Maintain the adia-ui (@adia-ai) framework itself \u2014 author primitives and shells, run the A2UI generation pipeline and its corpus, review gen-UI quality, sweep QA, cut releases, deploy. The maintainer counterpart to adia-factory (the consumer/app-author plugin).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"adia-ui",
|
|
@@ -41,6 +41,22 @@ surface `catalogId` → error, no registry default). The producer's
|
|
|
41
41
|
dialect-shaped; the bridge owns the translation — never hand-write Candidate
|
|
42
42
|
envelopes from this skill's surfaces.
|
|
43
43
|
|
|
44
|
+
site-a2ui (the build-time HTML→A2UI docs-site transpile) is RULED fit as the
|
|
45
|
+
**dialect side's regression corpus**, not a v1.0 conformance bed (ADR-0068):
|
|
46
|
+
it exercises the dialect renderer, the ADR-0061 lifecycle path, and the
|
|
47
|
+
engine transpiler at real-content scale in production, but never touches the
|
|
48
|
+
producer, the bridge, or the `wireFormat` flag — so it neither blocks the
|
|
49
|
+
v1.0 migration nor gets re-pointed at the v1 wire. **Named expiry:** that
|
|
50
|
+
ruling is load-bearing on `wireFormat` defaulting to `'dialect'`; the flag-flip
|
|
51
|
+
ADR that makes `'v1'` the shipping default MUST re-rule site-a2ui's fitness
|
|
52
|
+
(re-point vs retirement-by-attrition) — the fitness verdict expires with the
|
|
53
|
+
`'dialect'` default. Expanding site-a2ui — new message kinds, new consumers,
|
|
54
|
+
or a promotion PROGRAM toward all routes — also invalidates the ruling's
|
|
55
|
+
basis and needs a new decision; burn-down of existing
|
|
56
|
+
`visual-drift`/`blocked-format-gap` rows (including a route thereby becoming
|
|
57
|
+
parity-promoted) is ordinary maintenance and stays permitted (ADR-0068
|
|
58
|
+
Decision 5).
|
|
59
|
+
|
|
44
60
|
## Route by task shape
|
|
45
61
|
|
|
46
62
|
| Task shape | Load |
|
|
@@ -55,6 +71,7 @@ envelopes from this skill's surfaces.
|
|
|
55
71
|
| Add or change an MCP tool | [mcp-tool-reference](references/mcp-tool-reference.md) |
|
|
56
72
|
| Tune the anti-pattern catalogue | [anti-patterns](references/anti-patterns.md) |
|
|
57
73
|
| A component's contract can't express a content shape — decide how to extend it | [format-extension-decisions](references/format-extension-decisions.md) |
|
|
74
|
+
| Surface regeneration, pending/stale rendering, the `doc`-setter replace bracket | [surface-lifecycle](references/surface-lifecycle.md) (ADR-0061) |
|
|
58
75
|
|
|
59
76
|
Unmatched work defaults to pipeline-overview and re-classifies from there.
|
|
60
77
|
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Surface lifecycle — the runtime pending/stale contract (ADR-0061)
|
|
2
|
+
|
|
3
|
+
The renderer runtime (`packages/gen-ui/a2ui/`) owns a per-surface lifecycle
|
|
4
|
+
state machine, ratified by ADR-0061
|
|
5
|
+
(`docs/ops/adr/adr-0061-surface-lifecycle-pending-stale.md`; requirements and
|
|
6
|
+
build order in `docs/ops/spec/spec-a2ui-surface-lifecycle.md`). Load this file
|
|
7
|
+
when a change touches surface regeneration, `<a2ui-root>`'s `doc` setter,
|
|
8
|
+
pending/stale rendering, or a host's update bracketing.
|
|
9
|
+
|
|
10
|
+
## The state machine
|
|
11
|
+
|
|
12
|
+
```text
|
|
13
|
+
empty → pending-first → live → pending-stale → live
|
|
14
|
+
└→ error-empty └→ error-stale
|
|
15
|
+
(both error-* heal on the next successful commit)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
- **Pending is per-surface, never global.** Each renderer surface record
|
|
19
|
+
carries its own machine; one surface regenerating never dims another.
|
|
20
|
+
- **Latest-generation-wins arbitration.** When two update brackets race on
|
|
21
|
+
one surface, the newest generation's commit wins; a superseded bracket's
|
|
22
|
+
messages are discarded, not interleaved.
|
|
23
|
+
- **Stale content stays visible.** In `pending-stale` and `error-stale` the
|
|
24
|
+
previous answer keeps rendering — the blank-flash reset+replay shape is
|
|
25
|
+
what this contract retired. Error state heals: the next successful commit
|
|
26
|
+
clears `error-*`.
|
|
27
|
+
|
|
28
|
+
## The host API
|
|
29
|
+
|
|
30
|
+
Four public runtime methods drive the machine — `beginSurfaceUpdate` /
|
|
31
|
+
`applyTo` / `commitSurfaceUpdate` / `abortSurfaceUpdate`. Messages arriving
|
|
32
|
+
inside a bracket buffer and apply atomically at commit. A `replace`-mode
|
|
33
|
+
commit sweeps components the new answer no longer declares — the ONLY place
|
|
34
|
+
removal semantics exist; outside a bracket, `updateComponents` upserts
|
|
35
|
+
exactly as before, so unbracketed streams and hosts are behavior-identical
|
|
36
|
+
to the pre-lifecycle runtime (strictly additive, ADR-0061 Decision 4).
|
|
37
|
+
`<a2ui-root>`'s `doc` setter routes through this replace bracket
|
|
38
|
+
(`replaceDoc`) rather than reset+replay — a deliberate, ratified behavior
|
|
39
|
+
change for doc-setting hosts (ADR-0061 OD-2).
|
|
40
|
+
|
|
41
|
+
## The DOM contract
|
|
42
|
+
|
|
43
|
+
Staleness is exposed as one attribute plus three events, never styling:
|
|
44
|
+
|
|
45
|
+
- **`data-a2ui-lifecycle`** — a single enum attribute on the surface root
|
|
46
|
+
reflecting the current state. This is the `data-a2ui-*` prefix's FIRST
|
|
47
|
+
ratification (the pre-existing `data-a2ui-surface` stamp was accidental,
|
|
48
|
+
now ratified alongside it) — the runtime-owned `data-*` tier, sibling to
|
|
49
|
+
ADR-0060's trait tier.
|
|
50
|
+
- **Three bubbling CustomEvents** mark the transitions.
|
|
51
|
+
- Hosts and primitives style off the attribute with semantic tokens: stale
|
|
52
|
+
content dims; skeletons (the existing `skeleton` primitive) appear only in
|
|
53
|
+
`pending-first`. `@adia-ai/a2ui` ships state, never styling, and stays
|
|
54
|
+
zero-dependency.
|
|
55
|
+
|
|
56
|
+
## Layer boundary (ADR-0059)
|
|
57
|
+
|
|
58
|
+
The lifecycle is renderer-runtime work on gen-ui-kit's side of the ADR-0059
|
|
59
|
+
line. The three wire envelope kinds (`beginSurfaceUpdate` /
|
|
60
|
+
`commitSurfaceUpdate` / `abortSurfaceUpdate` as v1.0 server kinds) are a
|
|
61
|
+
genui-system standard PROPOSAL, not dialect schema — `a2ui.schema.json`
|
|
62
|
+
gains nothing, the dialect wire format is byte-identical, and stream-driven
|
|
63
|
+
regeneration waits on the upstream standard (the dialect escape hatch was
|
|
64
|
+
explicitly denied at ratification). Never hand-write lifecycle envelopes
|
|
65
|
+
from this skill's surfaces; the Bridge owns the mapping when the standard
|
|
66
|
+
lands.
|
|
67
|
+
|
|
68
|
+
## Interlock worth knowing
|
|
69
|
+
|
|
70
|
+
The v1.0 conformance program's duplicate-`surfaceId` error (REQ-002)
|
|
71
|
+
sequences AFTER this API — the silent `createSurface` no-op it removes was
|
|
72
|
+
previously the only wire-visible re-target path, and the lifecycle bracket
|
|
73
|
+
is its sanctioned replacement.
|
|
@@ -21,7 +21,7 @@ the live admin-dashboard example.
|
|
|
21
21
|
a bare `<nav-ui>` direct child overflows long lists
|
|
22
22
|
5. Sidebar `<admin-statusbar slot="footer">` with `<select-ui avatar="…">`
|
|
23
23
|
(user menu) — ★ commonly missing
|
|
24
|
-
6. Sidebar `<div data-resize></div>` — REQUIRED when `resizable` is on
|
|
24
|
+
6. Sidebar `<div data-sidebar-resize></div>` — REQUIRED when `resizable` is on
|
|
25
25
|
7. `<admin-content>` inner `<admin-topbar>` containing
|
|
26
26
|
`<button-ui data-sidebar-toggle="leading" icon="sidebar">` +
|
|
27
27
|
`<breadcrumb-ui>` + `<span data-spacer>` + `<div data-actions>` —
|
|
@@ -139,12 +139,12 @@ col-ui midpoint, landing it beside the description instead of the title.
|
|
|
139
139
|
**WORKS** — the renderer JSON-parses string JS_PROPS before assignment:
|
|
140
140
|
|
|
141
141
|
```html
|
|
142
|
-
<chart-ui type="bar" x="month" y="revenue"
|
|
142
|
+
<chart-ui type="bar" x="month" y="revenue" no-values
|
|
143
143
|
data='[{"month":"Jan","revenue":3200},{"month":"Feb","revenue":4100}]'>
|
|
144
144
|
</chart-ui>
|
|
145
145
|
```
|
|
146
146
|
|
|
147
|
-
Include 4–6 data points; `
|
|
147
|
+
Include 4–6 data points; `no-values` when the canvas is too narrow for labels.
|
|
148
148
|
|
|
149
149
|
### image-ui: data URIs, never external URLs
|
|
150
150
|
|
|
@@ -153,7 +153,7 @@ rectangle. Use either a sparkline placeholder (renders immediately, no network):
|
|
|
153
153
|
|
|
154
154
|
```html
|
|
155
155
|
<section bleed>
|
|
156
|
-
<chart-ui type="sparkline" x="t" y="v" color="accent"
|
|
156
|
+
<chart-ui type="sparkline" x="t" y="v" color="accent" no-values
|
|
157
157
|
data='[{"t":1,"v":60},{"t":2,"v":80},{"t":3,"v":45}]'
|
|
158
158
|
style="height:160px"></chart-ui>
|
|
159
159
|
</section>
|
|
@@ -148,7 +148,7 @@ const TAG_TO_COMPONENT = {
|
|
|
148
148
|
'chat-input-ui': 'ChatInput',
|
|
149
149
|
'chat-thread-ui': 'ChatThread',
|
|
150
150
|
'color-input-ui': 'ColorInput',
|
|
151
|
-
'color-
|
|
151
|
+
'color-area-ui': 'ColorArea',
|
|
152
152
|
'command-ui': 'Command',
|
|
153
153
|
'context-menu-ui': 'ContextMenu',
|
|
154
154
|
'date-range-picker-ui': 'DateRangePicker',
|
|
@@ -66,7 +66,7 @@ Treat this as the default lookup table. **If your affordance maps to a row here,
|
|
|
66
66
|
| Modal / drawer / toast | `modal-ui` / `drawer-ui` / `toast-ui` |
|
|
67
67
|
| Switch / checkbox / radio / segmented / toggle group | `switch-ui` / `check-ui` / `radio-ui` / `segmented-ui` / `toggle-group-ui` |
|
|
68
68
|
| Avatar / avatar group | `avatar-ui` / `avatar-group-ui` |
|
|
69
|
-
| Color / calendar / OTP picker | `color-
|
|
69
|
+
| Color / calendar / OTP picker | `color-area-ui` / `calendar-picker-ui` / `otp-input-ui` |
|
|
70
70
|
| Stepper / timeline / progress / progress-row | `stepper-ui` / `timeline-ui` / `progress-ui` / `progress-row-ui` |
|
|
71
71
|
| Card with header / section / footer | `card-ui` (+ slot children) — don't roll a "panel" |
|
|
72
72
|
| Description-list (key/value) | `description-list-ui` |
|
|
@@ -90,9 +90,9 @@ chart's Y-axis labels clipped under a bled card's corner.
|
|
|
90
90
|
```css
|
|
91
91
|
/* Guide/value/legend safety inset (gh#1095) — [bleed]'s zero-inset is
|
|
92
92
|
only collision-free for the bare-marks case: a sparkline, or any other
|
|
93
|
-
chart-ui type with BOTH [
|
|
94
|
-
& > section[bleed]:has(> chart-ui:not([type="sparkline"]):not([
|
|
95
|
-
& > section[bleed]:has(> chart-ui:not([type="sparkline"]):not([
|
|
93
|
+
chart-ui type with BOTH [no-grid] and [no-values] set. */
|
|
94
|
+
& > section[bleed]:has(> chart-ui:not([type="sparkline"]):not([no-grid])),
|
|
95
|
+
& > section[bleed]:has(> chart-ui:not([type="sparkline"]):not([no-values])),
|
|
96
96
|
& > section[bleed]:has(> chart-legend-ui) {
|
|
97
97
|
margin: var(--card-inset);
|
|
98
98
|
padding: 0;
|
|
@@ -105,7 +105,7 @@ relying on every author to remember. `#renderSparkline()` is the ONLY
|
|
|
105
105
|
renderer that never emits axis ticks, gridlines, value text, or a legend
|
|
106
106
|
(`chart.class.js`'s sparkline branch) — it's the sole type where genuine
|
|
107
107
|
edge-to-edge bleed is collision-free with no attribute needed. Every other
|
|
108
|
-
type needs BOTH `[
|
|
108
|
+
type needs BOTH `[no-grid]` and `[no-values]` set to opt into true
|
|
109
109
|
bleed; short of that, the safety inset applies and the chart renders inset
|
|
110
110
|
like a normal card section — expected, not a bug.
|
|
111
111
|
|
|
@@ -234,29 +234,34 @@ correctness rather than just aesthetics), set `shape-rendering: crispEdges`
|
|
|
234
234
|
explicitly** — the browser default (`auto`, effectively anti-aliased) is
|
|
235
235
|
correct for everything else and should stay the default.
|
|
236
236
|
|
|
237
|
-
## 8. Attribute-shadowing on SVG-adjacent primitives (ADR-0053/0054)
|
|
237
|
+
## 8. Attribute-shadowing on SVG-adjacent primitives (ADR-0053/0054/0070)
|
|
238
238
|
|
|
239
|
-
Two of the
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
239
|
+
Two of the global-attribute-grammar collisions gh#1335 surfaced are
|
|
240
|
+
specifically SVG-rendered primitives; both exemptions are **GRANTED**
|
|
241
|
+
(ADR-0070, ratified 2026-08-17), closing the last 2 of gh#1335's 17 and
|
|
242
|
+
emptying `check-attribute-shadowing.mjs`'s `KNOWN_FINDINGS` — the gate now
|
|
243
|
+
enforces via `attribute-api-system.md`'s ratified §11 table alone:
|
|
243
244
|
|
|
244
245
|
- **`qr-code-ui[color]`** — a free-form CSS color string (drives the raw
|
|
245
246
|
`fill` baked into the generated matrix SVG, §5 above), structurally
|
|
246
|
-
identical to the
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
247
|
+
identical to the ratified `swatch-ui`/`noodles-ui[color]` §11 exemptions
|
|
248
|
+
("the component's entire subject is a color"). The exemption covers the
|
|
249
|
+
free-form value space AND the hardcoded `#000000` scanability fallback
|
|
250
|
+
(deliberately never theme-derived — light-on-dark won't scan), plus its
|
|
251
|
+
contract pairing with `[background]`.
|
|
252
|
+
- **`icon-ui[weight]`** — Phosphor's own glyph-variant vocabulary
|
|
250
253
|
(`thin/light/regular/bold/fill/duotone`, selecting which pre-rendered SVG
|
|
251
|
-
|
|
252
|
-
`font-weight`
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
`
|
|
259
|
-
|
|
254
|
+
set `getIcon()` loads) is a DIFFERENT CONCEPT from CSS `font-weight`
|
|
255
|
+
despite the shared name; the global utility's `font-weight` is inert on
|
|
256
|
+
the inline SVG, so the collision has no cascade effect.
|
|
257
|
+
|
|
258
|
+
Known residual (documented in the §11 justification, accepted not fixed):
|
|
259
|
+
global-only `weight` values (`normal|medium|semibold`) select no Phosphor
|
|
260
|
+
set and fall back to `regular`; a semantic-enum value on `qr-code-ui[color]`
|
|
261
|
+
(`color="danger"`) passes to the SVG fill verbatim, unresolved through
|
|
262
|
+
tokens. Cite this section — ADR-0070 — not a fresh investigation, if either
|
|
263
|
+
attribute surfaces again in a yaml audit; the next colliding
|
|
264
|
+
`color`/`weight` on any OTHER component still needs its own ADR.
|
|
260
265
|
|
|
261
266
|
## When to load this file
|
|
262
267
|
|
|
@@ -138,7 +138,52 @@ mechanics; never work from this summary alone):
|
|
|
138
138
|
the global name always means the global thing. Before minting any attribute
|
|
139
139
|
in a component yaml, check it against the spec's attribute inventory; the
|
|
140
140
|
only sanctioned collisions live in the spec's §11 Global-Attribute Exemption
|
|
141
|
-
List (first entries: `swatch-ui[color]` / `noodles-ui[color]`, ADR-0054
|
|
141
|
+
List (first entries: `swatch-ui[color]` / `noodles-ui[color]`, ADR-0054;
|
|
142
|
+
granted since: `qr-code-ui[color]` / `icon-ui[weight]`, ADR-0070).
|
|
143
|
+
|
|
144
|
+
Beyond the global grammar, ADR-0063
|
|
145
|
+
(`docs/ops/adr/adr-0063-attribute-grammar-addendum.md`) ratifies six
|
|
146
|
+
CROSS-SIBLING conventions for component-local attribute naming — the axis
|
|
147
|
+
ADR-0053/0054 don't cover. Any new attribute follows these:
|
|
148
|
+
|
|
149
|
+
- **`no-*` is the canonical negation prefix** — `hide-*` retires
|
|
150
|
+
(`chart[hideAverage|hideGrid|hideValues]` → `no*`, `stream[hide-cursor]`
|
|
151
|
+
→ `[no-cursor]`).
|
|
152
|
+
- **Interactivity is opt-in by a positively-named boolean, default `false`**
|
|
153
|
+
(the `stepper-item[interactive]` / `swatch[selectable]` shape) — never
|
|
154
|
+
opt-out. `chart-legend[static]` retires to `[interactive]` (inverted
|
|
155
|
+
default). Applies to single-purpose toggles only — `noodles`'s
|
|
156
|
+
`editable`/`readonly` pair is two orthogonal booleans and stays.
|
|
157
|
+
- **Two sanctioned multi-value encodings, never a hand-rolled delimited
|
|
158
|
+
string:** (a) `multiple` boolean + a structured option model (`select`'s
|
|
159
|
+
`options`/`<option>` shape); (b) a native array-typed JS property,
|
|
160
|
+
JSON-serialized for attribute/form participation (`tags-input`'s
|
|
161
|
+
`.value`). One explicit, operator-ratified EXCEPTION for existing
|
|
162
|
+
components (recorded on gh#1563, 2026-08-17): `segmented-ui[multiple]`'s
|
|
163
|
+
comma-separated value IS accepted as the sanctioned multiple+options
|
|
164
|
+
encoding, and toggle-group's comma-string resolves under that same ruling
|
|
165
|
+
rather than being re-ticketed. This is a ruling on those two existing
|
|
166
|
+
components, not a loophole — a NEW component's multi-value attribute still
|
|
167
|
+
uses form (a) or (b) above, never a delimited string, unless a separate
|
|
168
|
+
ruling says otherwise.
|
|
169
|
+
- **Cross-sibling naming convergence:** `pane[side]` → `pane[edge]`
|
|
170
|
+
(drawer keeps physical `side`); `menu-item[subtitle]` →
|
|
171
|
+
`menu-item[description]` (the ~20-component majority word); `placement`
|
|
172
|
+
ratified as-is for anchored popovers. Documented exception:
|
|
173
|
+
`input[maxlength]` — a primitive wrapping a genuine native `<input>`
|
|
174
|
+
keeps the native attribute's exact casing (ADR-0025/0055 conformance);
|
|
175
|
+
new non-native length constraints use the framework's
|
|
176
|
+
camelCase-property/kebab-attribute pair.
|
|
177
|
+
- **`completed` is the stage-terminal word** for a `status` lifecycle enum
|
|
178
|
+
(`agent-reasoning[status]`'s `done` converges).
|
|
179
|
+
- **`-picker` is reserved for the outer trigger+popover form-associated
|
|
180
|
+
composite** — never the inline substrate it composes. `color-picker-ui`
|
|
181
|
+
(the inline substrate) renames to `color-area-ui`.
|
|
182
|
+
|
|
183
|
+
The renames above have LANDED: dual-read compat shims shipped via gh#1563,
|
|
184
|
+
and the breaking cut removed the old names in 0.8.43 (gh#1617). The new
|
|
185
|
+
spellings are the sole ones — a yaml or demo still showing an old name is
|
|
186
|
+
stale and should be fixed.
|
|
142
187
|
|
|
143
188
|
## When to update this reference
|
|
144
189
|
|
|
@@ -177,6 +177,79 @@ have no v1.0 sidecar.
|
|
|
177
177
|
|
|
178
178
|
---
|
|
179
179
|
|
|
180
|
+
## Semantic color-family axis — two role-classes, two names (ADR-0044, ADR-0064)
|
|
181
|
+
|
|
182
|
+
Every component carries at most one STYLE axis and one FAMILY axis (the
|
|
183
|
+
semantic color family: `default | info | success | warning | danger`,
|
|
184
|
+
`+primary` where the role-class already carries brand emphasis), and every
|
|
185
|
+
enum value belongs to exactly one axis. The family axis's ATTRIBUTE NAME is
|
|
186
|
+
decided by role-class — never one universal name (a same-name meaning-flip
|
|
187
|
+
is a silent-failure migration and poisons the trained corpus, per ADR-0044
|
|
188
|
+
LLD §3):
|
|
189
|
+
|
|
190
|
+
- **Role-class A — `variant` is unclaimed:** the family axis is named
|
|
191
|
+
`variant`. Badge/tag's ratified shape (ADR-0044), plus `rating-ui` and the
|
|
192
|
+
`variant`-only siblings (inline-message, feed-item, empty-state, menu-item,
|
|
193
|
+
progress-row).
|
|
194
|
+
- **Role-class B — an existing identity/style axis already claims the
|
|
195
|
+
selector slot:** the family axis is named `color`. Button's shape
|
|
196
|
+
(`variant`=style, `color`=family), extended by ADR-0064 to `text-ui`
|
|
197
|
+
(`variant`=typography role), `chart-ui`/`heatmap-ui` (`type`=kind),
|
|
198
|
+
`icon-ui` (`weight`=glyph style), `spinner-ui` (`variant`=animation), and
|
|
199
|
+
`toggle-scheme-ui`. Renames owed by this ruling (follow-on build, gh#1376
|
|
200
|
+
— not yet landed): `icon-ui[tone]` → `[color]`, `heatmap-ui[colorScheme]`
|
|
201
|
+
→ `[color]`, `spinner-ui[tone]` → `[color]`.
|
|
202
|
+
|
|
203
|
+
`accent` is RETIRED from the family enum everywhere — ADR-0044 removed it
|
|
204
|
+
from badge/tag/button; ADR-0064 removes it from the seven stragglers
|
|
205
|
+
(text, chart, icon, heatmap, rating, spinner, toggle-scheme) with no
|
|
206
|
+
replacement value. Never mint `accent` in a new enum.
|
|
207
|
+
|
|
208
|
+
Two ratified non-family exceptions — the name without the semantics:
|
|
209
|
+
|
|
210
|
+
- `swatch-ui[color]` / `noodles-ui[color]` — an arbitrary CSS color string,
|
|
211
|
+
not a semantic enum (ADR-0054 §11 exemption, unchanged).
|
|
212
|
+
- `spinner-ui[color]` (post-rename) — a closed contrast-mode enum
|
|
213
|
+
(`current | subtle | inverse`), NOT the family vocabulary; never assume it
|
|
214
|
+
accepts `info`/`success`/`warning`/`danger` by analogy.
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## Catalog tiers — L0–L4, `origin`, and the promotion rule (ADR-0050, ADR-0066)
|
|
219
|
+
|
|
220
|
+
ADR-0050's L0–L4 ladder is the ONLY tier grammar — never mint a second
|
|
221
|
+
manifest format. ADR-0066 refines it three ways:
|
|
222
|
+
|
|
223
|
+
- **`origin: primitive | module` on every L0 entry** — both YAML source
|
|
224
|
+
roots (web-components primitives AND web-modules composites) compile into
|
|
225
|
+
the same `catalog-a2ui_0_9.json` through one shared contract;
|
|
226
|
+
`derive-catalog-tiers.mjs` stamps which root an entry came from onto
|
|
227
|
+
`tier-index.json`. A module is legitimately a member of TWO rungs at two
|
|
228
|
+
grains: its component API (props/events/slots) is L0, its assembled shell
|
|
229
|
+
composition is L3 — ruled correct, not a modeling defect.
|
|
230
|
+
- **The promotion rule, stated once:** patterns/zettel compositions are the
|
|
231
|
+
SOLE promotion source, and they enter the ladder at exactly one point —
|
|
232
|
+
pattern → L1 widget, through `curate-l1-widgets.mjs`'s gates (which writes
|
|
233
|
+
only `l1-widgets.json`). The higher rungs (L1 → L2 → L3 → L4) are AUTHORED
|
|
234
|
+
edges — hand-written `tiers/l*-*.json` manifests whose `composes` reference
|
|
235
|
+
the rung below, reserved/unblocked per ADR-0050's own phasing; a module's
|
|
236
|
+
L3 membership comes from an authored L3 manifest, never from its yaml
|
|
237
|
+
(which contributes only the L0 entry + `origin`). There is no
|
|
238
|
+
patterns↔module edge, primitives and modules never "promote" into each
|
|
239
|
+
other, and nothing promotes automatically or in reverse — curation is the
|
|
240
|
+
one-way valve (ADR-0050: "corpus derives from catalogs, never the
|
|
241
|
+
reverse").
|
|
242
|
+
- **The two pattern-facing outputs stay separate by design:**
|
|
243
|
+
`site/patterns-index.json` / `pattern-index.md` are a generated,
|
|
244
|
+
developer-facing index over the FULL pattern/template census, intentionally
|
|
245
|
+
independent of the L0–L4 machine-validated schema — a different audience,
|
|
246
|
+
never a convergence gap to "fix".
|
|
247
|
+
|
|
248
|
+
(`status:` above is orthogonal to the tier ladder — tier = what an entry is
|
|
249
|
+
composed of; status = how much to trust its contract today.)
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
180
253
|
## `props:` field — prop schemas
|
|
181
254
|
|
|
182
255
|
Each prop is a top-level key inside `props:`. The full prop schema:
|
|
@@ -266,7 +339,7 @@ string-list schema is the exact silent-mismatch shape.
|
|
|
266
339
|
| --- | --- | --- |
|
|
267
340
|
| `[data-col]` | `display: flex; flex-direction: column; gap: var(--page-grid-gap)` | column layout helper |
|
|
268
341
|
| `[data-row]` | `display: flex; align-items: center; gap: var(--page-grid-gap)` | row layout helper |
|
|
269
|
-
| `[data-grid]` | `display: grid; grid-template-columns: 1fr 1fr` (or `1fr 1fr 1fr` for `data-grid="3"`) | 2- or 3-col grid helper |
|
|
342
|
+
| `[data-layout-grid]` | `display: grid; grid-template-columns: 1fr 1fr` (or `1fr 1fr 1fr` for `data-layout-grid="3"`) | 2- or 3-col grid helper |
|
|
270
343
|
| `[data-actions]` | `display: flex; align-items: center; gap: var(--page-actions-gap)` | action button cluster |
|
|
271
344
|
| `[data-spacer]` | `flex: 1` | flex spacer for pushing content to edges |
|
|
272
345
|
|
|
@@ -139,10 +139,18 @@ itself is unavailable.
|
|
|
139
139
|
- **`build:site` copies packages but does NOT rebuild their dist bundles** — after
|
|
140
140
|
component `.css`/`.js` source changes, rebuild first (`npm run build -w
|
|
141
141
|
@adia-ai/llm`, then `npm run build:bundles`) or the deployed bundles are stale.
|
|
142
|
-
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
142
|
+
- **Package registration is one manifest, `scripts/build/site-package-registry.mjs`
|
|
143
|
+
(ADR-0062)** — every `@adia-ai/*` package the site ships is one registry entry, from
|
|
144
|
+
which the dist copy, BOTH importmaps (one shared `renderImportMapBlock()` — the
|
|
145
|
+
`site/index.html` copy is a generated artifact, `npm run build:site-importmap`),
|
|
146
|
+
the `dist/node_modules` symlinks, and the CI build order all derive. The old
|
|
147
|
+
failure class (per-package `copyX()` hand-edits; local Vite works, prod 404s —
|
|
148
|
+
v0.3.0 llm/a2ui-runtime, v0.8.27 persona+agent) is gated mechanically:
|
|
149
|
+
`check:site-packages-registered` scans every shipped source root for an
|
|
150
|
+
unregistered bare `@adia-ai/*` import and fails naming file:line, alongside
|
|
151
|
+
`check:site-importmap-fresh` and `check:deploy-workflow-build-order` — all three
|
|
152
|
+
in `npm run check` and early in `deploy-site.yml`. After any package add/rename,
|
|
153
|
+
add the registry entry; the gates say the rest.
|
|
146
154
|
2. **Dry-run first, and adjudicate every delete — BEFORE the real rsync, never after:**
|
|
147
155
|
```sh
|
|
148
156
|
rsync -azni --delete --exclude='packages/gen-ui/a2ui/corpus/feedback/' \
|