@adia-ai/adia-ui-forge 0.8.47 → 0.8.50

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 (28) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.codex-plugin/plugin.json +38 -0
  3. package/CHANGELOG.md +19 -0
  4. package/codex.interface.json +12 -0
  5. package/package.json +5 -3
  6. package/skills/a2ui-maintenance/SKILL.md +1 -0
  7. package/skills/a2ui-maintenance/agents/openai.yaml +3 -0
  8. package/skills/a2ui-maintenance/references/data-model-reactivity.md +96 -0
  9. package/skills/a2ui-maintenance/references/mcp-pipeline-ops.md +7 -3
  10. package/skills/demo-audit/SKILL.md +2 -0
  11. package/skills/demo-audit/agents/openai.yaml +3 -0
  12. package/skills/gen-ui-review/agents/openai.yaml +3 -0
  13. package/skills/llm-client-maintenance/agents/openai.yaml +3 -0
  14. package/skills/package-release/SKILL.md +2 -0
  15. package/skills/package-release/agents/openai.yaml +3 -0
  16. package/skills/package-release/references/cut-procedure.md +3 -0
  17. package/skills/package-release/scripts/gate-roster.mjs +6 -0
  18. package/skills/package-release/scripts/release-pack.mjs +45 -1
  19. package/skills/primitive-authoring/SKILL.md +2 -0
  20. package/skills/primitive-authoring/agents/openai.yaml +3 -0
  21. package/skills/primitive-authoring/references/INDEX.md +2 -0
  22. package/skills/primitive-authoring/references/api-contract.md +24 -0
  23. package/skills/primitive-authoring/references/for-attribute-event-contract.md +62 -0
  24. package/skills/primitive-authoring/references/form-control-sizing.md +59 -0
  25. package/skills/site-deployment/agents/openai.yaml +3 -0
  26. package/skills/site-docs-authoring/SKILL.md +2 -0
  27. package/skills/site-docs-authoring/agents/openai.yaml +3 -0
  28. package/skills/ssr-compatibility/agents/openai.yaml +3 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adia-ui-kit-forge",
3
- "version": "0.8.47",
3
+ "version": "0.8.50",
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-ui-kit-factory (the consumer/app-author plugin).",
5
5
  "author": {
6
6
  "name": "Kim",
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "adia-ui-kit-forge",
3
+ "version": "0.8.50",
4
+ "description": "Maintain the adia-ui (@adia-ai) framework itself — 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
+ "author": {
6
+ "name": "Kim",
7
+ "email": "kim.granlund@adia.ai",
8
+ "url": "https://github.com/adiahealth/gen-ui-kit"
9
+ },
10
+ "homepage": "https://github.com/adiahealth/gen-ui-kit",
11
+ "repository": "git+https://github.com/adiahealth/gen-ui-kit.git",
12
+ "license": "MIT",
13
+ "keywords": [
14
+ "adia-ui",
15
+ "a2ui",
16
+ "gen-ui",
17
+ "web-components",
18
+ "framework-authoring",
19
+ "release-engineering",
20
+ "maintainer"
21
+ ],
22
+ "skills": "./skills/",
23
+ "interface": {
24
+ "displayName": "Adia UI Forge",
25
+ "shortDescription": "Maintain the adia-ui (@adia-ai) framework: primitives, A2UI pipeline, releases",
26
+ "longDescription": "Adia UI Forge is the maintainer toolkit for the adia-ui (@adia-ai) light-DOM web-component framework — author primitives and shells, run and tune the A2UI generative-UI pipeline and its corpus, review gen-UI quality, sweep app-shell QA, cut lockstep releases, and deploy the docs site. The maintainer counterpart to Adia UI Factory (the consumer/app-author toolkit).",
27
+ "category": "Engineering",
28
+ "capabilities": [
29
+ "Read",
30
+ "Write"
31
+ ],
32
+ "defaultPrompt": [
33
+ "Audit adia-ui primitives for token drift",
34
+ "Run the A2UI generation pipeline and score the gallery output"
35
+ ],
36
+ "brandColor": "#1B4D8C"
37
+ }
38
+ }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog — adia-ui-kit-forge
2
2
 
