@adia-ai/adia-ui-forge 0.8.62 → 0.8.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +2 -2
- package/.codex-plugin/plugin.json +3 -3
- package/CHANGELOG.md +300 -275
- package/README.md +54 -18
- package/__init__.py +8 -8
- package/agents/a2ui-maintenance-agent.corpus.json +7 -7
- package/agents/a2ui-maintenance-agent.md +6 -6
- package/agents/a2ui-planner-agent.md +11 -11
- package/agents/demo-audit-agent.corpus.json +4 -4
- package/agents/demo-audit-agent.md +8 -9
- package/agents/framework-checker.md +10 -11
- package/agents/framework-planner-agent.md +9 -10
- package/agents/gen-ui-review-agent.corpus.json +4 -4
- package/agents/gen-ui-review-agent.md +8 -8
- package/agents/package-release-agent.corpus.json +4 -4
- package/agents/package-release-agent.md +9 -10
- package/agents/primitive-authoring-agent.corpus.json +1 -1
- package/agents/primitive-authoring-agent.md +5 -5
- package/agents/routing-corpus.json +46 -46
- package/codex.interface.json +1 -1
- package/commands/gen-ui-review.md +1 -1
- package/commands/package-release.md +2 -2
- package/package.json +1 -1
- package/plugin.yaml +2 -2
- package/prompts/gen-ui-review.md +1 -1
- package/prompts/package-release.md +2 -2
- package/references/contracts/a2ui-mcp-surface.md +7 -7
- package/references/contracts/migration-guide-format.md +6 -7
- package/references/shared/content-trust.md +3 -5
- package/skills/a2ui-maintenance/SKILL.md +13 -16
- package/skills/a2ui-maintenance/evals/evals.json +2 -2
- package/skills/a2ui-maintenance/evals/routing-corpus.json +1 -1
- package/skills/a2ui-maintenance/references/anti-patterns.md +10 -10
- package/skills/a2ui-maintenance/references/chunk-authoring.md +11 -12
- package/skills/a2ui-maintenance/references/corpus-discipline.md +13 -14
- package/skills/a2ui-maintenance/references/data-model-reactivity.md +22 -25
- package/skills/a2ui-maintenance/references/eval-diagnostics.md +21 -21
- package/skills/a2ui-maintenance/references/format-extension-decisions.md +12 -13
- package/skills/a2ui-maintenance/references/leverage-rules.md +6 -6
- package/skills/a2ui-maintenance/references/mcp-pipeline-ops.md +9 -10
- package/skills/a2ui-maintenance/references/mcp-tool-reference.md +11 -12
- package/skills/a2ui-maintenance/references/pipeline-overview.md +33 -38
- package/skills/a2ui-maintenance/references/semantic-fail-lifting.md +13 -14
- package/skills/a2ui-maintenance/references/strategy-engines.md +14 -16
- package/skills/a2ui-maintenance/references/surface-lifecycle.md +10 -11
- package/skills/a2ui-maintenance/references/zettel-calibration.md +14 -16
- package/skills/component-md-authoring/SKILL.md +20 -21
- package/skills/component-md-authoring/agents/openai.yaml +1 -1
- package/skills/cross-harness-authoring-standards/SKILL.md +19 -21
- package/skills/cross-harness-authoring-standards/agents/openai.yaml +1 -1
- package/skills/cross-harness-compatibility-standards/SKILL.md +34 -35
- package/skills/cross-harness-compatibility-standards/agents/openai.yaml +1 -1
- package/skills/demo-audit/SKILL.md +38 -38
- package/skills/demo-audit/evals/routing-corpus.json +1 -1
- package/skills/demo-audit/references/admin-shell-anatomy.md +21 -25
- package/skills/demo-audit/references/app-shell-pitfalls.md +11 -13
- package/skills/demo-audit/references/auto-fix-allowlist.md +3 -3
- package/skills/demo-audit/references/card-anatomy-sweep.md +10 -11
- package/skills/demo-audit/references/chat-shell-anatomy.md +25 -26
- package/skills/demo-audit/references/editor-shell-anatomy.md +25 -28
- package/skills/demo-audit/references/html-attr-sweep.md +12 -13
- package/skills/demo-audit/references/mode7-status-battery.md +4 -4
- package/skills/demo-audit/references/native-leak-annotations.md +8 -8
- package/skills/demo-audit/references/output-contract-worked-example.md +8 -8
- package/skills/demo-audit/references/probe-discipline-and-escalation.md +2 -2
- package/skills/demo-audit/references/visual-probe-triage.md +21 -23
- package/skills/gen-ui-review/SKILL.md +27 -27
- package/skills/gen-ui-review/agents/openai.yaml +1 -1
- package/skills/gen-ui-review/evals/routing-corpus.json +1 -1
- package/skills/gen-ui-review/references/corpus-html-patterns.md +28 -29
- package/skills/gen-ui-review/references/exit-gate-mechanics.md +5 -5
- package/skills/gen-ui-review/references/lookup-maintenance.md +2 -2
- package/skills/gen-ui-review/references/loop-protocol.md +25 -25
- package/skills/gen-ui-review/references/rubric-cosmetic.md +10 -10
- package/skills/gen-ui-review/references/rubric-decompose.md +15 -16
- package/skills/gen-ui-review/references/rubric-score.md +23 -24
- package/skills/gen-ui-review/references/scorecard-worked-examples.md +12 -12
- package/skills/gen-ui-review/references/scores.schema.json +2 -2
- package/skills/llm-client-maintenance/SKILL.md +12 -12
- package/skills/llm-client-maintenance/evals/routing-corpus.json +1 -1
- package/skills/llm-client-maintenance/references/adapter-contract.md +27 -27
- package/skills/llm-client-maintenance/references/add-a-provider.md +25 -25
- package/skills/llm-client-maintenance/references/bridge-facade.md +31 -31
- package/skills/llm-client-maintenance/references/browser-proxy-boundary.md +17 -17
- package/skills/llm-client-maintenance/references/model-registry.md +14 -14
- package/skills/llm-client-maintenance/references/streaming-sse.md +21 -21
- package/skills/package-release/SKILL.md +21 -23
- package/skills/package-release/evals/evals.json +2 -2
- package/skills/package-release/evals/routing-corpus.json +2 -2
- package/skills/package-release/references/authorization-model.md +6 -8
- package/skills/package-release/references/changelog-discipline.md +25 -27
- package/skills/package-release/references/cut-procedure.md +129 -136
- package/skills/package-release/references/gates-catalog.md +42 -43
- package/skills/package-release/references/independent-package-release.md +14 -15
- package/skills/package-release/references/invariants-detail.md +9 -9
- package/skills/package-release/references/mechanization.md +11 -12
- package/skills/package-release/references/migration-guide-authoring.md +20 -20
- package/skills/package-release/references/notes-authoring.md +20 -20
- package/skills/package-release/references/recovery-paths.md +28 -28
- package/skills/primitive-authoring/SKILL.md +19 -19
- package/skills/primitive-authoring/agents/openai.yaml +1 -1
- package/skills/primitive-authoring/evals/evals.json +2 -2
- package/skills/primitive-authoring/evals/routing-corpus.json +2 -2
- package/skills/primitive-authoring/references/INDEX.md +22 -22
- package/skills/primitive-authoring/references/anti-patterns.md +76 -77
- package/skills/primitive-authoring/references/api-contract.md +63 -65
- package/skills/primitive-authoring/references/authoring-cycle.md +47 -50
- package/skills/primitive-authoring/references/canonical-pattern-index.md +118 -118
- package/skills/primitive-authoring/references/code-style.md +50 -52
- package/skills/primitive-authoring/references/common-gotchas.md +23 -23
- package/skills/primitive-authoring/references/composite-demo-protocol.md +42 -45
- package/skills/primitive-authoring/references/css-patterns.md +97 -97
- package/skills/primitive-authoring/references/for-attribute-event-contract.md +12 -12
- package/skills/primitive-authoring/references/form-control-sizing.md +16 -18
- package/skills/primitive-authoring/references/lifecycle-patterns.md +42 -42
- package/skills/primitive-authoring/references/llm-bridge.md +21 -21
- package/skills/primitive-authoring/references/module-promotion.md +51 -51
- package/skills/primitive-authoring/references/primitive-audit.md +16 -16
- package/skills/primitive-authoring/references/shell-patterns.md +81 -81
- package/skills/primitive-authoring/references/svg-authoring.md +62 -66
- package/skills/primitive-authoring/references/token-contract.md +45 -49
- package/skills/primitive-authoring/references/trait-pages.md +8 -8
- package/skills/primitive-authoring/references/worked-example.md +39 -39
- package/skills/primitive-authoring/references/yaml-contract.md +139 -143
- package/skills/site-deployment/SKILL.md +25 -26
- package/skills/site-deployment/agents/openai.yaml +1 -1
- package/skills/site-deployment/evals/routing-corpus.json +1 -1
- package/skills/site-deployment/references/deploy-playbooks.md +51 -53
- package/skills/site-docs-authoring/SKILL.md +14 -14
- package/skills/site-docs-authoring/agents/openai.yaml +1 -1
- package/skills/site-docs-authoring/evals/evals.json +1 -1
- package/skills/site-docs-authoring/evals/routing-corpus.json +1 -1
- package/skills/site-docs-authoring/intent.md +18 -18
- package/skills/ssr-compatibility/SKILL.md +24 -25
- package/skills/ssr-compatibility/agents/openai.yaml +1 -1
- package/skills/ssr-compatibility/evals/evals.json +1 -1
- package/skills/ssr-compatibility/evals/routing-corpus.json +1 -1
- package/skills/ssr-compatibility/references/consumer-workarounds.md +22 -23
- package/skills/ssr-compatibility/references/failure-shapes.md +84 -91
- package/skills/ssr-compatibility/references/guard-patterns.md +54 -58
- package/skills/ssr-compatibility/references/status-ledger.md +17 -17
- package/skills/ssr-compatibility/references/test-without-linkedom.md +26 -27
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# intent
|
|
1
|
+
# intent, site-docs-authoring
|
|
2
2
|
status: shipped
|
|
3
3
|
species: procedural
|
|
4
4
|
dials: { disable-model-invocation: false, user-invocable: true }
|
|
@@ -10,7 +10,7 @@ plan (`.claude/plans/enchanted-singing-globe.md`, "Site docs review +
|
|
|
10
10
|
authoring method") and this session's own research (3 parallel Explore
|
|
11
11
|
agents surveying `site/pages/`'s structure, a color-contrast root-cause
|
|
12
12
|
investigation, and a review of existing tooling) rather than a live
|
|
13
|
-
turn-by-turn interview
|
|
13
|
+
turn-by-turn interview, the operator confirmed the plan, including
|
|
14
14
|
"doc + a dedicated skill" as the Phase 4 method depth, before this
|
|
15
15
|
skill was forged. Slots below are answered from that record, not
|
|
16
16
|
fabricated dialogue.
|
|
@@ -23,22 +23,22 @@ should:
|
|
|
23
23
|
- "author a new page under site/pages/getting-started"
|
|
24
24
|
- "is this site page consistent with our conventions"
|
|
25
25
|
should_not:
|
|
26
|
-
- "review this component demo gallery" (packages/web-components/components/*/*.examples.html
|
|
27
|
-
- "fix this gen-ui training exemplar page" (site/pages/examples/**, site/pages/gen-ui
|
|
26
|
+
- "review this component demo gallery" (packages/web-components/components/*/*.examples.html, primitive-authoring)
|
|
27
|
+
- "fix this gen-ui training exemplar page" (site/pages/examples/**, site/pages/gen-ui/**, composition-and-examples.md's no-style-block rule + a2ui-maintenance)
|
|
28
28
|
|
|
29
29
|
## delta
|
|
30
30
|
Without this skill, Claude (or a human author) reaches for whatever
|
|
31
31
|
looks locally plausible on a `site/pages/*.html` page and repeats the
|
|
32
32
|
defect classes this session found and fixed: a fabricated `data-*`
|
|
33
33
|
attribute standing in for a real primitive (16 of 34 pages had
|
|
34
|
-
`data-alert="warning|info"` with ZERO matching CSS anywhere
|
|
34
|
+
`data-alert="warning|info"` with ZERO matching CSS anywhere, dead
|
|
35
35
|
markup that silently renders as plain paragraphs), a hand-rolled
|
|
36
36
|
`<style>` block duplicating an existing shared utility (4 pages
|
|
37
37
|
independently reinvented the same "tame this admin-shell demo" CSS),
|
|
38
38
|
and a background token picked for its "feels dark and subtle" name
|
|
39
39
|
rather than its actual measured contrast (inline `<code>` used
|
|
40
40
|
`--a-canvas-well`, hand-measured at ~1.1:1 against
|
|
41
|
-
the page background
|
|
41
|
+
the page background, WCAG 2.2 SC 1.4.11 wants ≥3:1). All three are
|
|
42
42
|
now fixed at the shared-CSS/token level (cascades to all 34 pages),
|
|
43
43
|
but a NEW page authored without this skill's guidance would
|
|
44
44
|
re-introduce the same classes on page 35. Deleted after a month: the
|
|
@@ -49,24 +49,24 @@ before they start typing.
|
|
|
49
49
|
|
|
50
50
|
## fences
|
|
51
51
|
- NOT for `packages/web-components/components/*/*.examples.html` component demo pages (primitive-authoring)
|
|
52
|
-
- NOT for `site/pages/examples/**`, `site/pages/gen-ui/**`, `packages/gen-ui/a2ui/corpus/exemplars
|
|
52
|
+
- NOT for `site/pages/examples/**`, `site/pages/gen-ui/**`, `packages/gen-ui/a2ui/corpus/exemplars/**`, pure primitive-composition training-harvest surfaces with their own no-style-block rule (`composition-and-examples.md`, a2ui-maintenance)
|
|
53
53
|
- NOT for the A2UI generation pipeline itself, chunk corpus, or MCP tools (a2ui-maintenance)
|
|
54
54
|
|
|
55
55
|
## assertions
|
|
56
|
-
1. A new callout block the skill produces uses `<alert-ui variant="...">` with a `[slot="content"]` wrapper for rich text
|
|
57
|
-
2. A new tamed-demo page the skill produces adds `class="demo-frame"` plus only a page-local `--demo-frame-height` override
|
|
56
|
+
1. A new callout block the skill produces uses `<alert-ui variant="...">` with a `[slot="content"]` wrapper for rich text, never a bare `data-*` attribute with no matching CSS.
|
|
57
|
+
2. A new tamed-demo page the skill produces adds `class="demo-frame"` plus only a page-local `--demo-frame-height` override, it does not restate `position`/`border`/`overflow`/`.demo-body` padding.
|
|
58
58
|
3. When asked to review an existing page, the skill's output names the specific rule from `site-pages-authoring.md` a defect violates (not just "this looks off").
|
|
59
59
|
4. The skill's own description correctly declines to fire on a component `.examples.html` demo or a `site/pages/examples/**` training page (see `should_not` above) and instead names the owning sibling skill.
|
|
60
60
|
|
|
61
61
|
## gates
|
|
62
|
-
P0 route: PASS
|
|
63
|
-
P1 intent: PASS
|
|
64
|
-
P2 evals: PASS
|
|
65
|
-
P3 draft: PASS
|
|
66
|
-
P4 language: PASS
|
|
67
|
-
P5 validate: PASS
|
|
62
|
+
P0 route: PASS, 2026-07-14, knowledge/procedure needed on demand (author or review a site/pages doc), not mechanically checkable (hook), not always-true-every-turn (entry file), no tool-wall/parallelism need (agent). Skill.
|
|
63
|
+
P1 intent: PASS, 2026-07-14, slots filled from the approved plan + this session's research; operator confirmed the plan's Phase 4 scope (doc + dedicated skill) via AskUserQuestion before forging began.
|
|
64
|
+
P2 evals: PASS, 2026-07-14, see evals/routing-corpus.json (trigger cases, matching this repo's primitive-authoring sibling's own eval-file convention) and assertions above (behavioral). No literal fresh-session baseline captured (this is a same-session, plan-driven forge, not an interactive intent interview), the delta section above records the concrete "without this skill" failure mode from direct evidence (the 3 defect classes this session found and fixed) in place of a baseline transcript.
|
|
65
|
+
P3 draft: PASS, 2026-07-14, SKILL.md + evals/routing-corpus.json exist; both dials explicit; body 61 lines, well under the 500-line budget.
|
|
66
|
+
P4 language: PASS, 2026-07-14, self-audited against the 5 instantiation checks: task-shape rows commit to concrete actions (not descriptions); ~3 hard-gate ceiling held (never restate demo-frame properties, never a bare data-* callout, don't reach for a raw ramp step without color-verify); numeric anchors present (>=3:1, 34-page, 4 rules); contracts (task-shape table) precede the verify-steps tail; the labeled good/bad alert-ui pair lives in the referenced convention doc rather than duplicated here (reference, never restate).
|
|
67
|
+
P5 validate: PASS, 2026-07-14, skill_lint.py clean; skill-auditor FLOOR audit verdict PASS (report at evals/audit-report.md), 3 minor non-blocking findings, all fixed same-change (phantom fence trimmed to reference composition-and-examples.md by name rather than specific paths; 2 negative imperatives demoted to positive form; intent.md's routing-corpus.json citation corrected). No fence-reciprocity step run against primitive-authoring's own evals, primitive-authoring's corpus already covers "primitive authoring" as should_route_to_author:true, which is the correct answer for those phrases; no reciprocal edit needed there.
|
|
68
68
|
|
|
69
69
|
## rulings
|
|
70
|
-
- Accepted with note: no literal fresh-session baseline transcript (P2)
|
|
71
|
-
- Accepted with note: convention doc lives at `.claude/docs/conventions/site-pages-authoring.md`, not inside this skill's own `references
|
|
72
|
-
- Post-ship correction (same session, before task close): the skill's own Rule-2 example used `<span slot="content"
|
|
70
|
+
- Accepted with note: no literal fresh-session baseline transcript (P2), this forge ran from an already-approved plan's research rather than a live interview; the delta section's direct evidence substitutes. Not re-litigated.
|
|
71
|
+
- Accepted with note: convention doc lives at `.claude/docs/conventions/site-pages-authoring.md`, not inside this skill's own `references/`, deliberate, to avoid a drift pair with the doc that's also linked from `document-routing.md`.
|
|
72
|
+
- Post-ship correction (same session, before task close): the skill's own Rule-2 example used `<span slot="content">`, a real bug, not just a style choice. `scripts/build/lib/docs-transpiler.mjs`'s `PROSE_CONTAINERS` only recognizes `p`/`div`/`ul`/`ol`; `<span>` fell to a different decomposition path that silently reordered mixed inline content (a leading `<strong>` rendered AFTER the surrounding text, bold dropped) once the compiled `site-a2ui/pages/*.json` regenerated, invisible to schema validation (`valid:true`) and to a raw-HTML read, only caught by a live-browser check. Fixed in SKILL.md, the convention doc, and all 16 already-migrated `site/pages/*.html` files (`<span>` → `<div>`). Added "visually verify" as a non-optional Verify step for this content shape.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: ssr-compatibility
|
|
3
3
|
description: >-
|
|
4
4
|
Answers why an AdiaUI component crashes, drops content, renders wrong, or
|
|
5
|
-
mutates a byte-identical subtree under SSR (linkedom/Astro)
|
|
5
|
+
mutates a byte-identical subtree under SSR (linkedom/Astro), the known
|
|
6
6
|
failure shapes, what's fixed vs open, how to prove a fix under the
|
|
7
7
|
linkedom shim gate. Use for "does this work under SSR", why a component
|
|
8
8
|
crashes on attachInternals/ResizeObserver/adoptedStyleSheets/matchMedia/
|
|
@@ -19,25 +19,25 @@ disable-model-invocation: false
|
|
|
19
19
|
user-invocable: false
|
|
20
20
|
---
|
|
21
21
|
|
|
22
|
-
# ssr-compatibility
|
|
22
|
+
# ssr-compatibility, does it work under SSR, and why not if it doesn't
|
|
23
23
|
|
|
24
24
|
Two real consumers (adiav2's `admin-portal-fe` and `factory-dashboard`) server-render
|
|
25
25
|
AdiaUI's light-DOM components via Astro 5 + `custom-elements-ssr`, which runs on
|
|
26
|
-
linkedom
|
|
26
|
+
linkedom, a DOM shim with no layout engine and missing browser APIs the framework's
|
|
27
27
|
base class assumes exist. Every SSR bug that's surfaced maps onto one of six root-cause
|
|
28
28
|
shapes; misclassifying a new report against the wrong shape sends the investigation
|
|
29
29
|
to the wrong fix (or worse, invents a redundant one). This pack answers "which shape is
|
|
30
|
-
this" and "what's the state of each shape's fix"
|
|
30
|
+
this" and "what's the state of each shape's fix", it never carries the fix itself.
|
|
31
31
|
|
|
32
32
|
## The shapes, in one line each
|
|
33
33
|
|
|
34
34
|
1. **A browser-only API is called unconditionally → crash** (`attachInternals`, Observers, `adoptedStyleSheets`). **Fixed** (gh#285).
|
|
35
|
-
2. **`connectedCallback` destructively re-stamps existing DOM → silent content loss.** ORIGINAL diagnosis, narrowed to a static audit 2026-07-17 (gh#284)
|
|
35
|
+
2. **`connectedCallback` destructively re-stamps existing DOM → silent content loss.** ORIGINAL diagnosis, narrowed to a static audit 2026-07-17 (gh#284), doesn't currently expose against any shipped component.
|
|
36
36
|
2b. **Custom-element upgrade doesn't replay `attributeChangedCallback` for pre-existing attributes → reflected properties stuck at class default.** The REAL mechanism behind gh#284's symptom. **Fixed 2026-07-18** (PR #309).
|
|
37
37
|
3. **A connect-time layout measurement is treated as confirmed, not unknown.** **Fixed for one component** (gh#286); the general pattern is unswept.
|
|
38
|
-
4. **Property-only components can't seed initial state from SSR HTML** (gh#288)
|
|
39
|
-
5. **A custom `render()`/`connected()` unconditionally rebuilds a subtree that already matches
|
|
40
|
-
6. **The conditional-inject class** (`querySelector`-guard-before-`innerHTML`, `search-ui`/`pagination-ui`)
|
|
38
|
+
4. **Property-only components can't seed initial state from SSR HTML** (gh#288), a feature gap, **CLOSED 2026-07-18** (table-ui's `data="[…]"` attribute).
|
|
39
|
+
5. **A custom `render()`/`connected()` unconditionally rebuilds a subtree that already matches**, no value-diff, no adopt-existing-DOM path, so a byte-identical server-rendered subtree gets torn down at upgrade. **Implemented for table-ui in open PR #1756** (gh#1678), pending merge, not yet fixed/shipped; not swept framework-wide (no static audit for it).
|
|
40
|
+
6. **The conditional-inject class** (`querySelector`-guard-before-`innerHTML`, `search-ui`/`pagination-ui`), decision recorded: SSR-safe when the guard target is structurally specific; post-adopt attribute writes still need shape 5's idempotent-write guard, **not yet applied** to either component (gh#1678's follow-up).
|
|
41
41
|
|
|
42
42
|
Full symptom → root-cause → status detail, cited to the actual shipped/open
|
|
43
43
|
code: [failure-shapes.md](references/failure-shapes.md).
|
|
@@ -46,15 +46,15 @@ code: [failure-shapes.md](references/failure-shapes.md).
|
|
|
46
46
|
|
|
47
47
|
| Ask | Answer from |
|
|
48
48
|
| --- | --- |
|
|
49
|
-
| "why does `<text-ui>`/`<avatar-ui>`/a container lose its content under SSR" | [`failure-shapes.md`](references/failure-shapes.md) §2
|
|
50
|
-
| "why does this crash / throw at import, construction or connect under SSR" | [`failure-shapes.md`](references/failure-shapes.md) §1
|
|
51
|
-
| "is this connect-time `getBoundingClientRect()`/measurement read safe" | [`failure-shapes.md`](references/failure-shapes.md) §3 + [`guard-patterns.md`](references/guard-patterns.md) §3
|
|
52
|
-
| "what's fixed vs still open for SSR support" | [`status-ledger.md`](references/status-ledger.md)
|
|
53
|
-
| "how do I test / prove an SSR gap or fix" | [`test-without-linkedom.md`](references/test-without-linkedom.md)
|
|
49
|
+
| "why does `<text-ui>`/`<avatar-ui>`/a container lose its content under SSR" | [`failure-shapes.md`](references/failure-shapes.md) §2, shape 2, NARROWED (doesn't currently reproduce against any shipped component; see the survey before assuming a new report fits this shape) |
|
|
50
|
+
| "why does this crash / throw at import, construction or connect under SSR" | [`failure-shapes.md`](references/failure-shapes.md) §1, shape 1, FIXED twice (gh#285, gh#1430/#1436) and now GATED by `scripts/dev/ssr-linkedom-smoke.mjs`; the exact guard shape to copy for a NEW instance is [`guard-patterns.md`](references/guard-patterns.md) §1, feature-detect the API, never `typeof window` |
|
|
51
|
+
| "is this connect-time `getBoundingClientRect()`/measurement read safe" | [`failure-shapes.md`](references/failure-shapes.md) §3 + [`guard-patterns.md`](references/guard-patterns.md) §3, the fixed component's exact shape, and the "unknown ≠ confirmed" principle to apply elsewhere |
|
|
52
|
+
| "what's fixed vs still open for SSR support" | [`status-ledger.md`](references/status-ledger.md), re-verify against `gh issue view` before trusting it, it drifts |
|
|
53
|
+
| "how do I test / prove an SSR gap or fix" | [`test-without-linkedom.md`](references/test-without-linkedom.md), run the linkedom shim gate first (`node scripts/dev/ssr-linkedom-smoke.mjs`, the consumer's exact global surface), then the unit-level delete/try/finally pattern and what it does NOT prove |
|
|
54
54
|
| "what's the consumer's current workaround, and can they drop it yet" | [`consumer-workarounds.md`](references/consumer-workarounds.md) |
|
|
55
|
-
| "table/chart/select renders empty in the SSR response" | [`failure-shapes.md`](references/failure-shapes.md) §4
|
|
56
|
-
| "a byte-identical SSR subtree gets rebuilt/mutated at upgrade
|
|
57
|
-
| "is this querySelector-guard-before-innerHTML component (search-ui/pagination-ui shape) SSR-safe" | [`failure-shapes.md`](references/failure-shapes.md) §6
|
|
55
|
+
| "table/chart/select renders empty in the SSR response" | [`failure-shapes.md`](references/failure-shapes.md) §4, shape 4, CLOSED (table-ui's `data="[…]"` attribute); check whether the reporting component is registered server-side first if it still reproduces |
|
|
56
|
+
| "a byte-identical SSR subtree gets rebuilt/mutated at upgrade, role/tabindex/cells added that weren't in the SSR HTML" | [`failure-shapes.md`](references/failure-shapes.md) §5, shape 5, implemented for table-ui in open PR #1756 (gh#1678), pending merge; the adopt-or-diff pattern to copy for a NEW instance is [`guard-patterns.md`](references/guard-patterns.md) §4, `Node.isEqualNode()` for a positional child, a seeded keyed-reconcile map for a flat list, `setAttrIfChanged()` for a plain attribute write, and §4.1 for why a renderer-owned candidate (one that can attach a listener) must never be adopted on structural equality alone |
|
|
57
|
+
| "is this querySelector-guard-before-innerHTML component (search-ui/pagination-ui shape) SSR-safe" | [`failure-shapes.md`](references/failure-shapes.md) §6, decision recorded: yes, when the guard target is structurally specific; post-adopt attribute writes are a separate, NOT-yet-closed gap (same file, same section) |
|
|
58
58
|
|
|
59
59
|
## Deviation doctrine
|
|
60
60
|
|
|
@@ -62,29 +62,29 @@ Every fix pattern this pack cites ([guard-patterns.md](references/guard-patterns
|
|
|
62
62
|
carries the reasoning for why it looks the way it does (e.g. the no-op
|
|
63
63
|
`ElementInternals` shim exists because `undefined` would relocate the crash,
|
|
64
64
|
not remove it). If a new case doesn't fit an existing pattern's reasoning,
|
|
65
|
-
that's a signal to design a new pattern
|
|
65
|
+
that's a signal to design a new pattern, route through `primitive-authoring`,
|
|
66
66
|
don't force-fit the nearest existing shape.
|
|
67
67
|
|
|
68
68
|
## Boundaries
|
|
69
69
|
|
|
70
|
-
- **Implementing any fix
|
|
70
|
+
- **Implementing any fix, new or matching an existing pattern.** Route to
|
|
71
71
|
`primitive-authoring`. This pack orients and cites; it never edits
|
|
72
72
|
`packages/web-components/core/` or any component source.
|
|
73
73
|
- **Consumer-side SSR/hydration host wiring** (an app's own Astro/Next config, which
|
|
74
74
|
rendering mode to pick, how to structure the hydration boundary). Route to
|
|
75
|
-
`host-wiring` (adia-ui-factory plugin)
|
|
75
|
+
`host-wiring` (adia-ui-factory plugin), this pack answers whether the FRAMEWORK's own
|
|
76
76
|
components are SSR-safe, not how a consumer app should be structured around them.
|
|
77
77
|
- **A2UI runtime/generation-pipeline SSR concerns** (if any surface later). Route to
|
|
78
|
-
`a2ui-maintenance
|
|
78
|
+
`a2ui-maintenance`: this pack is scoped to `UIElement`'s own lifecycle and the
|
|
79
79
|
component/trait/module layer, not the generative pipeline.
|
|
80
80
|
- **Not a general web-components-SSR tutorial.** Every claim here is cited to this
|
|
81
|
-
specific framework's actual code, issues, and PRs
|
|
81
|
+
specific framework's actual code, issues, and PRs, general SSR/custom-elements
|
|
82
82
|
theory that isn't grounded in this repo's own history doesn't belong in this pack.
|
|
83
83
|
|
|
84
|
-
## Worked example
|
|
84
|
+
## Worked example, the answer contract
|
|
85
85
|
|
|
86
86
|
A "content vanished" report can match shape 2's symptom while shape 2
|
|
87
|
-
itself no longer applies (it was narrowed 2026-07-17)
|
|
87
|
+
itself no longer applies (it was narrowed 2026-07-17), the general lesson
|
|
88
88
|
(grep the component's `static template` before answering "known issue,
|
|
89
89
|
shape 2") plus a full worked ask/answer are in
|
|
90
90
|
[failure-shapes.md](references/failure-shapes.md) §2's own Worked example.
|
|
@@ -92,7 +92,6 @@ shape 2") plus a full worked ask/answer are in
|
|
|
92
92
|
## Corpus of record
|
|
93
93
|
|
|
94
94
|
Routing-eval corpus: [`evals/routing-corpus.json`](evals/routing-corpus.json).
|
|
95
|
-
This pack is hand-authored from verified session work (not a research-wave corpus)
|
|
96
|
-
re-sync it per [`status-ledger.md`](references/status-ledger.md)'s own instructions
|
|
95
|
+
This pack is hand-authored from verified session work (not a research-wave corpus), re-sync it per [`status-ledger.md`](references/status-ledger.md)'s own instructions
|
|
97
96
|
whenever an issue referenced here changes state, rather than letting the ledger and
|
|
98
97
|
reality drift apart silently.
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
interface:
|
|
2
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)
|
|
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."
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
{ "id": "t04", "prompt": "table-ui and chart-ui always render empty in our server-rendered HTML even though the data is set", "expect": "trigger" },
|
|
9
9
|
{ "id": "t05", "prompt": "Is it safe to call getBoundingClientRect() synchronously in connectedCallback?", "expect": "trigger" },
|
|
10
10
|
{ "id": "t06", "prompt": "document.adoptedStyleSheets is undefined and our component library crashes on import under SSR", "expect": "trigger" },
|
|
11
|
-
{ "id": "t07", "prompt": "What's the actual root cause of the SSR content-loss bug
|
|
11
|
+
{ "id": "t07", "prompt": "What's the actual root cause of the SSR content-loss bug, container CEs losing their nested children?", "expect": "trigger" },
|
|
12
12
|
{ "id": "t08", "prompt": "Can our app finally delete the 110-line browser-API SSR shim now that 0.8.5 is out?", "expect": "trigger" },
|
|
13
13
|
{ "id": "n01", "prompt": "Add hydration-aware stamping so connectedCallback stops overwriting existing children", "expect": "no-trigger", "owner": "primitive-authoring" },
|
|
14
14
|
{ "id": "n02", "prompt": "Set up Astro's rendering mode and hydration boundaries for our admin app", "expect": "no-trigger", "owner": "host-wiring" },
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"version": "2.1.0",
|
|
5
5
|
"purpose": "Routing-eval corpus for ssr-compatibility. Each phrase declares the skill (expected), a forbidden skill (expected_not, for phrases the source data only ever asserted as \"not this skill\"), or neither. Scored by scripts/skills/run-skill-evals.mjs (TF-IDF token overlap over per-skill description+triggers).",
|
|
6
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
|
-
"scope": "ssr-compatibility routing
|
|
7
|
+
"scope": "ssr-compatibility routing, does this phrase activate ssr-compatibility?",
|
|
8
8
|
"phrases": [
|
|
9
9
|
{
|
|
10
10
|
"id": "ssr-compatibility-pos-01",
|
|
@@ -1,89 +1,88 @@
|
|
|
1
|
-
# The consumer's current workarounds
|
|
1
|
+
# The consumer's current workarounds, what they look like, why they're fragile
|
|
2
2
|
|
|
3
|
-
Two real consumers
|
|
3
|
+
Two real consumers, adiav2's `admin-portal-fe` and `factory-dashboard`, SSR AdiaUI
|
|
4
4
|
via Astro 5 + `custom-elements-ssr` (linkedom). Each open issue names a workaround
|
|
5
5
|
they currently maintain in their OWN app code (not in this framework). Knowing the
|
|
6
|
-
shape of each matters for two reasons: (1) it tells you what "done" looks like
|
|
6
|
+
shape of each matters for two reasons: (1) it tells you what "done" looks like, the
|
|
7
7
|
workaround should become deletable once the underlying gh issue closes; (2) it's the
|
|
8
8
|
concrete evidence for WHY each open issue matters, beyond the abstract description.
|
|
9
9
|
|
|
10
|
-
## The ~110-line browser-API shim (gh#285
|
|
10
|
+
## The ~110-line browser-API shim (gh#285, now deletable, unconfirmed)
|
|
11
11
|
|
|
12
12
|
Before every component module import, the consumer's SSR entry point ran a
|
|
13
13
|
prototype-patching shim: stubbed `attachInternals`, defined four no-op Observer
|
|
14
14
|
classes (`ResizeObserver`/`IntersectionObserver`/`MutationObserver`/`PerformanceObserver`),
|
|
15
15
|
and force-assigned `document.adoptedStyleSheets = []`. Two named fragilities:
|
|
16
|
-
- **Fragile import order
|
|
16
|
+
- **Fragile import order**, the shim MUST execute before any component module
|
|
17
17
|
loads, or the "deep-render pass" crashes anyway. This already broke once in a
|
|
18
|
-
production bundle (per the issue)
|
|
18
|
+
production bundle (per the issue), a bundler/tree-shaking change that reordered
|
|
19
19
|
imports silently reintroduced the crash.
|
|
20
|
-
- **A global patch, not scoped
|
|
20
|
+
- **A global patch, not scoped**, patching `HTMLElement.prototype` /
|
|
21
21
|
`globalThis.ResizeObserver` affects EVERY component and every other library in the
|
|
22
22
|
same process, not just AdiaUI's.
|
|
23
23
|
|
|
24
24
|
**Status as of gh#285's fix (PR #292, merged 2026-07-17): the AdiaUI-facing sections
|
|
25
|
-
of this shim are no longer necessary
|
|
25
|
+
of this shim are no longer necessary**, the framework guards its own call sites now.
|
|
26
26
|
**Consumer-confirmed 2026-08-17 (gh#1430 §Additional context, against 0.8.40):**
|
|
27
27
|
`attachInternals`, the four Observer stubs and `adoptedStyleSheets` are all confirmed
|
|
28
28
|
unnecessary. **But gh#285's closing comment over-reached** in saying the shim "as a
|
|
29
|
-
whole" can go: two of its sections patch `CustomElementRender.prototype
|
|
30
|
-
`setAttribute` null-guard and a `renderShadow` null-guard
|
|
29
|
+
whole" can go: two of its sections patch `CustomElementRender.prototype`, a
|
|
30
|
+
`setAttribute` null-guard and a `renderShadow` null-guard, i.e. they patch
|
|
31
31
|
`custom-elements-ssr` itself, which reads `shadowRoot.innerHTML` unconditionally and
|
|
32
32
|
AdiaUI is light-DOM-only, so `shadowRoot` is always `null`. Remove those two and every
|
|
33
33
|
SSR'd fixture dies with `Cannot read properties of null (reading 'innerHTML')`. No fix
|
|
34
34
|
in this repo can retire them; they belong to the renderer. Tell the next consumer that
|
|
35
35
|
explicitly rather than "the shim is unnecessary". (Also from that trial: `matchMedia`
|
|
36
|
-
was a further AdiaUI-side gap the #292 sweep missed
|
|
36
|
+
was a further AdiaUI-side gap the #292 sweep missed, fixed by gh#1430, so a
|
|
37
37
|
`matchMedia` stub is not needed either from the version carrying it.)
|
|
38
38
|
|
|
39
|
-
## Attribute-only SSR registration restriction (gh#284
|
|
39
|
+
## Attribute-only SSR registration restriction (gh#284, likely no longer necessary, unconfirmed)
|
|
40
40
|
|
|
41
41
|
The consumer restricts server-side custom-element registration to components whose
|
|
42
|
-
visible content derives ENTIRELY from attributes
|
|
42
|
+
visible content derives ENTIRELY from attributes, `button-ui text="…"`, `icon-ui
|
|
43
43
|
name="…"`. Every container (`admin-shell`, `admin-sidebar`, `nav-ui`) and every
|
|
44
44
|
projected-text component (`text-ui`, `avatar-ui`, `badge-ui`, and by extension
|
|
45
45
|
anything using `<component>slotted text</component>` markup) must register
|
|
46
46
|
CLIENT-side only, upgrading after first paint.
|
|
47
47
|
|
|
48
48
|
**Status as of gh#284's narrowing (2026-07-17): the STAMP() reason for this
|
|
49
|
-
restriction is gone
|
|
49
|
+
restriction is gone**, every component it names (and every other shipped
|
|
50
50
|
component with real content) currently derives its visible content from
|
|
51
51
|
properties/attributes only, never from light-DOM children, so `stamp()`'s
|
|
52
52
|
destructive replace never fires against real content for any of them (see
|
|
53
53
|
[`failure-shapes.md`](failure-shapes.md) §2 for the empirical survey). This did
|
|
54
|
-
NOT ship as a `stamp()` fix
|
|
54
|
+
NOT ship as a `stamp()` fix, it's a narrowing based on the CURRENT shape of the
|
|
55
55
|
component set, backed by a forward static audit
|
|
56
56
|
(`scripts/dev/audit-template-child-conflict.mjs`) that would catch a future
|
|
57
57
|
regression.
|
|
58
58
|
|
|
59
|
-
**UPDATE 2026-07-18
|
|
59
|
+
**UPDATE 2026-07-18, but there WAS a second, independent, real reason this
|
|
60
60
|
restriction was justified, now also fixed.** Every component this restriction
|
|
61
|
-
names is attribute/property-driven
|
|
61
|
+
names is attribute/property-driven, and until PR #309, attribute-driven
|
|
62
62
|
content was ITSELF broken under a late/SSR upgrade (see `failure-shapes.md` §2's
|
|
63
63
|
"UPDATE 2026-07-18" and `guard-patterns.md` §2b): `attributeChangedCallback`
|
|
64
64
|
never replayed for pre-existing attributes on upgrade, so `<nav-item-ui
|
|
65
65
|
text="Profile">` rendered with an empty label regardless of the stamp()
|
|
66
66
|
question. That's now fixed at the framework level (`element.js`
|
|
67
67
|
`connectedCallback`). So as of the version carrying PR #309, both reasons this
|
|
68
|
-
restriction existed are addressed
|
|
68
|
+
restriction existed are addressed, not just the one gh#284 originally named.
|
|
69
69
|
|
|
70
70
|
As with gh#285's shim: don't assume the consumer has actually
|
|
71
|
-
relaxed this restriction without checking the issue thread for their confirmation
|
|
72
|
-
— a consumer removing their own workaround is their change, not something this
|
|
71
|
+
relaxed this restriction without checking the issue thread for their confirmation, a consumer removing their own workaround is their change, not something this
|
|
73
72
|
narrowing does automatically. If the consumer's linkedom/`custom-elements-ssr`
|
|
74
73
|
setup surfaces something this repo's own repro didn't (a real second-connect
|
|
75
74
|
timing difference, an app-level component not covered by this framework), that's
|
|
76
75
|
new information worth feeding back into the issue, not something to assume away.
|
|
77
76
|
|
|
78
|
-
## gh#288 (property-only components)
|
|
77
|
+
## gh#288 (property-only components), CLOSED 2026-07-18, workaround droppable
|
|
79
78
|
|
|
80
79
|
The consumer's PRE-fix behavior for `table-ui`/`chart-ui`/`select-ui` with
|
|
81
80
|
programmatic content was: render empty in the SSR response, then a per-page
|
|
82
81
|
wiring script does `customElements.whenDefined(...) → getElementById → assign
|
|
83
82
|
properties` after hydration. As of the fix, that boilerplate is droppable for all
|
|
84
|
-
three
|
|
83
|
+
three, `select-ui` via native `<option>` children (already worked, pre-existing),
|
|
85
84
|
`chart-ui` via a `data="[…]"` JSON attribute (already worked, pre-existing),
|
|
86
85
|
`table-ui` via the same `data="[…]"` attribute (new) plus `<col-def>` children for
|
|
87
86
|
columns (pre-existing). Don't assume the consumer has removed the wiring script
|
|
88
|
-
without their confirmation
|
|
87
|
+
without their confirmation, see [`failure-shapes.md`](failure-shapes.md) §4 for
|
|
89
88
|
the full narrative.
|