@adia-ai/adia-ui-forge 0.8.4 → 0.8.6

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 (72) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/CHANGELOG.md +27 -2
  3. package/README.md +13 -4
  4. package/agents/a2ui-builder.corpus.json +35 -0
  5. package/agents/a2ui-builder.md +37 -0
  6. package/agents/component-author.corpus.json +40 -0
  7. package/agents/component-author.md +10 -1
  8. package/agents/framework-reviewer.corpus.json +35 -0
  9. package/agents/framework-reviewer.md +42 -0
  10. package/agents/release-builder.corpus.json +39 -0
  11. package/agents/release-builder.md +39 -0
  12. package/agents/routing-corpus.json +38 -38
  13. package/bin/release-pretag-docs-gate +226 -0
  14. package/commands/release.md +5 -3
  15. package/hooks/hooks.json +10 -0
  16. package/package.json +1 -1
  17. package/skills/adia-a2ui/SKILL.md +37 -8
  18. package/skills/adia-a2ui/evals/routing-corpus.json +36 -29
  19. package/skills/adia-a2ui/references/pipeline-overview.md +1 -1
  20. package/skills/adia-a2ui/references/zettel-calibration.md +5 -5
  21. package/skills/adia-author/SKILL.md +16 -8
  22. package/skills/adia-author/evals/routing-corpus.json +39 -218
  23. package/skills/adia-author/references/anti-patterns.md +7 -7
  24. package/skills/adia-author/references/api-contract.md +9 -9
  25. package/skills/adia-author/references/authoring-cycle.md +25 -6
  26. package/skills/adia-author/references/code-style.md +4 -5
  27. package/skills/adia-author/references/lifecycle-patterns.md +8 -8
  28. package/skills/adia-author/references/llm-bridge.md +7 -0
  29. package/skills/adia-author/references/token-contract.md +5 -5
  30. package/skills/adia-author/references/worked-example.md +34 -18
  31. package/skills/adia-author/references/yaml-contract.md +1 -1
  32. package/skills/adia-deploy/SKILL.md +71 -12
  33. package/skills/adia-deploy/evals/routing-corpus.json +37 -0
  34. package/skills/adia-deploy/references/deploy-playbooks.md +1 -1
  35. package/skills/adia-dogfood/SKILL.md +71 -11
  36. package/skills/adia-dogfood/evals/routing-corpus.json +34 -0
  37. package/skills/adia-dogfood/references/admin-shell-anatomy.md +1 -1
  38. package/skills/adia-gen-review/SKILL.md +73 -7
  39. package/skills/adia-gen-review/evals/routing-corpus.json +34 -0
  40. package/skills/adia-gen-review/scripts/gen-review-decompose.mjs +5 -0
  41. package/skills/adia-llm-internals/SKILL.md +10 -6
  42. package/skills/adia-llm-internals/evals/routing-corpus.json +37 -0
  43. package/skills/adia-llm-internals/references/bridge-facade.md +2 -2
  44. package/skills/adia-llm-internals/references/streaming-sse.md +1 -1
  45. package/skills/adia-release/SKILL.md +43 -13
  46. package/skills/adia-release/evals/evals.json +24 -0
  47. package/skills/adia-release/evals/routing-corpus.json +35 -0
  48. package/skills/adia-release/references/changelog-discipline.md +15 -9
  49. package/skills/adia-release/references/cut-procedure.md +78 -24
  50. package/skills/adia-release/references/gates-catalog.md +3 -3
  51. package/skills/adia-release/references/independent-package-release.md +1 -1
  52. package/skills/adia-release/references/recovery-paths.md +4 -2
  53. package/skills/adia-release/scripts/bump.mjs +32 -1
  54. package/skills/adia-release/scripts/dispatch-publish.mjs +49 -11
  55. package/skills/adia-release/scripts/gate-roster.mjs +71 -0
  56. package/skills/adia-release/scripts/insert-stub.mjs +36 -2
  57. package/skills/adia-release/scripts/promote-unreleased.mjs +35 -1
  58. package/skills/adia-release/scripts/release-pack.mjs +315 -56
  59. package/skills/adia-release/scripts/tag-lockstep.mjs +29 -7
  60. package/skills/adia-site-docs/SKILL.md +6 -1
  61. package/skills/adia-site-docs/evals/routing-corpus.json +35 -173
  62. package/skills/adia-ssr/SKILL.md +128 -0
  63. package/skills/adia-ssr/evals/audit-report.md +63 -0
  64. package/skills/adia-ssr/evals/routing-corpus.json +34 -0
  65. package/skills/adia-ssr/references/consumer-workarounds.md +81 -0
  66. package/skills/adia-ssr/references/failure-shapes.md +164 -0
  67. package/skills/adia-ssr/references/guard-patterns.md +183 -0
  68. package/skills/adia-ssr/references/status-ledger.md +33 -0
  69. package/skills/adia-ssr/references/test-without-linkedom.md +129 -0
  70. package/agents/a2ui-engineer.md +0 -26
  71. package/agents/framework-verifier.md +0 -26
  72. package/agents/release-engineer.md +0 -26