3
+ ## [0.8.50] — 2026-08-23
4
+
5
+ ### Maintenance
6
+ - **Lockstep bump riding the v0.8.50 cut** (`scripts/release/check-lockstep.mjs`); the headline v0.8.50 work ships in @adia-ai/web-components (prose/verse sheet removal gh#1885 / PR #1918, input/search fill-default posture gh#1856 — see `packages/web-components/CHANGELOG.md#0850--2026-08-23`). Package-local changes are listed below.
7
+ - **`.claude-plugin/plugin.json` version bump** — moves in lockstep with package.json (the `/plugin update` cache key).
8
+ - **`.codex-plugin/` touched in this release window** (1 file(s), e.g. `.codex-plugin/plugin.json`) — carried by the entries above.
9
+
10
+ ### Fixed
11
+ - **`skills/package-release` regenerates Codex plugin manifests in Step 4 (gh#1899, PR #1917)** — `release-pack.mjs` + `cut-procedure.md` gain the post-bump `build:codex-manifests` regen so `check:codex-manifests-fresh` stays green through a cut; `a2ui-maintenance` (`mcp-pipeline-ops.md`) and `primitive-authoring` (`api-contract.md`) references refreshed in the same window.
12
+
13
+ ## [0.8.48] — 2026-08-23
14
+
15
+ ### Added
16
+ - OpenAI Codex plugin manifest (gh#1888) — `.codex-plugin/plugin.json` +
17
+ a per-skill `skills/<name>/agents/openai.yaml`, derived from
18
+ `.claude-plugin/plugin.json` via `npm run build:codex-manifests`
19
+ (`check:codex-manifests-fresh` gates freshness). Additive: the Claude Code
20
+ plugin surface is unchanged.
21
+
3
22
  ## [0.8.47] — 2026-08-22
4
23
 
5
24
  ### Maintenance
@@ -0,0 +1,12 @@
1
+ {
2
+ "displayName": "Adia UI Forge",
3
+ "shortDescription": "Maintain the adia-ui (@adia-ai) framework: primitives, A2UI pipeline, releases",
4
+ "longDescription": "Adia UI Forge is the maintainer toolkit for the adia-ui (@adia-ai) light-DOM web-component framework — author primitives and shells, run and tune the A2UI generative-UI pipeline and its corpus, review gen-UI quality, sweep app-shell QA, cut lockstep releases, and deploy the docs site. The maintainer counterpart to Adia UI Factory (the consumer/app-author toolkit).",
5
+ "category": "Engineering",
6
+ "capabilities": ["Read", "Write"],
7
+ "defaultPrompt": [
8
+ "Audit adia-ui primitives for token drift",
9
+ "Run the A2UI generation pipeline and score the gallery output"
10
+ ],
11
+ "brandColor": "#1B4D8C"
12
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@adia-ai/adia-ui-forge",
3
- "version": "0.8.47",
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.50",
4
+ "description": "Maintain the adia-ui (@adia-ai) framework itself 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",
7
7
  "a2ui",
@@ -21,6 +21,7 @@
21
21
  },
22
22
  "files": [
23
23
  ".claude-plugin",
24
+ ".codex-plugin",
24
25
  "skills",
25
26
  "agents",
26
27
  "commands",
@@ -28,7 +29,8 @@
28
29
  "scripts",
29
30
  "hooks",
30
31
  "README.md",
31
- "CHANGELOG.md"
32
+ "CHANGELOG.md",
33
+ "codex.interface.json"
32
34
  ],
33
35
  "publishConfig": {
34
36
  "access": "public",
@@ -47,6 +47,7 @@ Unmatched work defaults to pipeline-overview and re-classifies from there.
47
47
  | Tune the anti-pattern catalogue | [anti-patterns](references/anti-patterns.md) |
48
48
  | A contract can't express a content shape — decide how to extend it | [format-extension-decisions](references/format-extension-decisions.md) |
49
49
  | Surface regeneration, pending/stale rendering, the `doc`-setter bracket | [surface-lifecycle](references/surface-lifecycle.md) (ADR-0061) |
50
+ | Data-model internals — `Cell`/`Derived`, RFC-6901 pointers, `path-pointer.js` call-site migration, watch semantics | [data-model-reactivity](references/data-model-reactivity.md) (ADR-0078) |
50
51
 
51
52
  ## Contracts that gate every change
52
53
 
@@ -0,0 +1,3 @@
1
+ interface:
2
+ display_name: "A2ui Maintenance"
3
+ short_description: "Maintains the A2UI pipeline (packages/gen-ui/a2ui/): the chunk corpus, compose strategies (zettel, chunk-zettel, free-form, monolithic), retrieval, validator, calibration, evals, the a2ui MCP server."
@@ -0,0 +1,96 @@
1
+ # v1 data-model reactivity — Cell/Derived, RFC-6901 pointers, value-identity cutoff
2
+
3
+ Source of truth: [ADR-0078](../../../../../../docs/ops/adr/adr-0078-a2ui-runtime-adopts-v1-data-model.md)
4
+ (ratified 2026-08-20, gh#1762; phased plan tracked in gh#1784). Read the ADR
5
+ before touching `packages/gen-ui/a2ui`'s data-model internals, `path-pointer.js`
6
+ call sites, or `surface.js`/`renderer.js` watch semantics — this file is the
7
+ routing pointer + the shape of the adopted contract, not a restatement of the
8
+ ruling, and NOT a claim that any phase has shipped (check gh#1784's own state
9
+ before citing this as already-live behavior).
10
+
11
+ ## What's decided (direction, not yet fully built)
12
+
13
+ The in-repo A2UI runtime (`packages/gen-ui/a2ui`, the 0.9 dialect) **adopts**
14
+ the vendored `packages/genui` v1.0 data model internally — `Cell`/`Derived`
15
+ reactive primitives, RFC-6901 pointer semantics (`resolvePointer`/
16
+ `setPointer`/`deletePointer` with structural sharing), and the
17
+ one-memoized-`Derived`-per-pointer read contract — as its own per-surface
18
+ data model. This is an internal implementation swap, not a consumer
19
+ migration or a wire-grammar change: the dialect's eight message kinds, the
20
+ `{path}` binding-prop shape, `updateDataModel`, `HandlerContext.updateModel/
21
+ setModel`, `registerController/Handler/Resolver`, and the `<a2ui-root>`
22
+ element API are all unchanged (ADR-0078 Decision item 2 — falsified if any
23
+ consumer needs a code change, or if `dialect-schema.source.mjs` diffs).
24
+ Phased across future cuts, plan/LLD to follow — nothing rides in the cut
25
+ this ADR itself was ratified for (item 6).
26
+
27
+ ## The mechanism, once adopted
28
+
29
+ - **Write path:** every write notifies the root `Cell`; every cached
30
+ `Derived` recomputes on any write, but a `Derived` notifies its own
31
+ subscribers only when the recomputed value differs by `Object.is`
32
+ (`renderer/dist/data-model.d.ts`, R-R10). The perf win is suppressed
33
+ *notification*, not suppressed *evaluation* — structural-sharing writes
34
+ keep untouched subtrees identity-stable, which is what makes the
35
+ `Object.is` cutoff effective.
36
+ - **The falsifiable perf contract (ADR-0078 item 3):** a single-path write
37
+ causes `#applyProps` (or its successor) to execute ONLY for bindings whose
38
+ resolved value at their pointer actually changed. Re-application count is
39
+ the gate, not evaluation count.
40
+ - **Pointer grammar:** RFC-6901 throughout — `~0`/`~1` escaping honored, no
41
+ empty-segment forgiveness, uniform missing-path → `undefined`. One
42
+ asymmetry survives by design: `resolvePointer`'s READ path treats only
43
+ `""` as whole-document (`"/"` resolves the empty-string key, strict RFC
44
+ 6901), while `setPointer`/`deletePointer`'s WRITE/DELETE path treats
45
+ `undefined`, `""`, and `"/"` all as whole-document.
46
+ - **Watch semantics:** a subscriber at a pointer fires when the resolved
47
+ value AT that pointer changes — any writer, any write at/above/beneath the
48
+ pointer that alters it; a sibling write never fires it (host-bridge R-H1,
49
+ same identity-cutoff rule as R-R10). This supersedes `surface.js`'s
50
+ prefix-descend rule and `renderer.js`'s re-apply-all-bindings behavior.
51
+
52
+ ## What's converging, and what it changes
53
+
54
+ `path-pointer.js` (gh#1763) currently preserves three divergent legacy
55
+ walkers (`getByPath`/`setByPath`, `getPath`/`setPath`, `getModelValue`) on
56
+ purpose, as a staging step — each call site migrates to the vendored
57
+ semantics above and retires when its last call site migrates. Every
58
+ migration phase must name its own behavior deltas rather than changing
59
+ silently (ADR-0078 item 4 is falsified by an unnamed semantics change) —
60
+ known deltas already called out: `/a//b/` stops resolving forgivingly,
61
+ `/name/length` on a string stops leaking the primitive's own property,
62
+ and a2ui's own read/write asymmetry (today: `getByPath`/`getPath` treat
63
+ absent-path/`""`/`"/"` alike, but `setByPath`/`setPath` no-op on root
64
+ instead of replacing it) converges on the read/write split named above.
65
+
66
+ ## What stays fixed (don't "fix" these under this ADR)
67
+
68
+ - The surface-lifecycle contract (ADR-0061 —
69
+ [surface-lifecycle](surface-lifecycle.md)): the state machine, the
70
+ `beginSurfaceUpdate → applyTo → commitSurfaceUpdate/abortSurfaceUpdate`
71
+ host bracket, `data-a2ui-lifecycle` reflection, bubbling surface events —
72
+ all orthogonal to data-model storage/invalidation and must stay
73
+ byte-identical across adoption phases.
74
+ - The dialect/wire surface (ADR-0059's frame) and ADR-0072's wire-format
75
+ flip — both explicitly untouched by this internal swap.
76
+ - `record.js`'s bidirectional-overlap store — app-layer, outside this
77
+ package, rides a separate review track (R2), not this ADR.
78
+
79
+ ## Consumption mechanism — open, LLD decides
80
+
81
+ `@adia-ai/a2ui` is a zero-runtime-deps package (ADR-0048 posture);
82
+ `packages/genui` is a vendored, never-edited-in-place artifact (ADR-0059).
83
+ Whether the adopted primitives land via a build-time vendor-copy (with a
84
+ provenance stamp) or a workspace-internal import is NOT decided by
85
+ ADR-0078 — whichever the LLD picks must either preserve the zero-deps
86
+ posture or explicitly re-rule it. Check the LLD (once authored, per gh#1784)
87
+ before assuming either mechanism.
88
+
89
+ ## Eval-floor risk
90
+
91
+ No eval floor movement is *expected* (floors measure retrieval/composition,
92
+ not runtime rendering — floor sources are authoritative in
93
+ [eval-diagnostics](eval-diagnostics.md)), but rendered-check verify targets
94
+ and any eval path that renders through the runtime need per-phase
95
+ verification once a phase actually ships. This reference flags the risk;
96
+ each landed phase clears or reports it, not this file.
@@ -59,9 +59,13 @@ MCP server restart, re-run `compose_from_chunks` for a fresh `state_id`.
59
59
  When the engine breaks expectations, fire `report_issue` with the most recent
60
60
  `state_id` (reporter: `llm` for agent self-fire, `user` for a human request).
61
61
  The record lands in the engine-internal telemetry store — scratch data for
62
- diagnosis. Anything worth durable tracking (a recurring pattern, a fix
63
- proposal) belongs in a GitHub issue or the PR description of the fixing
64
- change.
62
+ diagnosis. **[corrected 2026-08-23, ADR-0008 amendment]** that store is
63
+ `qa/findings/issues/<issue_id>.json`
64
+ (`packages/gen-ui/engine/compose/strategies/zettel/issue-reporter.js:10,26`,
65
+ `DEFAULT_STORAGE_ROOT`) — not the original `.brain/audit-history/issues/`
66
+ path, which was retired. Anything worth durable tracking (a recurring
67
+ pattern, a fix proposal) belongs in a GitHub issue or the PR description of
68
+ the fixing change.
65
69
 
66
70
  ## Validation checks
67
71
 
@@ -13,6 +13,8 @@ user-invocable: true
13
13
 
14
14
  # demo-audit
15
15
 
16
+ > **Claude-only seat.** This skill dispatches a Claude Code subagent (the Agent tool) — under Codex, run the equivalent work inline instead (gh#1888).
17
+
16
18
  Finds the bugs the type-checker misses across the monorepo's rendered surfaces.
17
19
  Detection is script-driven; the skill owns mode routing, triage judgment, the
18
20
  auto-fix boundary, and verification. Commands run from the monorepo root,
@@ -0,0 +1,3 @@
1
+ interface:
2
+ display_name: "Demo Audit"
3
+ short_description: "Seven-mode QA sweep of the monorepo's demo/app surfaces: visual probe, app-shell QA, attr-quote typos, native-primitive leak, admin-shell composition, card anatomy, plus an aggregated token/contrast/lifecycle drift battery (`npm run dogfood:status`)."
@@ -0,0 +1,3 @@
1
+ interface:
2
+ display_name: "Gen Ui Review"
3
+ short_description: "Closed-loop Gen UI gallery quality review — per cycle: derive ideal specs, decompose the rendered canvas, score the gap, root-cause, emit fix plans until every prompt clears the exit gate."
@@ -0,0 +1,3 @@
1
+ interface:
2
+ display_name: "Llm Client Maintenance"
3
+ short_description: "Maintains @adia-ai/llm (packages/llm/core/): provider adapters (anthropic/openai/ gemini), the shared SSE parser, model registry, chat()/streamChat() facade, createAdapter() bridge."
@@ -17,6 +17,8 @@ user-invocable: true
17
17
 
18
18
  # package-release
19
19
 
20
+ > **Claude-only seat.** This skill dispatches a Claude Code subagent (the Agent tool) — under Codex, run the equivalent work inline instead (gh#1888).
21
+
20
22
  Release engineering for an @adia-ai-style lockstep monorepo: the
21
23
  `@adia-ai/*` packages on the roster (`scripts/package-paths.mjs`, the single source — 10 lockstep as of gh#1282's shim retirement) version and
22
24
  publish together (class A). Class B (independent versioning, one member —
@@ -0,0 +1,3 @@
1
+ interface:
2
+ display_name: "Package Release"
3
+ short_description: "Release engineering for the @adia-ai lockstep monorepo."
@@ -151,6 +151,8 @@ Any red → route via [`gates-catalog.md`](gates-catalog.md); fix at the source,
151
151
 
152
152
  **4d.5b. Regenerate catalog tiers + re-harvest the chunk corpus if it goes stale** (gh#1361, automated — this was a recurring manual rider before): `npm run build:catalog-tiers`, then `npm run check:chunks-fresh`; if that probe goes stale, `npm run harvest:chunks`. `tier-index.json` derives from the same post-bump catalog 4d.5 just refreshed, and the chunk harvester hashes `tier-index.json` as a harvest SOURCE — regenerating tiers without re-harvesting left `check:chunks-fresh` red on the next run, needing a manual rider commit both cuts it happened live: v0.8.39 (`72417beff`) and v0.8.40/CUT-0840-B (`d9ca8b323`, "Ran `npm run build:catalog-tiers` ... That regen staled `check:chunks-fresh` ... so re-harvested"). The re-harvest is CONDITIONAL on the freshness probe, not unconditional — a tier regen that produces a byte-identical index owes no re-harvest. `tier-index.json`, `packages/gen-ui/engine/corpus/manifest.json`, and `packages/gen-ui/engine/corpus/chunks/` all ride the release commit (Step 5 stages them).
153
153
 
154
+ **4d.6. Regenerate the Codex plugin manifests** (gh#1888, gh#1899): `node scripts/build/codex-manifests.mjs`, then `npm run check:codex-manifests-fresh` to confirm. Both plugins' `.codex-plugin/plugin.json` embed `version` from `.claude-plugin/plugin.json`, which the 4b bump just moved — same "derived artifact carries the lockstep version" class as 4d.5's genui catalog. Gate 31 runs pre-bump in Step 3 and only proves freshness against the PREVIOUS version; nothing re-ran the generator post-bump before this line existed — the v0.8.48 release PR (#1897) shipped stale manifests as a result, caught by `check:codex-manifests-fresh` in CI and fixed by hand on the release branch. `packages/plugins/*/.codex-plugin/plugin.json` and `packages/plugins/*/skills/*/agents/openai.yaml` ride the release commit (Step 5 stages them).
155
+
154
156
  **4e. Release docs + team notes** (gated, not optional): review the entry
155
157
  files the release touches (root README/CHANGELOG, per-package READMEs —
156
158
  content currency is YOUR judgment; the gate only proves presence), then
@@ -212,6 +214,7 @@ node "${CLAUDE_PLUGIN_ROOT}/skills/package-release/scripts/bump.mjs" --from X.Y.
212
214
  npm install --package-lock-only --no-audit --no-fund # 4c
213
215
  npm run check:lockstep # 4d
214
216
  node scripts/build/derive-genui-catalog.mjs # 4d.5 — catalogId carries the bumped version (gh#617)
217
+ node scripts/build/codex-manifests.mjs # 4d.6 — Codex manifest version carries the bumped version (gh#1899)
215
218
  node scripts/release/check-release.mjs --pending-version X.Y.Z --fix # 4f — AFTER the stubs exist
216
219
  node scripts/release/generate-release-notes.mjs --version X.Y.Z --write # 4e
217
220
  node scripts/release/check-release-docs.mjs --version X.Y.Z # 4e gate
@@ -131,6 +131,12 @@ export const GATE_ROSTER = [
131
131
  // inserted: gate numbers are identities in shipped release notes (see
132
132
  // gate 29's note).
133
133
  { n: 30, cmd: 'npm run check:catalog-tiers', what: 'tier-index.json vs committed catalog (L0–L4, composability law)' },
134
+ // gh#1888: the Codex-plugin manifest tree (.codex-plugin/plugin.json +
135
+ // per-skill agents/openai.yaml, both plugins) is derived from
136
+ // .claude-plugin/plugin.json — a stale copy is a real Codex-install
137
+ // hazard the same way a stale dist bundle is a real Claude-install
138
+ // hazard. Appended, not inserted — same numbering discipline as gate 30.
139
+ { n: 31, cmd: 'npm run check:codex-manifests-fresh', what: 'Codex plugin.json + openai.yaml vs .claude-plugin/plugin.json SoT' },
134
140
  ];
135
141
 
136
142
  // -- CLI ------------------------------------------------------------------
@@ -627,6 +627,29 @@ function step4PromoteAndBump(args) {
627
627
  console.log(' ✓ chunk corpus still fresh after catalog-tiers regen — no re-harvest needed');
628
628
  }
629
629
 
630
+ // Step 4d.6 — regenerate the Codex plugin manifests (gh#1888, gh#1899): both
631
+ // .codex-plugin/plugin.json's `version` and each per-skill agents/openai.yaml
632
+ // derive from .claude-plugin/plugin.json, which the bump above just moved —
633
+ // same "derived artifact embeds the lockstep version" class as 4d.5's genui
634
+ // catalog. Gate 31 (check:codex-manifests-fresh) runs pre-bump in Step 3, so
635
+ // it only proves freshness against the PREVIOUS version; nothing re-ran the
636
+ // generator after the bump until now — the release PR for v0.8.48 (#1897)
637
+ // shipped stale manifests as a result (Static checks + MCP smoke failed on
638
+ // check:codex-manifests-fresh, fixed by hand on the release branch). Step 5
639
+ // stages both plugins' .codex-plugin/plugin.json + skills/*/agents/openai.yaml.
640
+ console.log('\n Step 4d.6 — regenerate Codex plugin manifests (version embeds the lockstep bump):');
641
+ sh('node scripts/build/codex-manifests.mjs', args);
642
+ if (args.dry) {
643
+ console.log(' [dry] npm run check:codex-manifests-fresh (post-regen proof)');
644
+ } else if (!shOk('npm run check:codex-manifests-fresh')) {
645
+ console.error('\nERROR: Codex plugin manifests still stale after regeneration — codex-manifests.mjs');
646
+ console.error(' did not produce output matching check:codex-manifests-fresh\'s expectations.');
647
+ console.error(' Run both by hand to diagnose before re-running the cut.');
648
+ process.exit(1);
649
+ } else {
650
+ console.log(' ✓ Codex plugin manifests fresh after regeneration');
651
+ }
652
+
630
653
  // Step 4e — generate docs/ops/releases/vX.Y.Z.md (gh#399: neither this step nor
631
654
  // its staging into the release commit existed before — check-cut-hygiene's
632
655
  // "notes present" claim (Step 4g, below) went unverified until
@@ -747,7 +770,17 @@ function step5Commit(args) {
747
770
  // generation MCP (@adia-ai/mcp) in .mcp.json (SKILL invariant 8 —
748
771
  // bump.mjs moves the pin too).
749
772
  const files = [`${dir}/package.json`, `${dir}/CHANGELOG.md`];
750
- if (plugin) files.push(`${dir}/.claude-plugin/plugin.json`);
773
+ if (plugin) {
774
+ files.push(`${dir}/.claude-plugin/plugin.json`);
775
+ // gh#1899: Step 4d.6 regenerates both plugins' Codex manifest tree
776
+ // post-bump (version embeds the lockstep bump, same class as the
777
+ // genui catalog outputs above) — stage it here or CI catches the
778
+ // drift the way v0.8.48's release PR (#1897) did. `skills/*/
779
+ // agents/openai.yaml` is a glob: `git add` expands it via the shell,
780
+ // and the per-skill count isn't statically knowable (same shape as
781
+ // the chunk-corpus directory pathspec above).
782
+ files.push(`${dir}/.codex-plugin/plugin.json`, `${dir}/skills/*/agents/openai.yaml`);
783
+ }
751
784
  if (name === 'adia-ui-factory') files.push(`${dir}/.mcp.json`);
752
785
  return files;
753
786
  }),
@@ -1169,6 +1202,17 @@ function selftest() {
1169
1202
  // health record, or it rides untracked past the release commit
1170
1203
  // (v0.8.35/v0.8.36 both did, PR #1196 swept them by hand).
1171
1204
  'evals/health/9.9.9.json',
1205
+ // gh#1899 — Step 4 must regenerate the Codex plugin manifests post-bump
1206
+ // (the v0.8.48 release PR #1897 shipped stale ones without this step).
1207
+ 'Step 4d.6 — regenerate Codex plugin manifests',
1208
+ '[dry] node scripts/build/codex-manifests.mjs',
1209
+ // gh#1899 — Step 5's staging pathspec must carry both plugins' Codex
1210
+ // manifest tree, or it rides untracked/uncommitted past the release
1211
+ // commit the same way the genui catalog outputs did before gh#617.
1212
+ 'packages/plugins/adia-ui-forge/.codex-plugin/plugin.json',
1213
+ 'packages/plugins/adia-ui-forge/skills/*/agents/openai.yaml',
1214
+ 'packages/plugins/adia-ui-factory/.codex-plugin/plugin.json',
1215
+ 'packages/plugins/adia-ui-factory/skills/*/agents/openai.yaml',
1172
1216
  ];
1173
1217
  for (const marker of need) {
1174
1218
  if (!out.includes(marker)) {
@@ -41,6 +41,8 @@ wins any tie with this skill. Monorepo source read while authoring (yaml, CSS,
41
41
  | Convention question ("is this idiomatic?") | [code-style.md](references/code-style.md) — cite the rule, don't expand it inline |
42
42
  | Trait detail page (`site/pages/traits/<name>/`) | [trait-pages.md](references/trait-pages.md) — the ADR-0019 required-section template (traits are this skill's charter; site-docs-authoring does not own `traits/`) |
43
43
  | SVG-rendered primitive (`chart-ui`, `qr-code-ui`, `icon-ui`, or a new one) — viewBox/scaling, stroke-width, text-anchor, card-bleed clipping, hit-testing | [svg-authoring.md](references/svg-authoring.md) — NOT `chart-legend-ui`/`swatch-ui`, which are HTML/CSS despite the chart-family name (file's own §0) |
44
+ | Form-control host sizing (fill vs. hug, a 20ch-class legibility floor, `[inline]`'s sizing axis) | [form-control-sizing.md](references/form-control-sizing.md) — ADR-0077 |
45
+ | A `for=`-bound pair (`table-toolbar-ui`, `chart-legend-ui`, `tooltip-ui[follows=pointer]`, `context-menu-ui`) — id-ref resolution, the bubbling-event interaction contract | [for-attribute-event-contract.md](references/for-attribute-event-contract.md) — ADR-0079 |
44
46
 
45
47
  Full retrieval map — one line per reference file, grouped by axis:
46
48
  [references/INDEX.md](references/INDEX.md). Depth references (api-contract,
@@ -0,0 +1,3 @@
1
+ interface:
2
+ display_name: "Primitive Authoring"
3
+ short_description: "Author or modify AdiaUI framework source inside the monorepo — primitives (packages/web-components), shells/composites (packages/web-modules), yaml SoTs, demos."
@@ -19,6 +19,8 @@ file, including the depth references those entries cross-link.
19
19
  - [css-patterns.md](css-patterns.md) — how do I structure a component stylesheet: two-block `@scope`, variants vs modes, token layering?
20
20
  - [lifecycle-patterns.md](lifecycle-patterns.md) — how do I keep `connected()`/`disconnected()` symmetric for listeners, timers, observers, and popovers?
21
21
  - [svg-authoring.md](svg-authoring.md) — viewBox/coordinate scaling, stroke-width, text-anchor/dominant-baseline, card-bleed clipping, currentColor vs `var()` inside SVG markup, hit-testing — for `chart-ui`/`qr-code-ui`/`icon-ui`/any new `<svg>`-emitting primitive.
22
+ - [form-control-sizing.md](form-control-sizing.md) — does a form-control host fill its container or hug its content, and where does the legibility floor live (ADR-0077)?
23
+ - [for-attribute-event-contract.md](for-attribute-event-contract.md) — what does `for=` resolve to, and how does a `for=`-bound pair talk to each other (ADR-0079)?
22
24
 
23
25
  ## Shells & modules
24
26
 
@@ -119,6 +119,30 @@ shape — see the ADR-0063 conventions list in
119
119
 
120
120
  Source: [ADR-0074](../../../../../../docs/ops/adr/adr-0074-chart-ratio-attribute-grammar.md).
121
121
 
122
+ **[verified 2026-08-23] Failure mode — DOM-ancestry auto-detection is riskier
123
+ than container-query auto-detection.** ADR-0081 Decision 1 (`chart-ui[labels]`,
124
+ a 3-value enum: `""`/`chip`/`outside`) initially mirrored this same
125
+ auto/explicit-override shape, but auto-detected via DOM ancestry — resolving
126
+ unset `labels=""` to `chip` whenever the element sat inside a `section[bleed]`
127
+ or `card-ui[padding="none"]` ancestor — instead of a container query on the
128
+ element's own box. The 2026-08-21 amendment walked that back entirely after it
129
+ silently flipped 2 of 60 fixtures on the Charts visual-eval floor
130
+ (`comp-chart-in-card-n-*`, pre-existing full-bleed compositions), caught only
131
+ by the floor's pixel-diff gate — neither the unit-test suite nor code review
132
+ renders real CSS/layout. Amended decision: unset `labels=""` resolves to
133
+ `outside` unconditionally; `chip` mode activates only via the explicit
134
+ `labels="chip"` attribute — no ancestry detection at all. ADR-0081's Decision
135
+ 2 (a `today` marker attribute) independently rejects clock-derived
136
+ auto-detection for the same reliability reason (cites IDR-0006). Lesson for a
137
+ new auto-snap attribute of this shape: auto-detection is safe when it reads
138
+ the element's *own* rendered geometry (a container query against its own box,
139
+ as `ratio` does); it is risky when it reads *ancestor* DOM state or wall-clock
140
+ time, because neither is guaranteed stable across every composition that
141
+ happens to nest the element — verify any such default against a real
142
+ pixel-diff/visual-eval gate, not unit tests or review alone. Source:
143
+ [ADR-0081](../../../../../../docs/ops/adr/adr-0081-chart-2-0-foundations-attribute-grammar.md)
144
+ Amendment (2026-08-21).
145
+
122
146
  ## Numeric props — `null` over sentinels
123
147
 
124
148
  Indeterminate, unknown, or "not yet set" numeric state uses `null`, not `-1` or `Infinity`:
@@ -0,0 +1,62 @@
1
+ # `for=` id-ref + bubbling-event interaction contract
2
+
3
+ Source of truth: [ADR-0079](../../../../../../docs/ops/adr/adr-0079-for-attribute-id-ref-and-events-only-interaction-contract.md)
4
+ (ratified 2026-08-20, executed by gh#1780). Read the ADR before adding a new
5
+ `for=`-bound pair or touching `table-toolbar-ui`/`chart-legend-ui`/
6
+ `tooltip-ui`/`context-menu-ui` — this file is the routing pointer + the
7
+ fix-now checklist, not a restatement of the ruling.
8
+
9
+ ## The one-line rule
10
+
11
+ `for=` means id-ref, everywhere in AdiaUI — no component may give it a
12
+ different resolution contract (`context-menu-ui`'s prior CSS-selector
13
+ reading was the violation this ADR ends). The interaction contract over any
14
+ `for=` binding is bubbling `CustomEvent`s in **both** directions — never a
15
+ direct property write or method call across the binding.
16
+ `chart-legend-ui`↔`chart-ui` is the ratified model: the bound element
17
+ dispatches a bubbling event, the target listens on `document` filtered by
18
+ `[for]` matching its own id.
19
+
20
+ ## Fix-now checklist for a `for=`-bound primitive
21
+
22
+ - `for=` resolves via `getElementById` (id-ref) — never
23
+ `querySelectorAll`/a CSS-selector reading. A component needing
24
+ selector-flavored targeting names a DIFFERENT attribute (see
25
+ `context-menu-ui`'s `target-selector` below) — it never overloads `for`.
26
+ - Every write the bound pair needs to make on each other is a bubbling
27
+ `CustomEvent`, dispatched at the resolved target (or document-delegated,
28
+ whichever the existing read direction already established) — never a
29
+ direct property write (`target.prop = …`) or method call
30
+ (`target.method()`) across the binding.
31
+ - `chart-legend-ui`, `chart-ui`, and `tooltip-ui[follows=pointer]` are
32
+ already verified compliant — don't touch them to "align" with a new
33
+ pattern; the ADR names them explicitly out of scope for its own sweep.
34
+ - `table-toolbar-ui`→`table-ui`'s inbound command surface is
35
+ `toolbar-search` / `toolbar-filter-set` / `toolbar-filter-clear` /
36
+ `toolbar-columns-set` / `toolbar-paginate` — dispatched by the toolbar at
37
+ its resolved `#target`, applied by `table-ui` via the same public-API call
38
+ the direct write used to make. This is additive to `table-ui`'s contract:
39
+ any consumer may dispatch these events, not only `table-toolbar-ui`. The
40
+ existing toolbar→consumer notification events (`search`, `filter-change`,
41
+ `sort-change`, `columns-change`, `page-size-change`) are unchanged and
42
+ never reused as the inbound command channel (naming collision, rejected
43
+ alternative in the ADR).
44
+ - A component whose `for=` was CSS-selector-flavored (`context-menu-ui`'s
45
+ prior shape) renames the selector-flavored attribute to `target-selector`;
46
+ `for` survives only as a **deprecated back-compat alias** — still resolved
47
+ as a selector (never dual-purposed into id-ref sniffing — rejected in the
48
+ ADR as ambiguous), honored only when `target-selector` is unset, with a
49
+ one-shot `console.warn` pointing at the replacement. Document the alias as
50
+ deprecated in the yaml SoT, the class doc comment, and the examples.
51
+
52
+ ## What NOT to do
53
+
54
+ - Don't invent a document-level delegated-listener shape for a pair that
55
+ already resolves a concrete target reference for its read direction — a
56
+ targeted dispatch at the resolved element is simpler and still satisfies
57
+ "events, not direct writes" (rejected alternative in the ADR, re:
58
+ `table-toolbar-ui`).
59
+ - Don't dual-purpose one attribute name for two resolution contracts
60
+ (id-ref sometimes, selector sometimes) — this is the exact same-name/
61
+ different-contract collision ADR-0053's no-shadowing doctrine forbids for
62
+ global attributes, and the defect this ADR exists to end.
@@ -0,0 +1,59 @@
1
+ # Form-control sizing posture — fill by default, `[inline]` hugs
2
+
3
+ Source of truth: [ADR-0077](../../../../../../docs/ops/adr/adr-0077-form-control-sizing-posture.md)
4
+ (ratified 2026-08-19; amends [ADR-0037](../../../../../../docs/ops/adr/adr-0037-inline-display-mode-convention.md)
5
+ partial — `[inline]` semantics widen to own the sizing axis, the display-default
6
+ convention itself is unchanged). Companion SPEC:
7
+ `docs/ops/spec/spec-form-control-sizing-posture.md`. Read the ADR before
8
+ touching a form-control host's width/min-width rules — this file is the
9
+ routing pointer + the fix-now checklist, not a restatement of the ruling.
10
+
11
+ ## The one-line rule
12
+
13
+ A form-control host, absent `[inline]`, is block-level (ADR-0037, unchanged)
14
+ **and fills its container's available inline space** — in block flow via
15
+ `width: auto` (already true), in flex/grid parents via `width: 100%` on the
16
+ host (the mechanism `field-ui`/`otp-input-ui` already shipped). `[inline]`
17
+ flips BOTH axes at once: inline-level display **and** shrink-wrap/hug sizing.
18
+ No separate `hug` attribute exists or should be minted — one token, one
19
+ posture flip.
20
+
21
+ ## Where legibility floors live
22
+
23
+ A `--*-min-width: 20ch`-class floor (the gh#781/gh#1633 pattern on
24
+ `input-ui`/`select-ui`/`combobox-ui`) belongs on `:scope[inline]` only, never
25
+ on the plain `:scope`. In the fill state the container owns the width, all
26
+ the way down — no exception, no re-added floor. Two floor classes are
27
+ explicitly NOT sizing-posture floors and stay in both states: inner
28
+ `min-width: 0` flex unclampers (the ellipsis-reset machinery) and
29
+ `min-width: var(--*-height)` squareness floors (`button-ui`'s keep-square
30
+ rule). Inner *segment* floors (`time-picker-ui`'s 2ch/2.5ch segments,
31
+ `tags-input-ui`'s 8em `[data-inline-input]`) are inner mechanics, not host
32
+ posture, and also stay in both states.
33
+
34
+ ## Fix-now checklist for a form-control primitive
35
+
36
+ - Plain `:scope` (no `[inline]`): block-level, `width: auto` in block flow,
37
+ `width: 100%` in flex/grid parents. No `min-width` legibility floor here.
38
+ - `:scope[inline]`: inline-level display, shrink-wrap sizing, and — only if
39
+ the component is a floor-carrier (input/select/combobox-class) — the
40
+ `--*-min-width: 20ch`-class floor moves here.
41
+ - A component that wants to own its line but still hug has no attribute for
42
+ that state (ADR-0077 Decision item 6, accepted consequence) — tell the
43
+ consumer to use explicit sizing (`width: fit-content` or an explicit
44
+ width), don't invent a third posture token.
45
+ - `field-ui`/`fields-ui`'s `[inline]` carve-out (single-row layout meaning,
46
+ ADR-0037 §5) is retained and stays behaviorally convergent with this
47
+ decision — don't "fix" it to match the family's token meaning.
48
+ - The trip-wire gate is `scripts/release/check-display-default-convention.mjs`
49
+ — it fails a 20ch-class host floor on the plain `:scope` and fails a
50
+ missing fill mechanism in the default state, for roster components. One
51
+ gate, no second check to satisfy.
52
+
53
+ ## Roster and rollout
54
+
55
+ The exact component roster and the breaking-wave/golden-regeneration rollout
56
+ (one coordinated wave, MIGRATION GUIDE entry same cycle, deliberately
57
+ regenerated `evals/visual/` goldens — never additive-first, never shimmed)
58
+ are the companion PLAN's job (`docs/ops/plan/plan-form-control-sizing.md`),
59
+ not this reference — cite the ADR/PLAN rather than re-deriving scope here.
@@ -0,0 +1,3 @@
1
+ interface:
2
+ display_name: "Site Deployment"
3
+ short_description: "Deploys and operates the AdiaUI site + services on exe.dev VMs — pushing a `site-v*` tag through the hardened rsync --delete deploy to ui-kit.exe.xyz (dry-run delete summary reviewed before the real deploy job runs), diagnosis (\"Port 8000 unbound\", a 502, a stale/404ing build behind npm after the last lockstep cut), rolling back a broken deploy, VM provisioning, secret rotation."
@@ -16,6 +16,8 @@ user-invocable: true
16
16
 
17
17
  # site-docs-authoring
18
18
 
19
+ > **Claude-only seat.** This skill dispatches a Claude Code subagent (the Agent tool) — under Codex, run the equivalent work inline instead (gh#1888).
20
+
19
21
  Every page under `site/pages/{architecture,getting-started,guides,patterns,
20
22
  reference}/` shares one skeleton: `<header><h1>` + a deck `<p>`, then numbered
21
23
  `<section data-section data-property="...">` blocks, each opening
@@ -0,0 +1,3 @@
1
+ interface:
2
+ display_name: "Site Docs Authoring"
3
+ short_description: "Review or author pages under site/pages/{architecture,getting-started, guides,patterns,reference}/ — the docs site (count the pages on disk; it grows)."
@@ -0,0 +1,3 @@
1
+ interface:
2
+ display_name: "Ssr Compatibility"
3
+ short_description: "Answers why an AdiaUI component crashes, drops content, renders wrong, or mutates a byte-identical subtree under SSR (linkedom/Astro) — the known failure shapes, what's fixed vs open, how to prove a fix under the linkedom shim gate."