@adia-ai/web-components 0.8.35 → 0.8.37

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.
Files changed (30) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/MIGRATION.md +246 -44
  3. package/README.md +3 -3
  4. package/components/inspector/inspector.class.js +1 -1
  5. package/components/table-toolbar/table-toolbar.examples.md +3 -3
  6. package/core/streams-bridge.d.ts +2 -2
  7. package/core/streams-bridge.js +1 -1
  8. package/dist/web-components.min.js +1 -1
  9. package/package.json +3 -3
  10. package/patterns/admin-keys-and-export/admin-keys-and-export.examples.html +8 -8
  11. package/patterns/agent-cost/agent-cost.examples.html +3 -3
  12. package/patterns/agent-memory/agent-memory.examples.html +4 -4
  13. package/patterns/agent-prompt-library/agent-prompt-library.examples.html +8 -8
  14. package/patterns/approvals/approvals.examples.html +2 -2
  15. package/patterns/changelog-feed/changelog-feed.examples.html +1 -1
  16. package/patterns/comments-and-collaboration/comments-and-collaboration.examples.html +7 -7
  17. package/patterns/data-tables-inline-edit-and-tree/data-tables-inline-edit-and-tree.examples.html +4 -4
  18. package/patterns/diff-review/diff-review.examples.html +6 -6
  19. package/patterns/filter-bar/filter-bar.examples.html +5 -5
  20. package/patterns/inline-dialog/inline-dialog.examples.html +1 -1
  21. package/patterns/kanban-board/kanban-board.examples.html +12 -12
  22. package/patterns/layout/layout.examples.html +3 -3
  23. package/patterns/marketing-engagement/marketing-engagement.examples.html +13 -13
  24. package/patterns/notifications-bell-and-digest/notifications-bell-and-digest.examples.html +1 -1
  25. package/patterns/permissions-matrix/permissions-matrix.examples.html +1 -1
  26. package/patterns/permissions-role-picker/permissions-role-picker.examples.html +1 -1
  27. package/patterns/permissions-sharing/permissions-sharing.examples.html +3 -3
  28. package/patterns/profile-public-and-verification/profile-public-and-verification.examples.html +2 -2
  29. package/patterns/search-discovery/search-discovery.examples.html +15 -15
  30. package/styles/type/scale.css +2 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog — @adia-ai/web-components
2
2
 