@@ -1,222 +1,43 @@
1
1
  {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "name": "adia-author routing accuracy corpus",
4
- "version": "2.0.0",
5
- "purpose": "Routing-eval corpus for adia-author (adia-forge plugin). Each phrase declares whether adia-author SHOULD be the routing target. Scored by the estate's TF-IDF routing-eval runner against the skill's description (heuristic token overlap).",
6
- "scoring_notes": "Heuristic signal, not ground truth. Treat misroutes as a prompt to tighten the skill description, never as a reason to keyword-stuff it. Real harness routing is LLM-driven.",
7
- "license": "internal",
8
- "scope": "adia-author routing does this phrase activate adia-author?",
9
-
10
- "minimums_per_spec": {
11
- "trigger_phrases": 21,
12
- "adversarial_phrases": 6,
13
- "task_shapes_covered": "new-primitive, modify-primitive, shell, module-promotion, drift-audit, llm-bridge, composite-demo",
14
- "adversarial_fraction": "20%"
15
- },
16
-
17
- "phrases": [
18
- {
19
- "id": "author-new-primitive-01",
20
- "phrase": "add a new button-ui primitive component",
21
- "should_route_to_author": true,
22
- "expected_shape": "new-primitive",
23
- "rationale": "Canonical new-primitive task shape."
24
- },
25
- {
26
- "id": "author-new-primitive-02",
27
- "phrase": "build a new <toggle-ui> component from scratch",
28
- "should_route_to_author": true,
29
- "expected_shape": "new-primitive",
30
- "rationale": "'build a <foo-ui>' phrasing."
31
- },
32
- {
33
- "id": "author-new-primitive-03",
34
- "phrase": "create a new primitive web component in packages/web-components",
35
- "should_route_to_author": true,
36
- "expected_shape": "new-primitive",
37
- "rationale": "Explicit packages/web-components path mention."
38
- },
39
-
40
- {
41
- "id": "author-modify-01",
42
- "phrase": "add a new prop to table-ui",
43
- "should_route_to_author": true,
44
- "expected_shape": "modify-primitive",
45
- "rationale": "Modify existing primitive — add a prop."
46
- },
47
- {
48
- "id": "author-modify-02",
49
- "phrase": "fix the CSS in card-ui to handle the new bleed variant",
50
- "should_route_to_author": true,
51
- "expected_shape": "modify-primitive",
52
- "rationale": "Modify existing primitive CSS."
53
- },
54
- {
55
- "id": "author-modify-03",
56
- "phrase": "update the input-ui yaml to add a placeholder attribute",
57
- "should_route_to_author": true,
58
- "expected_shape": "modify-primitive",
59
- "rationale": "Update the yaml SoT for an existing primitive."
60
- },
61
-
62
- {
63
- "id": "author-shell-01",
64
- "phrase": "build the chat-shell composition with the new sidebar slot",
65
- "should_route_to_author": true,
66
- "expected_shape": "shell",
67
- "rationale": "Shell authoring."
68
- },
69
- {
70
- "id": "author-shell-02",
71
- "phrase": "author a new web-module shell at packages/web-modules/editor/editor-shell",
72
- "should_route_to_author": true,
73
- "expected_shape": "shell",
74
- "rationale": "Explicit web-modules + shell."
75
- },
76
- {
77
- "id": "author-shell-03",
78
- "phrase": "add a pane behaviour to admin-shell per the bespoke shell-tier convention",
79
- "should_route_to_author": true,
80
- "expected_shape": "shell",
81
- "rationale": "Bespoke shell-tier (ADR-0023 shape) work."
82
- },
83
-
84
- {
85
- "id": "author-promote-01",
86
- "phrase": "promote this inline content to a shared web-modules module",
87
- "should_route_to_author": true,
88
- "expected_shape": "module-promotion",
89
- "rationale": "Promote inline → module."
90
- },
91
- {
92
- "id": "author-promote-02",
93
- "phrase": "this content keeps repeating across apps, extract to a shared module",
94
- "should_route_to_author": true,
95
- "expected_shape": "module-promotion",
96
- "rationale": "Repetition trigger."
97
- },
98
- {
99
- "id": "author-promote-03",
100
- "phrase": "lift this billing-summary block from apps/saas to web-modules",
101
- "should_route_to_author": true,
102
- "expected_shape": "module-promotion",
103
- "rationale": "Lift inline page content to a reusable module."
104
- },
105
-
106
- {
107
- "id": "author-audit-01",
108
- "phrase": "audit the four-axis contract for table-ui",
109
- "should_route_to_author": true,
110
- "expected_shape": "drift-audit",
111
- "rationale": "Contract drift audit."
112
- },
113
- {
114
- "id": "author-audit-02",
115
- "phrase": "check the token usage in card-ui for drift",
116
- "should_route_to_author": true,
117
- "expected_shape": "drift-audit",
118
- "rationale": "Token audit procedure."
119
- },
120
- {
121
- "id": "author-audit-03",
122
- "phrase": "lifecycle audit on dropdown-ui — symmetric connected/disconnected?",
123
- "should_route_to_author": true,
124
- "expected_shape": "drift-audit",
125
- "rationale": "Lifecycle audit."
126
- },
127
-
128
- {
129
- "id": "author-llm-01",
130
- "phrase": "extend the LLM bridge to add a new provider",
131
- "should_route_to_author": true,
132
- "expected_shape": "llm-bridge",
133
- "rationale": "Extend @adia-ai/llm."
134
- },
135
- {
136
- "id": "author-llm-02",
137
- "phrase": "modify createAdapter in @adia-ai/llm to add chunk-shape support",
138
- "should_route_to_author": true,
139
- "expected_shape": "llm-bridge",
140
- "rationale": "Explicit createAdapter + @adia-ai/llm mention."
141
- },
142
- {
143
- "id": "author-llm-03",
144
- "phrase": "set up the LLM-bridge surface for a new tool-call provider",
145
- "should_route_to_author": true,
146
- "expected_shape": "llm-bridge",
147
- "rationale": "LLM-bridge trigger phrase."
148
- },
149
-
150
- {
151
- "id": "author-demo-01",
152
- "phrase": "author a demo for the billing-overview composite",
153
- "should_route_to_author": true,
154
- "expected_shape": "composite-demo",
155
- "rationale": "Composite-demo authoring."
156
- },
157
- {
158
- "id": "author-demo-02",
159
- "phrase": "compose the examples.html for dashboard-layout",
160
- "should_route_to_author": true,
161
- "expected_shape": "composite-demo",
162
- "rationale": "'compose examples.html for Y' trigger."
163
- },
164
- {
165
- "id": "author-demo-03",
166
- "phrase": "write the demo for <integrations-page-ui> in packages/web-modules/settings",
167
- "should_route_to_author": true,
168
- "expected_shape": "composite-demo",
169
- "rationale": "'write the demo for <module-ui>' + web-modules path."
170
- },
171
-
172
- {
173
- "id": "author-adv-01",
174
- "phrase": "compose this Figma mock into AdiaUI components for our consumer app",
175
- "should_route_to_author": false,
176
- "expected_alternative": "adia-compose (adia-factory plugin)",
177
- "rationale": "Adversarial — consumer-side composition (screens FROM existing primitives). The description NEG-fences it."
178
- },
179
- {
180
- "id": "author-adv-02",
181
- "phrase": "cut a release of the next version and publish the npm packages",
182
- "should_route_to_author": false,
183
- "expected_alternative": "adia-release",
184
- "rationale": "Adversarial — release territory."
185
- },
186
- {
187
- "id": "author-adv-03",
188
- "phrase": "tune the zettel composition coverage; eval is at 38%",
189
- "should_route_to_author": false,
190
- "expected_alternative": "adia-a2ui",
191
- "rationale": "Adversarial — a2ui pipeline internals (compose strategies, eval coverage)."
192
- },
193
- {
194
- "id": "author-adv-04",
195
- "phrase": "build a user profile card with avatar and edit actions",
196
- "should_route_to_author": false,
197
- "expected_alternative": "adia-compose (adia-factory plugin)",
198
- "rationale": "Adversarial — canonical consumer-composition task (build UI from intent)."
199
- },
200
- {
201
- "id": "author-adv-05",
202
- "phrase": "deploy the api service to the hosting platform",
203
- "should_route_to_author": false,
204
- "expected_alternative": "adia-deploy",
205
- "rationale": "Adversarial — deployment/ops territory."
206
- },
207
- {
208
- "id": "author-adv-06",
209
- "phrase": "explain how React hooks work",
210
- "should_route_to_author": false,
211
- "expected_alternative": null,
212
- "rationale": "Adversarial — generic framework knowledge; no AdiaUI skill should activate."
213
- }
2
+ "positives": [
3
+ "add a new button-ui primitive component",
4
+ "build a new <toggle-ui> component from scratch",
5
+ "create a new primitive web component in packages/web-components",
6
+ "add a new prop to table-ui",
7
+ "fix the CSS in card-ui to handle the new bleed variant",
8
+ "update the input-ui yaml to add a placeholder attribute",
9
+ "build the chat-shell composition with the new sidebar slot",
10
+ "author a new web-module shell at packages/web-modules/editor/editor-shell",
11
+ "add a pane behaviour to admin-shell per the bespoke shell-tier convention",
12
+ "promote this inline content to a shared web-modules module",
13
+ "this content keeps repeating across apps, extract to a shared module",
14
+ "lift this billing-summary block from apps/saas to web-modules",
15
+ "audit the four-axis contract for table-ui",
16
+ "check the token usage in card-ui for drift",
17
+ "lifecycle audit on dropdown-ui \u2014 symmetric connected/disconnected?",
18
+ "author a demo for the billing-overview composite",
19
+ "compose the examples.html for dashboard-layout",
20
+ "write the demo for <integrations-page-ui> in packages/web-modules/settings"
214
21
  ],
215
-
216
- "evaluator_notes": {
217
- "current_state": "27 cases (21 trigger + 6 adversarial). Each of the 7 task shapes has 3 trigger cases. The old corpus's 3 Teach-mode cases were dropped (skill-teaching is estate-level maintenance now, not a product-skill mode).",
218
- "promotion_criteria": "Promote to a CI gate (warn hard-fail) when F1 ≥ 0.85 on this corpus across 3+ consecutive runs without description edits.",
219
- "review_cadence": "Re-run on every adia-author description edit. Add 1-2 new cases per checkpoint reflecting newly-observed routing failure modes.",
220
- "known_limitations": "module-promotion and composite-demo phrases overlap semantically ('lift to web-modules' vs 'author demo for module') — the heuristic scorer may not disambiguate; the harness with file-path context will (the demo path pattern also fires the demo-postwrite-pattern-gate hook regardless of routing)."
22
+ "negatives": [
23
+ "compose this Figma mock into AdiaUI components for our consumer app",
24
+ "cut a release of the next version and publish the npm packages",
25
+ "tune the zettel composition coverage; eval is at 38%",
26
+ "build a user profile card with avatar and edit actions",
27
+ "deploy the api service to the hosting platform",
28
+ "explain how React hooks work",
29
+ "the gemini adapter is dropping usage tokens on streamed responses",
30
+ "fix the openai stopReason mapping in the llm client",
31
+ "extend the LLM bridge to add a new provider",
32
+ "modify createAdapter in @adia-ai/llm to add chunk-shape support",
33
+ "set up the LLM-bridge surface for a new tool-call provider"
34
+ ],
35
+ "_measured": {
36
+ "as_of": "2026-07-18",
37
+ "scorer": "routing_eval.py (nonoun-plugins/forge)",
38
+ "f1": 0.971,
39
+ "precision": 1.0,
40
+ "recall": 0.944,
41
+ "exit_code": 0
221
42
  }
222
43
  }
@@ -376,7 +376,7 @@ disconnected() {
376
376
 
377
377
  ```javascript
378
378
  // WRONG — chart.js (pre-fix)
379
- class AdiaChart extends AdiaElement {
379
+ class UIChart extends UIElement {
380
380
  connected() { /* ... */ this.#ro = new ResizeObserver(...); }
381
381
 
382
382
  disconnected() {
@@ -408,8 +408,8 @@ disconnected() {
408
408
  ### AP-L3 · Missing `super.connected()` / `super.disconnected()`
409
409
 
410
410
  ```javascript
411
- // WRONG — AdiaFormElement subclass missing super call
412
- class AdiaInput extends AdiaFormElement {
411
+ // WRONG — UIFormElement subclass missing super call
412
+ class UIInput extends UIFormElement {
413
413
  connected() {
414
414
  // super.connected() NOT called
415
415
  this.#inputEl = this.querySelector('input');
@@ -479,7 +479,7 @@ updateConfig(opts) {
479
479
 
480
480
  ```javascript
481
481
  // WRONG — drawer.js (pre-fix)
482
- class AdiaDrawer extends AdiaElement {
482
+ class UIDrawer extends UIElement {
483
483
  static template = () => html``; // ← looks harmless. It isn't.
484
484
 
485
485
  connected() {
@@ -489,7 +489,7 @@ class AdiaDrawer extends AdiaElement {
489
489
  }
490
490
  ```
491
491
 
492
- **What went wrong:** `AdiaElement`'s base `connectedCallback` runs an effect that calls `stamp(template(this), this)`. `stamp` calls `mount`, which calls `container.replaceChildren(fragment)`. Even an "empty" `html\`\``produces a non-null result, so`replaceChildren`runs and clears every authored child (header/section/footer) out of the host element. The component's own`render()` then tries to migrate children that no longer exist.
492
+ **What went wrong:** `UIElement`'s base `connectedCallback` runs an effect that calls `stamp(template(this), this)`. `stamp` calls `mount`, which calls `container.replaceChildren(fragment)`. Even an "empty" `html\`\``produces a non-null result, so`replaceChildren`runs and clears every authored child (header/section/footer) out of the host element. The component's own`render()` then tries to migrate children that no longer exist.
493
493
 
494
494
  Symptom: drawers render with a close button in an empty panel; all authored content is gone. Hard to debug because the children WERE in the DOM at `connected()` time — they get wiped milliseconds later when the effect runs.
495
495
 
@@ -497,8 +497,8 @@ Symptom: drawers render with a close button in an empty panel; all authored cont
497
497
 
498
498
  ```javascript
499
499
  // RIGHT — no template override
500
- class AdiaDrawer extends AdiaElement {
501
- // base AdiaElement.template returns null → stamp() is skipped →
500
+ class UIDrawer extends UIElement {
501
+ // base UIElement.template returns null → stamp() is skipped →
502
502
  // authored light-DOM children survive through render().
503
503
 
504
504
  connected() { /* ... */ }
@@ -4,7 +4,7 @@ Deep dive on declaring component APIs in AdiaUI. Read this when adding a new pro
4
4
 
5
5
  ## The `static properties` block
6
6
 
7
- Every `AdiaElement` subclass declares its public API as a `static properties` object. Keys are camelCase JS names; values describe type, default, reflection, and attribute mapping.
7
+ Every `UIElement` subclass declares its public API as a `static properties` object. Keys are camelCase JS names; values describe type, default, reflection, and attribute mapping.
8
8
 
9
9
  ```javascript
10
10
  static properties = {
@@ -141,21 +141,21 @@ Reserve `error` for validation state (`[error]` on form inputs matches ARIA patt
141
141
  The component has three names that must agree:
142
142
 
143
143
  - **File path:** `packages/web-components/components/foo/foo.js`
144
- - **Class name:** `class AdiaFoo extends AdiaElement`
145
- - **Custom element tag:** `customElements.define('foo-ui', AdiaFoo)`
144
+ - **Class name:** `class UIFoo extends UIElement`
145
+ - **Custom element tag:** `customElements.define('foo-ui', UIFoo)`
146
146
 
147
147
  A fourth consistency requirement: the CSS file at `packages/web-components/components/foo/foo.css` uses `@scope (foo-ui)`.
148
148
 
149
- ## Extending `AdiaFormElement`
149
+ ## Extending `UIFormElement`
150
150
 
151
- Form-participating components extend `AdiaFormElement` (which extends `AdiaElement`) and get `ElementInternals` wiring, form-reset handling, and `.form` / `.labels` / `.validity` accessors for free.
151
+ Form-participating components extend `UIFormElement` (which extends `UIElement`) and get `ElementInternals` wiring, form-reset handling, and `.form` / `.labels` / `.validity` accessors for free.
152
152
 
153
153
  ```javascript
154
- import { AdiaFormElement } from '../../core/form.js';
154
+ import { UIFormElement } from '../../core/form.js';
155
155
 
156
- class AdiaInput extends AdiaFormElement {
156
+ class UIInput extends UIFormElement {
157
157
  static properties = {
158
- ...AdiaFormElement.properties, // inherit name, value, disabled, required, etc.
158
+ ...UIFormElement.properties, // inherit name, value, disabled, required, etc.
159
159
  placeholder: { type: String, default: '', reflect: true },
160
160
  };
161
161
 
@@ -180,7 +180,7 @@ Key details:
180
180
 
181
181
  - **Always `super.connected()` and `super.disconnected()`** — without them, form-association doesn't register.
182
182
  - **`this.syncValue(str)`** — call this whenever the value changes to update the form-submitted string. Accepts a string.
183
- - **Inheriting properties** — spread `AdiaFormElement.properties` into your own `static properties` so you don't re-declare `name`, `disabled`, `required`.
183
+ - **Inheriting properties** — spread `UIFormElement.properties` into your own `static properties` so you don't re-declare `name`, `disabled`, `required`.
184
184
 
185
185
  ## Event conventions
186
186
 
@@ -9,8 +9,8 @@ The 5-step procedure run AFTER [primitive-audit.md](primitive-audit.md) clears (
9
9
  Before writing or editing, load these four files. They are the ground truth:
10
10
 
11
11
  - `.claude/docs/specs/component-token-contract.md` — the authoritative invariants. Skim the whole thing if you haven't read it this session; focus on "Variants vs Modes" and "Sanctioned Mode Attributes" if you're adding a new layout-affecting attribute.
12
- - `packages/web-components/core/element.js` — `AdiaElement` base class. The `static properties` schema, `connected()`/`disconnected()`/`render()` lifecycle, and attribute-mapping conventions are all defined here.
13
- - `packages/web-components/core/form.js` — `AdiaFormElement`. Only needed if the new component participates in forms (inputs, selects, checkboxes, etc.).
12
+ - `packages/web-components/core/element.js` — `UIElement` base class. The `static properties` schema, `connected()`/`disconnected()`/`render()` lifecycle, and attribute-mapping conventions are all defined here.
13
+ - `packages/web-components/core/form.js` — `UIFormElement`. Only needed if the new component participates in forms (inputs, selects, checkboxes, etc.).
14
14
  - At least one good-citizen reference that matches the shape of what you're building. Pick from: `button-ui`, `card-ui`, `input-ui`, `textarea-ui`, `check-ui`. Read both the `.js` and the `.css`.
15
15
 
16
16
  ## Step 2 — Classify the work before you write
@@ -41,7 +41,7 @@ These rules are the distilled lessons from a 5-iteration audit. Each one corresp
41
41
 
42
42
  5. **Reserved-name anti-patterns.** Avoid: `title` (collides with HTML tooltip attribute), `active` on parent components (use `value` for a selection or `step` for an index — per-item `active` on children is fine), `error` in variant names (use `danger`; reserve `error` for validation state), `disabled` on non-form-participating components (use `readonly`), `multiple` with exclusion semantics (use a negated positive like `single`).
43
43
 
44
- 6. **Element tag ends in `-ui`; JS class is `Adia<Component>`.** `<foo-ui>` ↔ `class AdiaFoo extends AdiaElement`. Three-way consistency: filename, class name, custom-element tag. The sanctioned `-n` carve-out is `cot-ui` (the chain-of-thought streaming component); `nav-ui` was deprecated in favor of the `-ui` replacements. New `-n` tags require a contract-doc update — see `.claude/docs/specs/component-token-contract.md`.
44
+ 6. **Element tag ends in `-ui`; JS class is `UI<Component>`.** `<foo-ui>` ↔ `class UIFoo extends UIElement`. Three-way consistency: filename, class name, custom-element tag. The sanctioned `-n` carve-out is `cot-ui` (the chain-of-thought streaming component); `nav-ui` was deprecated in favor of the `-ui` replacements. New `-n` tags require a contract-doc update — see `.claude/docs/specs/component-token-contract.md`.
45
45
 
46
46
  ### CSS
47
47
 
@@ -86,7 +86,7 @@ These rules are the distilled lessons from a 5-iteration audit. Each one corresp
86
86
 
87
87
  1. **Every `addEventListener` in `connected()` has a matching `removeEventListener` in `disconnected()`.** Handler must be a stable `#field` arrow (`#onClick = (e) => { ... }`), never an inline arrow passed to `addEventListener`. Inline arrows can't be removed — `removeEventListener` needs reference equality.
88
88
 
89
- 2. **`AdiaFormElement` subclasses call `super.connected()` and `super.disconnected()`.** `ElementInternals` registration depends on it. Omitting `super` strands the form-association.
89
+ 2. **`UIFormElement` subclasses call `super.connected()` and `super.disconnected()`.** `ElementInternals` registration depends on it. Omitting `super` strands the form-association.
90
90
 
91
91
  3. **Timers and observers are torn down.** `clearInterval`, `clearTimeout`, `ResizeObserver.disconnect()`, `MutationObserver.disconnect()`, `IntersectionObserver.disconnect()` all in `disconnected()`.
92
92
 
@@ -164,7 +164,7 @@ Before declaring the work done, run through this checklist. If anything fails, f
164
164
  - [ ] Every `static properties` entry uses `attribute:` (not `attr:`).
165
165
  - [ ] Every state-bearing Boolean has `reflect: true`.
166
166
  - [ ] No reserved-name anti-patterns (`title`, parent-level `active`, `error` variant, `disabled` on non-form, exclusion-`multiple`).
167
- - [ ] Element tag ends in `-ui`; class is `Adia<Component>`.
167
+ - [ ] Element tag ends in `-ui`; class is `UI<Component>`.
168
168
 
169
169
  ### CSS
170
170
 
@@ -179,11 +179,29 @@ Before declaring the work done, run through this checklist. If anything fails, f
179
179
 
180
180
  - [ ] Every `addEventListener` in `connected()` has a paired `removeEventListener` in `disconnected()`.
181
181
  - [ ] All handlers passed to `addEventListener` are stable `#field` arrows (or bound method refs), not inline arrows.
182
- - [ ] If the class extends `AdiaFormElement`, both `connected()` and `disconnected()` call `super`.
182
+ - [ ] If the class extends `UIFormElement`, both `connected()` and `disconnected()` call `super`.
183
183
  - [ ] Every timer/observer created in `connected()` is disposed in `disconnected()`.
184
184
  - [ ] Cached DOM refs (`this.#fooEl`) are nulled in `disconnected()`.
185
185
  - [ ] Class declares `disconnected()` exactly once.
186
186
 
187
+ ## Step 4b — Author the yaml SoT (+ regenerate the sidecar)
188
+
189
+ A component isn't just its `.js`/`.css` — the `<name>.yaml` is the SOURCE OF
190
+ TRUTH the whole pipeline reads (docs site, A2UI registries, consumer
191
+ harnesses, `.d.ts` codegen). Every new primitive ships one; every prop/slot/
192
+ event change updates it. Field-by-field contract:
193
+ [yaml-contract.md](yaml-contract.md). Then regenerate — never hand-edit the
194
+ sidecar (`sidecar-prewrite-guard` blocks it anyway):
195
+
196
+ ```bash
197
+ npm run build:components # yaml → <name>.a2ui.json + catalog + .d.ts
198
+ node scripts/build/components.mjs --verify # "clean — N files up-to-date"
199
+ ```
200
+
201
+ A primitive also needs BOTH barrel registrations — the CSS `@import` in
202
+ `styles/components.css` AND the JS `export` in `components/index.js`
203
+ (`scripts/audit/check-components-js-barrel.mjs` gates the second).
204
+
187
205
  ## Step 5 — Run the project's verification gates
188
206
 
189
207
  Before committing, run the project's verify scripts. These catch the drift-shaped bugs the checklist can miss:
@@ -206,4 +224,5 @@ If a gate fails, fix before declaring done.
206
224
  - [lifecycle-patterns.md](lifecycle-patterns.md) — timers, observers, popovers, listener patterns
207
225
  - [anti-patterns.md](anti-patterns.md) — full failure-mode catalogue, file:line refs
208
226
  - [worked-example.md](worked-example.md) — badge-ui + counter-ui walkthroughs
227
+ - [yaml-contract.md](yaml-contract.md) — the `<name>.yaml` SoT schema (Step 4b)
209
228
  - [token-contract.md](token-contract.md) — token audit (post-implementation check)
@@ -210,7 +210,7 @@ Native DOM accessors (`textContent`, `innerHTML`) get clobbered if declared in `
210
210
  Every `addEventListener` in `connected()` must be paired with a `removeEventListener` in `disconnected()`. Every timer cleared, every observer disconnected, every popover removed. Handlers must be stable `#field` arrows so `removeEventListener` finds them via reference equality.
211
211
 
212
212
  ```js
213
- class AdiaBadge extends AdiaElement {
213
+ class UIBadge extends UIElement {
214
214
  #onRemove = (e) => { /* ... */ }; // stable handler
215
215
 
216
216
  connected() {
@@ -226,7 +226,7 @@ class AdiaBadge extends AdiaElement {
226
226
 
227
227
  Inline arrows passed to `addEventListener` look fine and leak quietly — `removeEventListener` no-ops because the new arrow has different identity. Three components in one audit cycle bit on this exact bug.
228
228
 
229
- If the class extends `AdiaFormElement`, `connected()` and `disconnected()` MUST call `super.*` — `ElementInternals` registration depends on it. And declare `disconnected()` exactly once per class; the second silently overrides the first.
229
+ If the class extends `UIFormElement`, `connected()` and `disconnected()` MUST call `super.*` — `ElementInternals` registration depends on it. And declare `disconnected()` exactly once per class; the second silently overrides the first.
230
230
 
231
231
  Full lifecycle patterns in [lifecycle-patterns.md](lifecycle-patterns.md).
232
232
 
@@ -276,11 +276,11 @@ When transparency-mixing colors, use `oklab` not `oklch` for the interpolation s
276
276
 
277
277
  ## Legacy avoidance
278
278
 
279
- The library was renamed from `@agent-ui-kit/*` to `@adia-ai/*`; tokens went from `--n-*` to `--a-*`; the base class went from `NanoElement` to `AdiaElement`. Don't use the legacy forms in new code. Don't reference `nano-ui` in notes, commit messages, CHANGELOG entries, or any AdiaUI artifact.
279
+ The library was renamed from `@agent-ui-kit/*` to `@adia-ai/*`; tokens went from `--n-*` to `--a-*`; the base class went `NanoElement` `AdiaElement` → `UIElement` (ADR-0016 class rename). Don't use the legacy forms in new code. Don't reference `nano-ui` in notes, commit messages, CHANGELOG entries, or any AdiaUI artifact.
280
280
 
281
281
  ```js
282
282
  // right
283
- import { AdiaElement } from '@adia-ai/web-components';
283
+ import { UIElement } from '@adia-ai/web-components/core';
284
284
  :where(:scope) { --button-bg: var(--a-primary-bg); }
285
285
 
286
286
  // wrong
@@ -319,7 +319,6 @@ For component source under `packages/web-components/components/**`, the gate is
319
319
  - [css-patterns.md](css-patterns.md) — full @scope + variant/mode CSS architecture
320
320
  - [lifecycle-patterns.md](lifecycle-patterns.md) — timers, observers, popovers, listeners
321
321
  - [token-contract.md](token-contract.md) — token audit procedure
322
- - [llm-bridge.md](llm-bridge.md) — extend @adia-ai/llm
323
322
  - [module-promotion.md](module-promotion.md) — promote inline → module
324
323
  - [anti-patterns.md](anti-patterns.md) — failure-mode catalogue with file:line refs
325
324
  - **adia-a2ui** (sibling skill) — generator / corpus / MCP pipeline
@@ -1,13 +1,13 @@
1
1
  # Lifecycle Patterns — Listeners, Timers, Observers, Popovers
2
2
 
3
- Deep dive on symmetric `connected()` / `disconnected()` in AdiaUI components. Read when adding any side effect (listener, timer, observer, popover) to a component, or when inheriting from `AdiaFormElement`.
3
+ Deep dive on symmetric `connected()` / `disconnected()` in AdiaUI components. Read when adding any side effect (listener, timer, observer, popover) to a component, or when inheriting from `UIFormElement`.
4
4
 
5
5
  ## The symmetry rule
6
6
 
7
7
  Every side effect set up in `connected()` has a matching teardown in `disconnected()`. The teardown is authored at the same time as the setup, not later — if you leave `disconnected()` for tomorrow, tomorrow won't happen.
8
8
 
9
9
  ```javascript
10
- class AdiaWidget extends AdiaElement {
10
+ class UIWidget extends UIElement {
11
11
  static properties = { /* ... */ };
12
12
  static template = () => null;
13
13
 
@@ -150,16 +150,16 @@ disconnected() {
150
150
 
151
151
  **Lesson:** a class must declare `disconnected()` exactly once. If you need to add teardown, edit the existing method. Duplicate method names silently shadow — no error, no warning.
152
152
 
153
- ## `AdiaFormElement` — `super` discipline
153
+ ## `UIFormElement` — `super` discipline
154
154
 
155
- Form-participating components inherit `ElementInternals` wiring from `AdiaFormElement`. That wiring only works if `super.connected()` and `super.disconnected()` are called:
155
+ Form-participating components inherit `ElementInternals` wiring from `UIFormElement`. That wiring only works if `super.connected()` and `super.disconnected()` are called:
156
156
 
157
157
  ```javascript
158
- import { AdiaFormElement } from '../../core/form.js';
158
+ import { UIFormElement } from '../../core/form.js';
159
159
 
160
- class AdiaInput extends AdiaFormElement {
160
+ class UIInput extends UIFormElement {
161
161
  static properties = {
162
- ...AdiaFormElement.properties,
162
+ ...UIFormElement.properties,
163
163
  placeholder: { type: String, default: '', reflect: true },
164
164
  };
165
165
 
@@ -296,7 +296,7 @@ Especially important for components that are attached/detached frequently (modal
296
296
  - **Inline arrow + `removeEventListener`** — the listener isn't really being removed. Silent leak.
297
297
  - **Forgot to create `disconnected()`** — if `connected()` adds side effects, `disconnected()` must exist. No exceptions.
298
298
  - **Two `disconnected()` methods in the same class** — the second silently wins; the first's cleanup is lost.
299
- - **`super.connected()` missing in `AdiaFormElement` subclass** — form participation silently fails.
299
+ - **`super.connected()` missing in `UIFormElement` subclass** — form participation silently fails.
300
300
  - **Popover / tooltip never cleaned up** — stays in `document.body` forever.
301
301
  - **Observer recreated on every render** — re-observing without disconnecting first leaks observer refs.
302
302
  - **Timer fired after component removed** — not cleared in `disconnected()`, fires on a dead component. Can cause null-deref crashes or phantom re-renders.
@@ -1,5 +1,12 @@
1
1
  # LLM Bridge extension — @adia-ai/llm
2
2
 
3
+ **Superseded 2026-07-18 — `@adia-ai/llm` internals are `adia-llm-internals`'s charter, not
4
+ `adia-author`'s.** That skill's references (`adapter-contract.md`, `streaming-sse.md`,
5
+ `model-registry.md`, `bridge-facade.md`, `browser-proxy-boundary.md`, `add-a-provider.md`)
6
+ are the current, maintained source — this file is kept only as a historical pointer and is
7
+ no longer linked from `adia-author`'s task-shape table or `code-style.md`. Route provider/
8
+ streaming/bridge work to `adia-llm-internals`.
9
+
3
10
  Use when adding a 4th provider, modifying `createAdapter()`, changing the streaming chunk shape, or extending `packages/llm/server.js`.
4
11
 
5
12
  This reference is about **modifying** the package. For day-to-day consumption (import + call), the README at `packages/llm/README.md` is sufficient.
@@ -14,7 +14,7 @@ Every component's `.css` file must follow the **two-block @scope** pattern:
14
14
  /* Block 1: token declarations on :where(:scope) — zero specificity */
15
15
  @scope (my-component-ui) {
16
16
  :where(:scope) {
17
- --my-bg: var(--a-surface-1);
17
+ --my-bg: var(--a-bg);
18
18
  --my-text: var(--a-fg);
19
19
  --my-radius: var(--a-radius-md);
20
20
  }
@@ -30,8 +30,8 @@ Every component's `.css` file must follow the **two-block @scope** pattern:
30
30
 
31
31
  /* Variants override TOKENS, not base styles */
32
32
  :scope[variant="danger"] {
33
- --my-bg: var(--a-danger-surface);
34
- --my-text: var(--a-danger-text);
33
+ --my-bg: var(--a-danger-bg);
34
+ --my-text: var(--a-danger-fg);
35
35
  }
36
36
  }
37
37
  ```
@@ -40,7 +40,7 @@ Every component's `.css` file must follow the **two-block @scope** pattern:
40
40
 
41
41
  1. **Zero raw color values** anywhere in component CSS
42
42
  - No `#fff`, `rgb(...)`, `oklch(...)` literals
43
- - All colors must reference `--a-chrome-*`, `--a-data-0..9`, `--a-fg*`, `--a-surface-*`, or family tokens (`--a-brand-*`, `--a-primary-*`, etc.)
43
+ - All colors must reference `--a-chrome-*`, `--a-data-0..9`, `--a-fg*`, `--a-bg-*`, or family tokens (`--a-brand-*`, `--a-primary-*`, etc.)
44
44
  2. **Two-block pattern** — token declarations separate from style rules
45
45
  3. **Variants override tokens** — never rewrite base styles inside `[variant]` selectors. Change token values; the base styles absorb the change.
46
46
  4. **`:where(:scope)`** for token defaults — zero specificity lets consumers override tokens from outside
@@ -75,7 +75,7 @@ Every component's `.css` file must follow the **two-block @scope** pattern:
75
75
  4. **Check token usage in parent stylesheet**
76
76
 
77
77
  ```bash
78
- grep -n "--a-chrome\|--a-data\|--a-fg\|--a-surface" \
78
+ grep -n -- "--a-chrome\|--a-data\|--a-fg\|--a-bg" \
79
79
  packages/web-components/components/<name>/*.css
80
80
  ```
81
81