3
+ ## [0.8.37] — 2026-08-14
4
+
5
+ ### Maintenance
6
+ - **Lockstep version bump only.** No source changes in this package; bumped to maintain the lockstep version coherence enforced by `scripts/release/check-lockstep.mjs`. Substantive v0.8.37 work shipped in ADR-0048 estate split: @adia-ai/{a2ui,gen-ui,mcp} first publish; six a2ui-* names ship as shims and retire. See `packages/mcp/CHANGELOG.md#0837--2026-08-14` for details.
7
+ - **`components/` touched in this release window** (123 file(s), e.g. `accordion/accordion.examples.html`) — carried by the entries above.
8
+ - **`core/` touched in this release window** (3 file(s), e.g. `core/element.test.js`) — carried by the entries above.
9
+ - **`dist/` bundles rebuilt** in this cut's window (1 file(s)) — regenerated from the source changes described above, not independent edits.
10
+ - **`patterns/` touched in this release window** (20 file(s), e.g. `admin-keys-and-export/admin-keys-and-export.examples.html`) — carried by the entries above.
11
+ - **`styles/` touched in this release window** (1 file(s), e.g. `type/scale.css`) — carried by the entries above.
12
+ - **`traits/` touched in this release window** (57 file(s), e.g. `active-state/active-state.examples.html`) — carried by the entries above.
13
+
14
+ ## [0.8.36] — 2026-08-13
15
+
16
+ ### Maintenance
17
+ - **Lockstep version bump only.** No source changes in this package; bumped to maintain the lockstep version coherence enforced by `scripts/release/check-lockstep.mjs`. Substantive v0.8.36 work shipped in a2ui chain standalone-installable (gh#1186: unpublishable dep removed, 143 packed-import escapes fixed, packed-imports gate + boot probe) + ui-architect coordinator agent + MCP doc consolidation. See `packages/a2ui/mcp/CHANGELOG.md#0836--2026-08-13` for details.
18
+
3
19
  ## [0.8.35] — 2026-08-13
4
20
 
5
21
  ### Maintenance
package/MIGRATION.md CHANGED
@@ -52,10 +52,194 @@ Version cuts and migration scope:
52
52
 
53
53
  - **`0.8.11`** — PATCH lockstep cut (2026-07-23). Internal ranges stay at `^0.8.0`. **BREAKING: the size model.** Every component `size` enum is now exactly `sm | md | lg`; the removed tiers (`xs`, `xl`, icon's `2xl/3xl/4xl/fill`) are served by the new ancestor **`[scale]`** context — six hand-tabled tiers (`ui-sm · ui-md · ui-lg · content-sm · content-md · content-lg`): scale picks the table, `size` picks the row. `[verse]`/`[prose]` are deprecated aliases of `ui-sm`/`content-md` (removed at v1.0). Also new: `<adia-wordmark-ui>`. See [§ v0.8.11 section below](#migrating-to-adia-aiv0811-2026-07-23).
54
54
 
55
+ - **`0.8.37`** — PATCH lockstep cut. **BREAKING: the a2ui / gen-ui estate split (ADR-0048).** Six published package names (`a2ui-runtime`, `a2ui-compose`, `a2ui-corpus`, `a2ui-retrieval`, `a2ui-validator`, `a2ui-mcp`) are replaced by four (`a2ui`, `gen-ui`, `gen-ui-mcp`, `a2ui-protocol-mcp`). **A patch-shaped version number does not make this non-breaking** — every old name is renamed. One-cycle re-export shims bridge the gap; the cut AFTER `0.8.37` retires them. See [§ 0.8.37 — the a2ui / gen-ui estate split](#0837--the-a2ui--gen-ui-estate-split-adr-0048).
56
+
55
57
  Live demos and per-component docs at [ui-kit.exe.xyz/site/](https://ui-kit.exe.xyz/site/). The `adia-ui-migration` skill (in `.agents/skills/`) automates most of the mechanical sweeps in this guide.
56
58
 
57
59
  ---
58
60
 
61
+ ## `0.8.37` — the a2ui / gen-ui estate split (ADR-0048)
62
+
63
+ **Read this even though the version number is a patch.** The `0.8.37` lockstep
64
+ cut renames six published packages. Nothing about the rename is patch-shaped
65
+ except the number, which is an operator ruling (gh#1192, 2026-08-13) about
66
+ release cadence, not a claim that your imports keep working forever.
67
+
68
+ The split is by concept, ruled in `docs/adr/adr-0048-a2ui-gen-ui-estate-split.md`:
69
+
70
+ - **`@adia-ai/a2ui` — the protocol.** How one system renders gen-UI canvases
71
+ in another system, safely: renderer, registry, streams, surface, wiring,
72
+ dockables, prop-apply, schema, plus protocol-side validation. **Zero
73
+ dependencies** — no LLM stack, no corpus. This is what an embedding host
74
+ installs.
75
+ - **`@adia-ai/gen-ui` — the generation system.** compose + retrieval + corpus
76
+ + catalog-aware and LLM-judge validation, as one package.
77
+ - **Two MCP servers, one npm package.** `@adia-ai/mcp` (gh#1240 — folds what
78
+ were originally two planned packages, `@adia-ai/gen-ui-mcp` and
79
+ `@adia-ai/a2ui-protocol-mcp`, before either ever published) ships one bin,
80
+ `adia-mcp`, dispatching two subcommands as separate processes:
81
+ `adia-mcp gen-ui` (30 tools — the generation surface, direct successor of
82
+ `@adia-ai/a2ui-mcp`) and `adia-mcp protocol` (4 tools — `validate_document`,
83
+ `get_registry_map`, `get_wiring_registry`, `protocol_status`; renamed off
84
+ their original same-named-as-`gen-ui`-surface forms by gh#1248 before this
85
+ server ever published). The name `@adia-ai/a2ui-mcp` is **burned, never
86
+ reused**: it means "the generation MCP" to every consumer that has it
87
+ pinned, so it is deprecated with a pointer rather than repurposed.
88
+
89
+ ### The one-cycle bridge — what happens if you do nothing
90
+
91
+ At `0.8.37` every old name gets a final **shim publish**: a thin package whose
92
+ exports re-export the new package's matching subpaths. Because npm's caret is
93
+ minor-locked below 1.0, `0.8.37` satisfies the `^0.8.x` range you already
94
+ carry — so **an existing consumer floats onto the shim on its next
95
+ `npm install`, with no action and no broken import.** The `npm deprecate`
96
+ pointer on each old name tells you where to move.
97
+
98
+ That window is exactly one cycle. The follow-up PR deletes the shims from the
99
+ repo and the release roster, so **the cut after `0.8.37` is the one that breaks
100
+ an un-migrated consumer.** Migrate during the `0.8.37` line.
101
+
102
+ Two things the shim structurally cannot bridge, so migrate these first:
103
+
104
+ - **JSON-data subpaths of `@adia-ai/a2ui-corpus`** — the catalog,
105
+ `./manifest`, `./chunks`, `./chunks/*`, `./chunk-embeddings`. A JavaScript
106
+ forwarder cannot re-export a JSON module (`export *` drops `default`, and
107
+ Node requires `with { type: 'json' }`, which throws against a `.js` target).
108
+ These get pointer text only. The corpus package's one JS export,
109
+ `./chunk-library`, IS forwarded.
110
+ - **TypeScript types**, except the two subpaths the old package itself
111
+ published as `.d.ts` (`a2ui-runtime`'s `./schema` and `./types`). A one-cycle
112
+ bridge ships JS.
113
+
114
+ Also not minted, because they never worked on the published packages:
115
+ extension-suffixed alias forms (`@adia-ai/a2ui-runtime/registry.js`,
116
+ `@adia-ai/a2ui-compose/core/artifacts.js`). The published wildcard targets
117
+ already end in `.js`, so those specifiers resolved to `…/artifacts.js.js` and
118
+ failed at load. If you were writing them, they were already broken.
119
+
120
+ ### Subpath-export map (old → new)
121
+
122
+ | Old import | New import |
123
+ |---|---|
124
+ | `@adia-ai/a2ui-runtime` | `@adia-ai/a2ui` |
125
+ | `@adia-ai/a2ui-runtime/<sub>` (`registry`, `renderer`, `prop-apply`, `streams`, `surface`, `wiring`, `dockables`, `schema`, `types`) | `@adia-ai/a2ui/<sub>` (unchanged sub) |
126
+ | `@adia-ai/a2ui-validator` / `./validator` | `@adia-ai/a2ui/validate` |
127
+ | `@adia-ai/a2ui-validator/catalog` | `@adia-ai/gen-ui/validate/catalog` |
128
+ | `@adia-ai/a2ui-validator/semantic` (+`/*`) | `@adia-ai/gen-ui/validate/semantic` (+`/*`) |
129
+ | `@adia-ai/a2ui-compose` | `@adia-ai/gen-ui` (compose is the package's primary surface; root re-exports `generateUI`) |
130
+ | `@adia-ai/a2ui-compose/<sub>` (`core`, `strategies/*`, `transpiler`, `evals`, `shared/*`; incl. deprecated `engine`/`engines/*` aliases) | `@adia-ai/gen-ui/compose/<sub>` (aliases NOT carried over — they were already deprecated one cycle) |
131
+ | `@adia-ai/a2ui-retrieval` | `@adia-ai/gen-ui/retrieval` |
132
+ | `@adia-ai/a2ui-retrieval/<sub>` (e.g. `domain-router`, `intent/*`, `embedding/*`, `feedback/*`, `authoring/*`) | `@adia-ai/gen-ui/retrieval/<sub>` (e.g. `@adia-ai/gen-ui/retrieval/domain-router`) |
133
+ | `@adia-ai/a2ui-corpus` | `@adia-ai/gen-ui/corpus` |
134
+ | `@adia-ai/a2ui-corpus/<sub>` (`chunks/*`, `chunk-library`, `chunk-embeddings`, `manifest`) | `@adia-ai/gen-ui/corpus/<sub>` |
135
+ | `@adia-ai/a2ui-mcp` (bin `adiaui-mcp`) | `@adia-ai/mcp` (bin `adia-mcp`, subcommand `gen-ui`) — retargeted gh#1240; the `@adia-ai/gen-ui-mcp` name this row originally named never published |
136
+ | — (new) | `@adia-ai/mcp` (bin `adia-mcp`, subcommand `protocol`) — folded into the same package as the row above by gh#1240; the `@adia-ai/a2ui-protocol-mcp` name this row originally named never published |
137
+
138
+ ### Mechanical sweeps
139
+
140
+ **First, hand-migrate the two deprecated compose aliases — the sweep below
141
+ cannot do it and will silently break them.** `@adia-ai/a2ui-compose` published
142
+ `./engine` and `./engines/*`, deprecated one cycle ago; they are **not** carried
143
+ over to `@adia-ai/gen-ui`. A blind prefix rewrite would turn them into
144
+ `@adia-ai/gen-ui/compose/engine{,s/…}`, which do not exist — and the post-sweep
145
+ grep would not catch it, because by then they carry the new package name.
146
+
147
+ ```bash
148
+ git grep -n '@adia-ai/a2ui-compose/engine' # must be empty before you sweep
149
+ ```
150
+
151
+ Any hit maps like this (the old alias and its successor resolve to the same
152
+ file, so this is a rename, not a behaviour change):
153
+
154
+ | Deprecated alias | Migrate to |
155
+ |---|---|
156
+ | `@adia-ai/a2ui-compose/engine` | `@adia-ai/gen-ui/compose/core` |
157
+ | `@adia-ai/a2ui-compose/engines/zettel` | `@adia-ai/gen-ui/compose/strategies/zettel` |
158
+ | `@adia-ai/a2ui-compose/engines/registry` | `@adia-ai/gen-ui/compose/strategies/registry` |
159
+ | `@adia-ai/a2ui-compose/engines/cascade` | `@adia-ai/gen-ui/compose/strategies/cascade` |
160
+ | `@adia-ai/a2ui-compose/engines/escalation` | `@adia-ai/gen-ui/compose/strategies/escalation` |
161
+
162
+ Then run the sweeps in this order — the longest specifier first, so a shorter
163
+ prefix doesn't eat a longer one:
164
+
165
+ ```bash
166
+ # One helper, three deliberate choices:
167
+ #
168
+ # 1. A `while` loop, not `| xargs perl -i -pe …`: with no matches, GNU xargs
169
+ # runs perl with NO file arguments and it hangs reading stdin. The loop
170
+ # body simply never executes.
171
+ # 2. The old/new strings go through the ENVIRONMENT, not the perl source —
172
+ # inlining them would let perl read `@adia-ai` on the replacement side as
173
+ # an array interpolation and silently substitute an empty string.
174
+ # 3. NUL-delimited (`-lz` + `read -d ''`), so a path containing a space
175
+ # survives — this repo's own "MIGRATION GUIDE.md" is one, and
176
+ # `for f in $(git grep -l …)` word-splits it into two nonexistent paths.
177
+ sweep() {
178
+ git grep -lz "$1" | while IFS= read -r -d '' f; do
179
+ OLD="$1" NEW="$2" perl -i -pe 'BEGIN{$o=$ENV{OLD};$n=$ENV{NEW}} s/\Q$o\E/$n/g' "$f"
180
+ done
181
+ }
182
+
183
+ # validator — longest specifier FIRST, so a shorter prefix doesn't eat it.
184
+ # `./validator` was a real published subpath and maps to the SAME target as the
185
+ # bare name; without its own line the generic rule below would produce
186
+ # `@adia-ai/a2ui/validate/validator`, which a2ui does not export (no `./validate/*`
187
+ # wildcard) → ERR_PACKAGE_PATH_NOT_EXPORTED.
188
+ sweep '@adia-ai/a2ui-validator/validator' '@adia-ai/a2ui/validate'
189
+ sweep '@adia-ai/a2ui-validator/catalog' '@adia-ai/gen-ui/validate/catalog'
190
+ sweep '@adia-ai/a2ui-validator/semantic' '@adia-ai/gen-ui/validate/semantic'
191
+ sweep '@adia-ai/a2ui-validator' '@adia-ai/a2ui/validate'
192
+
193
+ # generation system
194
+ sweep '@adia-ai/a2ui-compose/' '@adia-ai/gen-ui/compose/'
195
+ sweep '@adia-ai/a2ui-compose' '@adia-ai/gen-ui'
196
+ sweep '@adia-ai/a2ui-retrieval' '@adia-ai/gen-ui/retrieval'
197
+ sweep '@adia-ai/a2ui-corpus' '@adia-ai/gen-ui/corpus'
198
+
199
+ # protocol
200
+ sweep '@adia-ai/a2ui-runtime' '@adia-ai/a2ui'
201
+ ```
202
+
203
+ The helper takes paths from `git grep`, so it only ever touches tracked files —
204
+ `node_modules/` and build output are never rewritten.
205
+
206
+ Then fix your manifest by hand — a find-replace does not know the difference
207
+ between a dependency and a peer:
208
+
209
+ - **`dependencies` / `devDependencies`** on any renamed package → the new name
210
+ at the caret range for the cut (`^0.8.0`).
211
+ - **`peerDependencies`** stay **exact-pinned** to the lockstep version. If you
212
+ peer-pinned `@adia-ai/a2ui-runtime`, the pin moves to `@adia-ai/a2ui` —
213
+ moving the import without the peer pin leaves you resolving two runtimes.
214
+ - **MCP client config** (`.mcp.json`, Claude Desktop, Cursor): the generation
215
+ server's package and bin both change —
216
+ `npx -y @adia-ai/a2ui-mcp` → `npx -y @adia-ai/mcp gen-ui` (gh#1240 folded
217
+ the originally-planned `@adia-ai/gen-ui-mcp` name, and the separate protocol
218
+ MCP, into one package, `@adia-ai/mcp`, before either ever published — the
219
+ bin gained a subcommand accordingly). Tool names and their input/output
220
+ shapes are **unchanged**; only the package that serves them is renamed. The
221
+ 30-tool surface is documented at `packages/mcp/TOOLS.md` (the `gen-ui`
222
+ section).
223
+
224
+ ### After the sweep, check
225
+
226
+ - No `@adia-ai/a2ui-` specifier survives:
227
+ `git grep -nE '@adia-ai/a2ui-(runtime|compose|corpus|retrieval|validator|mcp)'`
228
+ should return nothing. (There is no exception to read past here —
229
+ `@adia-ai/a2ui-protocol-mcp` was the originally-planned protocol-server
230
+ name, but gh#1240 folded it into `@adia-ai/mcp`'s `protocol` subcommand
231
+ before it ever published, so it never became a real name to match.)
232
+ - **The grep above cannot see a mis-rewritten subpath**, because those carry
233
+ the new package name. Check the two classes it misses directly:
234
+ `git grep -nE '@adia-ai/gen-ui/compose/engines?(/|$)'` and
235
+ `git grep -n '@adia-ai/a2ui/validate/'` — both should return nothing.
236
+ Any hit is a specifier that does not exist and will fail at import.
237
+ - Your lockfile actually resolved the new names — a stale lockfile keeps
238
+ installing shims and hides the work until they retire.
239
+ - `npm ls @adia-ai/a2ui` shows one copy, not two.
240
+
241
+ ---
242
+
59
243
  ## Upcoming — variant/color/tone convention cut
60
244
 
61
245
  **One theme: every color-ish attribute owns exactly one axis.** `variant`/`tone` on badge & tag
@@ -77,7 +261,9 @@ have exactly one fill style each.
77
261
 
78
262
  ```bash
79
263
  git grep -nE '<badge-ui[^>]*variant="accent"'
80
- git grep -lE '<badge-ui[^>]*variant="accent"' | xargs perl -i -pe 's/(<badge-ui[^>]*variant=")accent(")/${1}primary${2}/g'
264
+ git grep -lz '<badge-ui[^>]*variant="accent"' | while IFS= read -r -d '' f; do
265
+ perl -i -pe 's/(<badge-ui[^>]*variant=")accent(")/${1}primary${2}/g' "$f"
266
+ done
81
267
  ```
82
268
 
83
269
  - **`<tag-ui variant="accent">` → `<tag-ui variant="primary">`** — identical rendering
@@ -85,7 +271,9 @@ have exactly one fill style each.
85
271
 
86
272
  ```bash
87
273
  git grep -nE '<tag-ui[^>]*variant="accent"'
88
- git grep -lE '<tag-ui[^>]*variant="accent"' | xargs perl -i -pe 's/(<tag-ui[^>]*variant=")accent(")/${1}primary${2}/g'
274
+ git grep -lz '<tag-ui[^>]*variant="accent"' | while IFS= read -r -d '' f; do
275
+ perl -i -pe 's/(<tag-ui[^>]*variant=")accent(")/${1}primary${2}/g' "$f"
276
+ done
89
277
  ```
90
278
 
91
279
  - **`<badge-ui variant="muted">` / `<badge-ui variant="neutral">` → `<badge-ui tone="muted">`**
@@ -97,7 +285,9 @@ have exactly one fill style each.
97
285
 
98
286
  ```bash
99
287
  git grep -nE '<badge-ui[^>]*variant="(muted|neutral)"'
100
- git grep -lE '<badge-ui[^>]*variant="(muted|neutral)"' | xargs perl -i -pe 's/(<badge-ui[^>]*)variant="(?:muted|neutral)"/${1}tone="muted"/g'
288
+ git grep -lz '<badge-ui[^>]*variant="(muted|neutral)"' | while IFS= read -r -d '' f; do
289
+ perl -i -pe 's/(<badge-ui[^>]*)variant="(?:muted|neutral)"/${1}tone="muted"/g' "$f"
290
+ done
101
291
  ```
102
292
 
103
293
  - **`<alert-ui variant="muted">` / `<alert-ui variant="neutral">` → drop the attribute** — both
@@ -113,8 +303,10 @@ have exactly one fill style each.
113
303
  ```bash
114
304
  EX=(-g '!*MIGRATION*' -g '!*CHANGELOG.md' -g '!**/dist/**' -g '!*.a2ui.json' -g '!*.examples.md')
115
305
  rg -nU '<alert-ui(\s[^>]*)?\svariant="(muted|neutral)"' "${EX[@]}"
116
- rg -lU '<alert-ui(\s[^>]*)?\svariant="(muted|neutral)"' "${EX[@]}" \
117
- | xargs perl -0777 -i -pe 's/(<alert-ui(?:\s[^>]*)?)\s+variant="(?:muted|neutral)"/${1}/gs'
306
+ rg -0 -lU '<alert-ui(\s[^>]*)?\svariant="(muted|neutral)"' "${EX[@]}" \
307
+ | while IFS= read -r -d '' f; do
308
+ perl -0777 -i -pe 's/(<alert-ui(?:\s[^>]*)?)\s+variant="(?:muted|neutral)"/${1}/gs' "$f"
309
+ done
118
310
  ```
119
311
 
120
312
  - **Programmatic setters (JS render paths — the sweep HTML greps miss):**
@@ -230,7 +422,9 @@ git grep -nE '"size": *"(xs|xl|2xl|3xl|4xl|fill)"' # A2UI/JSON form
230
422
 
231
423
  **Sweep (mechanical, non-icon tags):**
232
424
  ```bash
233
- git grep -lE 'size="(xs|xl)"' | xargs perl -i -pe 's/size="xs"/size="sm"/g; s/size="xl"/size="lg"/g'
425
+ git grep -lz 'size="(xs|xl)"' | while IFS= read -r -d '' f; do
426
+ perl -i -pe 's/size="xs"/size="sm"/g; s/size="xl"/size="lg"/g' "$f"
427
+ done
234
428
  ```
235
429
  Icon named tiers are a table-driven remap (`xs→"12"`, `xl→"32"`, `2xl→"48"`, `3xl→"64"`, `4xl→"96"`, `fill→"100%"`) — sweep them BEFORE the generic pass, and never touch already-free-form values (`size="48"`).
236
430
 
@@ -268,7 +462,9 @@ git grep -nE -- '--a-accent'
268
462
 
269
463
  **Sweep (mechanical):**
270
464
  ```bash
271
- git grep -lE -- '--a-accent' | xargs perl -i -pe 's/--a-accent(?![a-z0-9])/--a-primary/g'
465
+ git grep -lz -- '--a-accent' | while IFS= read -r -d '' f; do
466
+ perl -i -pe 's/--a-accent(?![a-z0-9])/--a-primary/g' "$f"
467
+ done
272
468
  ```
273
469
 
274
470
  (The `(?![a-z0-9])` guard keeps suffixed forms like `--a-accent-strong` → `--a-primary-strong` correct while never touching unrelated names. Prefer consuming `--md-sys-color-primary*` directly in new code.)
@@ -295,7 +491,9 @@ git grep -n 'primitives-accent'
295
491
 
296
492
  **Sweep (mechanical):**
297
493
  ```bash
298
- git grep -l 'primitives-accent' | xargs perl -i -pe 's/primitives-accent/primitives-primary/g'
494
+ git grep -lz 'primitives-accent' | while IFS= read -r -d '' f; do
495
+ perl -i -pe 's/primitives-accent/primitives-primary/g' "$f"
496
+ done
299
497
  ```
300
498
 
301
499
  ### Behavioral: named `[theme]` presets no longer re-color (manual review)
@@ -315,7 +513,7 @@ git grep -c 'primitives-accent' || echo clean # expect clean (item
315
513
  git grep -cE -- '--a-[a-z]+-[0-9]-(tint-|shade-)?scrim\b' || echo clean # expect clean (item 2)
316
514
  ```
317
515
 
318
- Then the browser gate on the migrated screens (`adia-verify`): zero console errors,
516
+ Then the browser gate on the migrated screens (`surface-qa`): zero console errors,
319
517
  non-zero bounding boxes, and read the screenshot — the scrim remap (item 2) and the
320
518
  `[theme]` behavioral change are visual; only the pixels prove overlay weights and
321
519
  brand color survived. Compare a before/after screenshot of one themed page if the
@@ -965,7 +1163,7 @@ Non-zero exit on regression. Used internally for the 6 in-repo consumers — pas
965
1163
  If you maintain your own shell-style components in your fork or extension:
966
1164
  - `<admin-shell>` host: 305 → **87 LOC** (-71%) at v0.4.0
967
1165
  - The bespoke pattern moves resize / collapse / persistence / dialog behavior INTO each child. The host coordinates only.
968
- - See [`bespoke-shell-children` skill](../../.agents/skills/adia-author/SKILL.md) for the canonical decomposition recipe.
1166
+ - See [`bespoke-shell-children` skill](../../.agents/skills/primitive-authoring/SKILL.md) for the canonical decomposition recipe.
969
1167
 
970
1168
  ### Don't roll back
971
1169
 
@@ -978,8 +1176,10 @@ Once on `0.4.0`, the legacy paths cannot be reactivated by config — they're ph
978
1176
  `grid-ui` has only ever accepted `columns="N"` (see [`packages/web-components/components/grid/grid.js:12`](../../packages/web-components/components/grid/grid.js#L12)). Pages authored with `cols=` were silently rendering as the default 3-column grid — the attribute was ignored. Sweep:
979
1177
 
980
1178
  ```bash
981
- git grep -nlE '<grid-ui[^>]*\bcols=' \
982
- | xargs perl -i -pe 's/(<grid-ui[^>]*?)\bcols=/$1columns=/g'
1179
+ git grep -nlz '<grid-ui[^>]*\bcols=' \
1180
+ | while IFS= read -r -d '' f; do
1181
+ perl -i -pe 's/(<grid-ui[^>]*?)\bcols=/$1columns=/g' "$f"
1182
+ done
983
1183
  ```
984
1184
 
985
1185
  Then re-run `npm run harvest:chunks` if any of the touched pages live under `site/pages/` and are tagged with `data-chunk` (extracts to `packages/a2ui/corpus/chunks/`).
@@ -1355,46 +1555,48 @@ Not a break, but pairs with §1. `<button-ui>` now accepts `[color="default | ac
1355
1555
 
1356
1556
  ```bash
1357
1557
  # 1. button variant=danger → color=danger (sweep HTML)
1358
- git grep -nlE 'button-ui[^>]*variant="danger"' \
1359
- | xargs perl -i -pe 's/(<button-ui[^>]*?)variant="danger"/$1color="danger"/g'
1558
+ git grep -nlz 'button-ui[^>]*variant="danger"' \
1559
+ | while IFS= read -r -d '' f; do perl -i -pe 's/(<button-ui[^>]*?)variant="danger"/$1color="danger"/g' "$f"; done
1360
1560
 
1361
1561
  # 2. timeline-item-ui Booleans → status enum
1362
- git grep -nlE '<timeline-item-ui[^>]*\bcompleted\b' \
1363
- | xargs perl -i -pe 's/(<timeline-item-ui[^>]*?)\bcompleted\b/$1status="completed"/g'
1364
- git grep -nlE '<timeline-item-ui[^>]*\bactive\b' \
1365
- | xargs perl -i -pe 's/(<timeline-item-ui[^>]*?)\bactive\b/$1status="active"/g'
1366
- git grep -nlE '<timeline-item-ui[^>]*\berror\b' \
1367
- | xargs perl -i -pe 's/(<timeline-item-ui[^>]*?)\berror\b/$1status="error"/g'
1562
+ git grep -nlz '<timeline-item-ui[^>]*\bcompleted\b' \
1563
+ | while IFS= read -r -d '' f; do perl -i -pe 's/(<timeline-item-ui[^>]*?)\bcompleted\b/$1status="completed"/g' "$f"; done
1564
+ git grep -nlz '<timeline-item-ui[^>]*\bactive\b' \
1565
+ | while IFS= read -r -d '' f; do perl -i -pe 's/(<timeline-item-ui[^>]*?)\bactive\b/$1status="active"/g' "$f"; done
1566
+ git grep -nlz '<timeline-item-ui[^>]*\berror\b' \
1567
+ | while IFS= read -r -d '' f; do perl -i -pe 's/(<timeline-item-ui[^>]*?)\berror\b/$1status="error"/g' "$f"; done
1368
1568
 
1369
1569
  # 3. stepper-item-ui similarly
1370
- git grep -nlE '<stepper-item-ui[^>]*\bcompleted\b' \
1371
- | xargs perl -i -pe 's/(<stepper-item-ui[^>]*?)\bcompleted\b/$1status="completed"/g'
1570
+ git grep -nlz '<stepper-item-ui[^>]*\bcompleted\b' \
1571
+ | while IFS= read -r -d '' f; do perl -i -pe 's/(<stepper-item-ui[^>]*?)\bcompleted\b/$1status="completed"/g' "$f"; done
1372
1572
 
1373
1573
  # 4. pipeline-status-ui complete → status=completed (note spelling)
1374
- git grep -nlE '<pipeline-status-ui[^>]*\bcomplete\b' \
1375
- | xargs perl -i -pe 's/(<pipeline-status-ui[^>]*?)\bcomplete\b/$1status="completed"/g'
1376
-
1377
- # 5. event listeners
1378
- git grep -nE "addEventListener.*'chat-submit'" \
1379
- | xargs perl -i -pe "s/'chat-submit'/'submit'/g"
1380
- git grep -nE "addEventListener.*'legend-toggle'" \
1381
- | xargs perl -i -pe "s/'legend-toggle'/'toggle'/g"
1382
- git grep -nE "addEventListener.*'slide-change'" \
1383
- | xargs perl -i -pe "s/'slide-change'/'change'/g"
1574
+ git grep -nlz '<pipeline-status-ui[^>]*\bcomplete\b' \
1575
+ | while IFS= read -r -d '' f; do perl -i -pe 's/(<pipeline-status-ui[^>]*?)\bcomplete\b/$1status="completed"/g' "$f"; done
1576
+
1577
+ # 5. event listeners — note -l (files-with-matches), not -n: the old form piped
1578
+ # `grep -n` (file:line:text) straight into `perl -i`, handing perl a bogus
1579
+ # "filename" that never exists.
1580
+ git grep -lz "addEventListener.*'chat-submit'" \
1581
+ | while IFS= read -r -d '' f; do perl -i -pe "s/'chat-submit'/'submit'/g" "$f"; done
1582
+ git grep -lz "addEventListener.*'legend-toggle'" \
1583
+ | while IFS= read -r -d '' f; do perl -i -pe "s/'legend-toggle'/'toggle'/g" "$f"; done
1584
+ git grep -lz "addEventListener.*'slide-change'" \
1585
+ | while IFS= read -r -d '' f; do perl -i -pe "s/'slide-change'/'change'/g" "$f"; done
1384
1586
 
1385
1587
  # 6. error → danger on toast/alert/tag (one component at a time so other variant=error don't collide)
1386
- git grep -nlE '<toast-ui[^>]*variant="error"' \
1387
- | xargs perl -i -pe 's/(<toast-ui[^>]*?)variant="error"/$1variant="danger"/g'
1388
- git grep -nlE '<alert-ui[^>]*variant="error"' \
1389
- | xargs perl -i -pe 's/(<alert-ui[^>]*?)variant="error"/$1variant="danger"/g'
1390
- git grep -nlE '<tag-ui[^>]*variant="error"' \
1391
- | xargs perl -i -pe 's/(<tag-ui[^>]*?)variant="error"/$1variant="danger"/g'
1588
+ git grep -nlz '<toast-ui[^>]*variant="error"' \
1589
+ | while IFS= read -r -d '' f; do perl -i -pe 's/(<toast-ui[^>]*?)variant="error"/$1variant="danger"/g' "$f"; done
1590
+ git grep -nlz '<alert-ui[^>]*variant="error"' \
1591
+ | while IFS= read -r -d '' f; do perl -i -pe 's/(<alert-ui[^>]*?)variant="error"/$1variant="danger"/g' "$f"; done
1592
+ git grep -nlz '<tag-ui[^>]*variant="error"' \
1593
+ | while IFS= read -r -d '' f; do perl -i -pe 's/(<tag-ui[^>]*?)variant="error"/$1variant="danger"/g' "$f"; done
1392
1594
 
1393
1595
  # 7. chat-input busy → loading
1394
- git grep -nlE '<chat-input-ui[^>]*\bbusy\b' \
1395
- | xargs perl -i -pe 's/(<chat-input-ui[^>]*?)\bbusy\b/$1loading/g'
1396
- git grep -nlE 'chatInput\.busy' \
1397
- | xargs perl -i -pe 's/chatInput\.busy/chatInput.loading/g'
1596
+ git grep -nlz '<chat-input-ui[^>]*\bbusy\b' \
1597
+ | while IFS= read -r -d '' f; do perl -i -pe 's/(<chat-input-ui[^>]*?)\bbusy\b/$1loading/g' "$f"; done
1598
+ git grep -nlz 'chatInput\.busy' \
1599
+ | while IFS= read -r -d '' f; do perl -i -pe 's/chatInput\.busy/chatInput.loading/g' "$f"; done
1398
1600
 
1399
1601
  # 8. agent-trace open → no attr (default visible) OR collapsed
1400
1602
  # Manual review: default-visible is the new default; consumers that wrote
@@ -1405,8 +1607,8 @@ git grep -nE '<agent-trace-ui'
1405
1607
  # 9. avatar-ui name= → text= (deprecated alias, scheduled for removal)
1406
1608
  # `name=` still works in 0.0.20+ but fires a one-shot console warning
1407
1609
  # per page. Sweep before the next major to avoid the upcoming break.
1408
- git grep -nlE '<avatar-ui[^>]*\bname=' \
1409
- | xargs perl -i -pe 's/(<avatar-ui[^>]*?\s)name=/\1text=/g'
1610
+ git grep -nlz '<avatar-ui[^>]*\bname=' \
1611
+ | while IFS= read -r -d '' f; do perl -i -pe 's/(<avatar-ui[^>]*?\s)name=/\1text=/g' "$f"; done
1410
1612
  ```
1411
1613
 
1412
1614
  The `adia-ui-migration` skill in `.claude/skills/adia-ui-migration/` automates these sweeps and runs the verification gate after.
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  Vanilla web components + A2UI runtime for AdiaUI. **95 light-DOM custom
4
4
  elements** + **56 composable traits**, a reactive core (signals + tagged-template renderer), form-associated form controls, and integration into the A2UI generation pipeline.
5
5
 
6
- > This package ships UI atoms only. Composite shells (admin / chat / editor / simple / theme) live in [`@adia-ai/web-modules`](../web-modules). The generation pipeline lives in [`@adia-ai/a2ui-compose`](../a2ui/compose); the pattern corpus in [`@adia-ai/a2ui-corpus`](../a2ui/corpus); the MCP server in [`@adia-ai/a2ui-mcp`](../a2ui/mcp).
6
+ > This package ships UI atoms only. Composite shells (admin / chat / editor / simple / theme) live in [`@adia-ai/web-modules`](../web-modules). The generation pipeline lives in [`@adia-ai/a2ui-compose`](../gen-ui/compose); the pattern corpus in [`@adia-ai/a2ui-corpus`](../gen-ui/corpus); the MCP server in [`@adia-ai/mcp`](../mcp) (its `gen-ui` surface).
7
7
  >
8
8
  > **Consumer guide:** [`USAGE.md`](./USAGE.md) — property reactivity, event contract, form participation, lifecycle, registration, TypeScript. Start here if you're integrating AdiaUI into an app.
9
9
  >
@@ -125,7 +125,7 @@ web-components/
125
125
  │ All actual A2UI runtime code (renderer,
126
126
  │ registry, streams, surface manifest,
127
127
  │ wiring, dockables, controllers) lives in
128
- │ `@adia-ai/a2ui-runtime` at packages/a2ui/runtime/.
128
+ │ `@adia-ai/a2ui` at packages/a2ui/.
129
129
 
130
130
  └── styles/ — Global tokens and CSS layering
131
131
  ├── tokens.css all --a-* design tokens
@@ -329,7 +329,7 @@ attribute table + live demos:
329
329
  npm run build:components # regenerate all .a2ui.json from YAML
330
330
  ```
331
331
 
332
- The build also writes `packages/a2ui/corpus/catalog-a2ui_0_9.json` and
332
+ The build also writes `packages/gen-ui/corpus/catalog-a2ui_0_9.json` and
333
333
  `catalog-a2ui_0_9_rules.txt` — the flat-file catalog the MCP server and
334
334
  generation engine consume.
335
335
 
@@ -12,7 +12,7 @@
12
12
  */
13
13
 
14
14
  import { UIElement } from '../../core/element.js';
15
- import { registry } from '@adia-ai/a2ui-runtime';
15
+ import { registry } from '@adia-ai/a2ui';
16
16
  import '../tabs/tabs.js';
17
17
  import '../tabs/tab.js';
18
18
  import '../code/code.js';
@@ -32,21 +32,21 @@
32
32
  <td>Maya Chen</td>
33
33
  <td>Designer</td>
34
34
  <td>
35
- <tag-ui size="sm" variant="success">Active</tag-ui>
35
+ <tag-ui variant="success">Active</tag-ui>
36
36
  </td>
37
37
  </tr>
38
38
  <tr>
39
39
  <td>Alex Park</td>
40
40
  <td>Engineer</td>
41
41
  <td>
42
- <tag-ui size="sm" variant="success">Active</tag-ui>
42
+ <tag-ui variant="success">Active</tag-ui>
43
43
  </td>
44
44
  </tr>
45
45
  <tr>
46
46
  <td>Jordan Lee</td>
47
47
  <td>Product</td>
48
48
  <td>
49
- <tag-ui size="sm" variant="warning">Away</tag-ui>
49
+ <tag-ui variant="warning">Away</tag-ui>
50
50
  </td>
51
51
  </tr>
52
52
  </tbody>
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * The bridge duck-types the renderer (it needs `.process()`, nothing
6
6
  * else), so it works with any A2UI-protocol consumer — the actual
7
- * `A2UIRenderer` from `@adia-ai/a2ui-runtime`, a custom renderer, or
7
+ * `A2UIRenderer` from `@adia-ai/a2ui`, a custom renderer, or
8
8
  * a test stub.
9
9
  *
10
10
  * Contract:
@@ -27,7 +27,7 @@
27
27
 
28
28
  /**
29
29
  * Minimal renderer contract the bridge requires. The actual
30
- * `A2UIRenderer` from `@adia-ai/a2ui-runtime` satisfies this surface,
30
+ * `A2UIRenderer` from `@adia-ai/a2ui` satisfies this surface,
31
31
  * as does any custom renderer that handles
32
32
  * `{ type: 'updateDataModel', ... }` actions.
33
33
  */
@@ -12,7 +12,7 @@
12
12
  * the dependency direction is web-components → a2ui-utils, not the
13
13
  * reverse. The bridge duck-types the renderer (it needs `.process()`,
14
14
  * nothing else), so it works with any A2UI-protocol consumer — the
15
- * actual `A2UIRenderer` from `@adia-ai/a2ui-runtime`, a custom renderer,
15
+ * actual `A2UIRenderer` from `@adia-ai/a2ui`, a custom renderer,
16
16
  * or a test stub.
17
17
  *
18
18
  * Contract: