baldart 3.9.0 → 3.12.0
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/CHANGELOG.md +93 -0
- package/README.md +15 -3
- package/VERSION +1 -1
- package/framework/.claude/agents/REGISTRY.md +3 -3
- package/framework/.claude/agents/code-reviewer.md +47 -11
- package/framework/.claude/agents/codebase-architect.md +8 -0
- package/framework/.claude/agents/ui-expert.md +355 -43
- package/framework/.claude/commands/design-review.md +7 -0
- package/framework/.claude/skills/bug/SKILL.md +5 -1
- package/framework/.claude/skills/context-primer/SKILL.md +4 -0
- package/framework/.claude/skills/design-system-init/SKILL.md +232 -0
- package/framework/.claude/skills/design-system-init/scripts/component-spec.template.md +79 -0
- package/framework/.claude/skills/frontend-design/SKILL.md +124 -0
- package/framework/.claude/skills/lsp-bootstrap/SKILL.md +113 -0
- package/framework/.claude/skills/motion-design/reference/accessibility-and-modern-apis.md +114 -0
- package/framework/.claude/skills/new/SKILL.md +1 -1
- package/framework/.claude/skills/prd/SKILL.md +3 -1
- package/framework/.claude/skills/simplify/SKILL.md +6 -0
- package/framework/.claude/skills/ui-design/SKILL.md +43 -0
- package/framework/agents/code-search-protocol.md +126 -0
- package/framework/agents/design-review.md +51 -0
- package/framework/agents/design-system-protocol.md +363 -0
- package/framework/agents/index.md +4 -0
- package/framework/docs/LSP-LAYER.md +405 -0
- package/framework/docs/PROJECT-CONFIGURATION.md +17 -0
- package/framework/docs/UPGRADE-3.12-UI-COHERENCE.md +268 -0
- package/framework/templates/baldart.config.template.yml +22 -0
- package/framework/templates/overlays/agents/codebase-architect.lsp-example.md +53 -0
- package/package.json +1 -1
- package/src/commands/configure.js +69 -0
- package/src/commands/doctor.js +55 -0
- package/src/utils/lsp-adapters/go.js +29 -0
- package/src/utils/lsp-adapters/index.js +49 -0
- package/src/utils/lsp-adapters/python.js +42 -0
- package/src/utils/lsp-adapters/ruby.js +30 -0
- package/src/utils/lsp-adapters/rust.js +26 -0
- package/src/utils/lsp-adapters/typescript.js +54 -0
- package/src/utils/lsp-installer.js +118 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: design-system-init
|
|
3
|
+
description: >
|
|
4
|
+
Bootstrap a component registry / design system on a project that doesn't have
|
|
5
|
+
one yet. Scaffolds ${paths.design_system}/INDEX.md (component index +
|
|
6
|
+
Canonical Authority Matrix), tokens-reference.md (extracted from
|
|
7
|
+
${paths.global_styles} / Tailwind config), and a components/<Name>.md spec
|
|
8
|
+
per primitive already present under ${paths.components_primitives}. Then
|
|
9
|
+
flips features.has_design_system: true in baldart.config.yml. Use when the
|
|
10
|
+
user says /design-system-init, "crea design system", "bootstrap design
|
|
11
|
+
system", "inizializza registro componenti", or when configure detected no
|
|
12
|
+
design-system path and the user wants one. Idempotent — refuses to overwrite
|
|
13
|
+
an existing registry, supports incremental re-runs to add specs for new
|
|
14
|
+
components.
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# Design-System Init
|
|
18
|
+
|
|
19
|
+
Scaffold the component registry that the registry-first protocol
|
|
20
|
+
(`framework/agents/design-system-protocol.md`) treats as BLOCKING for every
|
|
21
|
+
UI task. Without a registry, the BLOCKING reads in `ui-design`,
|
|
22
|
+
`frontend-design`, `ui-expert`, and `/design-review` are inert — they have
|
|
23
|
+
nothing to read. This skill creates the missing pieces from the codebase's
|
|
24
|
+
current state so the discipline can kick in immediately.
|
|
25
|
+
|
|
26
|
+
## Project Context
|
|
27
|
+
|
|
28
|
+
**Reads from `baldart.config.yml`:** `paths.design_system`,
|
|
29
|
+
`paths.components_primitives`, `paths.components_root`, `paths.global_styles`,
|
|
30
|
+
`paths.ui_guidelines`, `identity.brand_name`, `identity.design_philosophy`,
|
|
31
|
+
`stack.design_system_signals`.
|
|
32
|
+
|
|
33
|
+
**Gated by features:** none — this skill is the bootstrap mechanism for
|
|
34
|
+
`features.has_design_system`. It refuses to run when a registry is already
|
|
35
|
+
present (`has_design_system: true` AND `paths.design_system/INDEX.md` exists).
|
|
36
|
+
|
|
37
|
+
**Overlay:** loads `.baldart/overlays/design-system-init.md` if present —
|
|
38
|
+
project-specific opinions (e.g. mandated section order in `components/<Name>.md`,
|
|
39
|
+
brand-voice rules to inject into the scaffolded INDEX, custom token extraction
|
|
40
|
+
recipe for non-Tailwind stacks).
|
|
41
|
+
|
|
42
|
+
**On missing keys:** ask the user; do not assume defaults. See
|
|
43
|
+
`framework/agents/project-context.md` § 3.
|
|
44
|
+
|
|
45
|
+
## What This Skill Does
|
|
46
|
+
|
|
47
|
+
1. **Refusal check.** Reads `baldart.config.yml`.
|
|
48
|
+
- If `features.has_design_system: true` AND `${paths.design_system}/INDEX.md`
|
|
49
|
+
exists: stop with "Registry already present at `${paths.design_system}`.
|
|
50
|
+
To extend it, edit it directly or invoke `ui-design` / `frontend-design`
|
|
51
|
+
which know how to propose registry additions."
|
|
52
|
+
- If `has_design_system: true` but the path is missing: warn about the
|
|
53
|
+
drift, offer to re-scaffold at the configured path.
|
|
54
|
+
2. **Resolve target path.** Default `docs/design-system/`. Ask the user to
|
|
55
|
+
confirm or override. Use `${paths.design_system}` if already set in config.
|
|
56
|
+
3. **Inventory existing primitives.** Launch the `codebase-architect` agent
|
|
57
|
+
on `${paths.components_primitives}` (and `${paths.components_root}/shared`
|
|
58
|
+
when present) to extract: file path, exported component name, props
|
|
59
|
+
signature, variants (if discoverable), accessibility hooks used, tokens
|
|
60
|
+
referenced.
|
|
61
|
+
4. **Extract token contract.** Read `${paths.global_styles}` for CSS custom
|
|
62
|
+
properties; read `tailwind.config.{ts,js,mjs,cjs}` for theme extensions;
|
|
63
|
+
read any `tokens.{json,ts,js}` or Style Dictionary output. Group by
|
|
64
|
+
category (color, spacing, shadow, radius, typography, motion).
|
|
65
|
+
5. **Scaffold the files** under the target path:
|
|
66
|
+
- `INDEX.md` — component index, Canonical Authority Matrix (empty
|
|
67
|
+
visual/behavioral/composition columns to be filled by the team),
|
|
68
|
+
pointer to `tokens-reference.md` and `components/`.
|
|
69
|
+
- `tokens-reference.md` — extracted tokens, grouped, with a note that
|
|
70
|
+
`tokens-reference.md` is the SSOT and hardcoded literals are forbidden.
|
|
71
|
+
- `components/<Name>.md` — one file per discovered primitive, generated
|
|
72
|
+
from `scripts/component-spec.template.md`. Fill the fields the inventory
|
|
73
|
+
could resolve; leave clearly-marked TODO sections for the rest.
|
|
74
|
+
- `patterns/.gitkeep` — empty dir for future pattern docs.
|
|
75
|
+
6. **Update config.** Set `features.has_design_system: true` and
|
|
76
|
+
`paths.design_system: <target>` in `baldart.config.yml`. Use the same
|
|
77
|
+
YAML write path as `configure` (preserve user values, never clobber
|
|
78
|
+
unrelated keys).
|
|
79
|
+
7. **Print next-steps.** Authority Matrix to fill, specs to review, suggested
|
|
80
|
+
first follow-up (`/design-review` on a key route to validate the registry).
|
|
81
|
+
|
|
82
|
+
## Workflow
|
|
83
|
+
|
|
84
|
+
1. **Refusal check** — see § What This Skill Does step 1.
|
|
85
|
+
|
|
86
|
+
2. **Target path prompt:**
|
|
87
|
+
```
|
|
88
|
+
Scaffold the registry at: docs/design-system/ [Y/n/custom]
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
3. **Inventory** — launch `codebase-architect` with this prompt skeleton:
|
|
92
|
+
> Enumerate the UI primitives under `${paths.components_primitives}`. For
|
|
93
|
+
> each: file path, exported name, props type (best-effort from TS/JSDoc),
|
|
94
|
+
> variants (e.g. `variant="primary|ghost"`), accessibility attributes
|
|
95
|
+
> (aria-*, role, focus management), design tokens referenced (CSS vars,
|
|
96
|
+
> Tailwind classes that map to tokens). Report as a JSON-friendly list.
|
|
97
|
+
|
|
98
|
+
4. **Token extraction** — for each detected source:
|
|
99
|
+
- CSS custom properties: parse `--*: ...;` declarations and group by prefix.
|
|
100
|
+
- Tailwind theme: parse `theme.extend.{colors,spacing,boxShadow,borderRadius,fontFamily,transitionDuration,transitionTimingFunction}`.
|
|
101
|
+
- Style Dictionary / tokens file: parse the JSON tree.
|
|
102
|
+
- If nothing is found, leave a TODO section in `tokens-reference.md`
|
|
103
|
+
pointing the team to populate it before relying on the SSOT contract.
|
|
104
|
+
|
|
105
|
+
5. **Generate files** using the template in
|
|
106
|
+
`scripts/component-spec.template.md` for each component, and the inline
|
|
107
|
+
templates below for INDEX and tokens-reference.
|
|
108
|
+
|
|
109
|
+
6. **Persist config:**
|
|
110
|
+
```yaml
|
|
111
|
+
paths:
|
|
112
|
+
design_system: docs/design-system # or user-chosen
|
|
113
|
+
features:
|
|
114
|
+
has_design_system: true
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
7. **Output** — short status block (see Output Contract).
|
|
118
|
+
|
|
119
|
+
## Output Contract
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
Design-system bootstrap:
|
|
123
|
+
✓ Created docs/design-system/INDEX.md
|
|
124
|
+
✓ Created docs/design-system/tokens-reference.md (32 tokens extracted)
|
|
125
|
+
✓ Generated 17 component specs under docs/design-system/components/
|
|
126
|
+
⚠ 4 components had no resolvable props — TODO sections marked
|
|
127
|
+
Config updated: baldart.config.yml has_design_system=true, paths.design_system=docs/design-system
|
|
128
|
+
Next: review INDEX.md Authority Matrix, fill TODO sections, run /design-review on a key route.
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## INDEX.md template
|
|
132
|
+
|
|
133
|
+
The generated `INDEX.md` has this skeleton (concrete values substituted from
|
|
134
|
+
the inventory):
|
|
135
|
+
|
|
136
|
+
```markdown
|
|
137
|
+
# ${identity.brand_name} Design System
|
|
138
|
+
|
|
139
|
+
Single source of truth for visual, behavioral, and compositional decisions on
|
|
140
|
+
this product. Read this BEFORE producing or reviewing any UI. The registry-first
|
|
141
|
+
protocol is defined in `framework/agents/design-system-protocol.md`.
|
|
142
|
+
|
|
143
|
+
## Token Contract
|
|
144
|
+
|
|
145
|
+
Tokens live in [`tokens-reference.md`](tokens-reference.md). Hardcoded color /
|
|
146
|
+
shadow / radius / spacing / motion values are FORBIDDEN when these tokens
|
|
147
|
+
cover the use case.
|
|
148
|
+
|
|
149
|
+
## Component Index
|
|
150
|
+
|
|
151
|
+
| Component | File | Purpose | Spec |
|
|
152
|
+
|-----------|------|---------|------|
|
|
153
|
+
| Button | ${paths.components_primitives}/Button.tsx | … | [components/Button.md](components/Button.md) |
|
|
154
|
+
| … | … | … | … |
|
|
155
|
+
|
|
156
|
+
## Canonical Authority Matrix
|
|
157
|
+
|
|
158
|
+
| Dimension | Authority | Override path |
|
|
159
|
+
|--------------------|---------------------------------|---------------|
|
|
160
|
+
| Color / shadow / radius / spacing | `tokens-reference.md` | Propose a new token + ADR |
|
|
161
|
+
| Props / variants / a11y | per-component `components/<Name>.md` | Update the spec in the same change |
|
|
162
|
+
| Composition (patterns) | `patterns/<topic>.md` | New pattern doc + INDEX entry |
|
|
163
|
+
|
|
164
|
+
## Quick MUST Rules
|
|
165
|
+
|
|
166
|
+
- Reuse from the Component Index before inventing a new primitive.
|
|
167
|
+
- Consume tokens via the project's mechanism (CSS vars / Tailwind theme /
|
|
168
|
+
theme provider) — never hardcode literals.
|
|
169
|
+
- Any new primitive ships with its `components/<Name>.md` spec in the same
|
|
170
|
+
change.
|
|
171
|
+
- Authority Matrix violations require a registry update, not a local override.
|
|
172
|
+
|
|
173
|
+
## How to Extend
|
|
174
|
+
|
|
175
|
+
- New primitive → create `components/<Name>.md` (the template lives at
|
|
176
|
+
`.framework/framework/.claude/skills/design-system-init/scripts/component-spec.template.md`
|
|
177
|
+
after `npx baldart add` — copy it, fill it in, drop under
|
|
178
|
+
`${paths.design_system}/components/`),
|
|
179
|
+
implement under `${paths.components_primitives}`, add the row above.
|
|
180
|
+
- New pattern → create `patterns/<topic>.md`, link from this INDEX.
|
|
181
|
+
- New token → add to `tokens-reference.md`, propagate to the project's
|
|
182
|
+
token mechanism.
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## tokens-reference.md template
|
|
186
|
+
|
|
187
|
+
```markdown
|
|
188
|
+
# Token Reference
|
|
189
|
+
|
|
190
|
+
Single source of truth for design tokens. Values below are extracted from
|
|
191
|
+
${paths.global_styles} and tailwind config (when present). DO NOT hardcode
|
|
192
|
+
literals that duplicate these tokens in components.
|
|
193
|
+
|
|
194
|
+
## Color
|
|
195
|
+
- `--color-primary: <value>` — …
|
|
196
|
+
- …
|
|
197
|
+
|
|
198
|
+
## Spacing
|
|
199
|
+
- `--space-1: <value>` — …
|
|
200
|
+
- …
|
|
201
|
+
|
|
202
|
+
## Shadow
|
|
203
|
+
- …
|
|
204
|
+
|
|
205
|
+
## Radius
|
|
206
|
+
- …
|
|
207
|
+
|
|
208
|
+
## Typography
|
|
209
|
+
- …
|
|
210
|
+
|
|
211
|
+
## Motion
|
|
212
|
+
- duration: …
|
|
213
|
+
- easing: …
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Notes
|
|
217
|
+
|
|
218
|
+
- The skill never modifies source components — its only side effects are
|
|
219
|
+
creating files under `${paths.design_system}` and updating
|
|
220
|
+
`baldart.config.yml`.
|
|
221
|
+
- Generated specs are starting points, not final docs. The expected next move
|
|
222
|
+
is human review + filling TODO sections + a `/design-review` pass.
|
|
223
|
+
- Idempotent: re-running detects existing specs and only generates files for
|
|
224
|
+
new primitives (and updates the Component Index table).
|
|
225
|
+
|
|
226
|
+
## See Also
|
|
227
|
+
|
|
228
|
+
- `framework/agents/design-system-protocol.md` — the protocol this skill bootstraps.
|
|
229
|
+
- `framework/agents/project-context.md` — config + overlay contract.
|
|
230
|
+
- `framework/.claude/skills/ui-design/SKILL.md` — primary consumer (reads
|
|
231
|
+
the registry BLOCKING).
|
|
232
|
+
- `scripts/component-spec.template.md` — per-component spec template.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# {{ComponentName}}
|
|
2
|
+
|
|
3
|
+
> Per-component spec. Authoritative for props, variants, accessibility, and
|
|
4
|
+
> anti-patterns. Visual authority (color/shadow/radius/spacing) belongs to
|
|
5
|
+
> [`../tokens-reference.md`](../tokens-reference.md).
|
|
6
|
+
|
|
7
|
+
## Source
|
|
8
|
+
|
|
9
|
+
- File: `{{file_path}}`
|
|
10
|
+
- Exported as: `{{exported_name}}`
|
|
11
|
+
- Used by: <!-- TODO: list 2-3 key consumers, e.g. pages or compound components -->
|
|
12
|
+
|
|
13
|
+
## Purpose
|
|
14
|
+
|
|
15
|
+
<!-- One-sentence statement of what this primitive is for and when to reach
|
|
16
|
+
for it instead of an alternative. -->
|
|
17
|
+
|
|
18
|
+
## Props
|
|
19
|
+
|
|
20
|
+
| Prop | Type | Default | Notes |
|
|
21
|
+
|------|------|---------|-------|
|
|
22
|
+
{{props_table}}
|
|
23
|
+
|
|
24
|
+
<!-- TODO: if props were not auto-resolvable, fill the table from the source
|
|
25
|
+
file. Keep types accurate — drift here is the most common bug. -->
|
|
26
|
+
|
|
27
|
+
## Variants
|
|
28
|
+
|
|
29
|
+
{{variants_section}}
|
|
30
|
+
|
|
31
|
+
<!-- TODO: enumerate every variant the component exposes. For each, describe
|
|
32
|
+
when to use it. Example:
|
|
33
|
+
- `variant="primary"` — primary CTA, one per surface
|
|
34
|
+
- `variant="ghost"` — secondary actions in dense layouts
|
|
35
|
+
- `size="sm" | "md" | "lg"` — bind to spacing tokens
|
|
36
|
+
-->
|
|
37
|
+
|
|
38
|
+
## Tokens consumed
|
|
39
|
+
|
|
40
|
+
{{tokens_section}}
|
|
41
|
+
|
|
42
|
+
<!-- TODO: list the tokens this component reads from tokens-reference.md.
|
|
43
|
+
Color, spacing, shadow, radius, motion. If you find hardcoded literals in
|
|
44
|
+
the source, that's a registry violation — fix at the source. -->
|
|
45
|
+
|
|
46
|
+
## Accessibility
|
|
47
|
+
|
|
48
|
+
- Keyboard: <!-- focus order, shortcuts, escape behavior -->
|
|
49
|
+
- ARIA: <!-- roles, labels, descriptions, live regions -->
|
|
50
|
+
- Touch target: ≥ 44×44px when interactive
|
|
51
|
+
- Color contrast: text ≥ 4.5:1, UI ≥ 3:1 (WCAG 2.1 AA)
|
|
52
|
+
- Reduced motion: respects `prefers-reduced-motion`
|
|
53
|
+
|
|
54
|
+
## Composition
|
|
55
|
+
|
|
56
|
+
<!-- How this primitive composes with others. Patterns it appears in.
|
|
57
|
+
Cross-link to patterns/ docs when applicable. -->
|
|
58
|
+
|
|
59
|
+
## Anti-patterns
|
|
60
|
+
|
|
61
|
+
<!-- Common misuses that should be rejected in code review. Examples:
|
|
62
|
+
- Wrapping in a div with absolute positioning to fake a variant — add a
|
|
63
|
+
variant to the registry instead.
|
|
64
|
+
- Hardcoding a custom color via inline style — add a token and consume it.
|
|
65
|
+
-->
|
|
66
|
+
|
|
67
|
+
## MUST rules
|
|
68
|
+
|
|
69
|
+
<!-- HIGH-severity rules the code-reviewer agent enforces. Examples:
|
|
70
|
+
- MUST consume `--color-primary` for background; never hardcode.
|
|
71
|
+
- MUST set `aria-label` when icon-only.
|
|
72
|
+
-->
|
|
73
|
+
|
|
74
|
+
## Changelog
|
|
75
|
+
|
|
76
|
+
<!-- Track breaking changes to the spec. Bump version when removing a variant
|
|
77
|
+
or changing a default. -->
|
|
78
|
+
|
|
79
|
+
- {{today}} — Spec scaffolded by `/design-system-init`.
|
|
@@ -50,6 +50,11 @@ Remember: Claude is capable of extraordinary creative work. Don't hold back, sho
|
|
|
50
50
|
|
|
51
51
|
## MANDATORY Pre-Work Read (project design-system override)
|
|
52
52
|
|
|
53
|
+
The registry-first cascade below is the consumer view of the SSOT in
|
|
54
|
+
[`framework/agents/design-system-protocol.md`](../../../agents/design-system-protocol.md).
|
|
55
|
+
When the cascade rules diverge between this file and the protocol module,
|
|
56
|
+
the protocol module wins.
|
|
57
|
+
|
|
53
58
|
When operating inside a repo that ships a design-system SSOT, the generic
|
|
54
59
|
creative guidance above is BLOCKED by the project design-system until the
|
|
55
60
|
reads below are complete. MANDATORY pre-work reads (skipping any of them is
|
|
@@ -72,6 +77,125 @@ Within those bounds, creative choices (typography nuance, composition, motion in
|
|
|
72
77
|
|
|
73
78
|
---
|
|
74
79
|
|
|
80
|
+
## Performance Gates (Core Web Vitals 2026)
|
|
81
|
+
|
|
82
|
+
Production-grade frontend is not just "looks good" — it ships within the CWV
|
|
83
|
+
thresholds. Every page / component / route MUST be designed against these
|
|
84
|
+
budgets, not retrofitted after Lighthouse complains.
|
|
85
|
+
|
|
86
|
+
### Thresholds (p75, CrUX dataset)
|
|
87
|
+
|
|
88
|
+
| Metric | Good | Poor | What it measures |
|
|
89
|
+
|---|---|---|---|
|
|
90
|
+
| **LCP** | ≤ 2.5s | > 4.0s | Largest Contentful Paint — usually the hero image or H1 |
|
|
91
|
+
| **INP** | ≤ 200ms | > 500ms | Interaction to Next Paint — replaced FID in Mar 2024 |
|
|
92
|
+
| **CLS** | ≤ 0.1 | > 0.25 | Cumulative Layout Shift |
|
|
93
|
+
| TTFB | ≤ 0.8s | > 1.8s | Subset of LCP (~40% of budget) |
|
|
94
|
+
| FCP | ≤ 1.8s | > 3.0s | Diagnostic only |
|
|
95
|
+
|
|
96
|
+
A page passes CWV when all three (LCP/INP/CLS) are *good* at p75. INP is the
|
|
97
|
+
hardest of the three on JS-heavy apps and the most commonly failed (~43% of
|
|
98
|
+
sites globally).
|
|
99
|
+
|
|
100
|
+
### LCP image: the only correct pattern
|
|
101
|
+
|
|
102
|
+
```html
|
|
103
|
+
<!-- in <head> — preload + fetchpriority for the hero -->
|
|
104
|
+
<link rel="preload" as="image"
|
|
105
|
+
href="/hero.avif"
|
|
106
|
+
imagesrcset="/hero-800.avif 800w, /hero-1600.avif 1600w"
|
|
107
|
+
imagesizes="100vw"
|
|
108
|
+
fetchpriority="high">
|
|
109
|
+
|
|
110
|
+
<!-- in body — picture with AVIF/WebP/fallback + explicit dimensions -->
|
|
111
|
+
<picture>
|
|
112
|
+
<source srcset="/hero.avif" type="image/avif">
|
|
113
|
+
<source srcset="/hero.webp" type="image/webp">
|
|
114
|
+
<img src="/hero.jpg" alt="..."
|
|
115
|
+
fetchpriority="high"
|
|
116
|
+
width="1600" height="900">
|
|
117
|
+
</picture>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**Never** apply `loading="lazy"` to the LCP image. **Never** render the LCP
|
|
121
|
+
image via client-side JS after hydration — server-render it or preload it.
|
|
122
|
+
|
|
123
|
+
### INP fixes
|
|
124
|
+
|
|
125
|
+
- Break any task > 50ms into `await scheduler.yield()` chunks (Chrome 129+;
|
|
126
|
+
fallback `await new Promise(r => setTimeout(r, 0))`).
|
|
127
|
+
- Debounce input handlers to one frame (~16ms) when they trigger expensive
|
|
128
|
+
recomputes. Throttle scroll/resize to `requestAnimationFrame`.
|
|
129
|
+
- Move CPU-bound work (parsing, transforming, encoding) off the main thread
|
|
130
|
+
with Web Workers when latency matters.
|
|
131
|
+
- Avoid `setInterval` polling for data — use SWR / React Query / TanStack
|
|
132
|
+
Query with stale-while-revalidate.
|
|
133
|
+
|
|
134
|
+
### CLS budget — zero unexpected shift
|
|
135
|
+
|
|
136
|
+
- Every `<img>`, `<iframe>`, `<video>` declares `width` + `height` or
|
|
137
|
+
`aspect-ratio` CSS.
|
|
138
|
+
- Web fonts: `font-display: optional` (no FOIT/FOUT shift, accept fallback
|
|
139
|
+
on first load) OR `size-adjust` + matching `ascent-override` /
|
|
140
|
+
`descent-override` / `line-gap-override` to produce a metric-compatible
|
|
141
|
+
fallback font.
|
|
142
|
+
- Skeleton screens mirror the real layout dimensions exactly — a skeleton
|
|
143
|
+
that's the wrong height *causes* CLS instead of preventing it.
|
|
144
|
+
- Inserted UI (banners, cookie notices, ads) must reserve space upfront via
|
|
145
|
+
`min-height` — never push existing content down post-paint.
|
|
146
|
+
|
|
147
|
+
## Modern CSS (2025–2026)
|
|
148
|
+
|
|
149
|
+
Default to platform features instead of JS shims:
|
|
150
|
+
|
|
151
|
+
- **Container queries** (`@container` + `container-type: inline-size`) —
|
|
152
|
+
default for any component that lives in variable-width contexts (sidebar,
|
|
153
|
+
grid cell, modal). Component decides its own breakpoint, independent of
|
|
154
|
+
viewport. Use viewport-based `@media` only for app-shell-level layout.
|
|
155
|
+
- **`:has()`** — collapse `useState` that exists *only for styling*
|
|
156
|
+
(e.g. label color reacting to input invalid state). Never put business
|
|
157
|
+
logic into `:has()` — only visual reactions to DOM state.
|
|
158
|
+
- **View Transitions API** — `document.startViewTransition()` for SPA
|
|
159
|
+
navigation and `view-transition-name` for shared-element morphs. See
|
|
160
|
+
`motion-design/reference/accessibility-and-modern-apis.md` for the full
|
|
161
|
+
pattern.
|
|
162
|
+
- **Subgrid** — children align to the parent grid without re-declaring
|
|
163
|
+
tracks. Fixes the long-standing "card content alignment across rows"
|
|
164
|
+
problem.
|
|
165
|
+
- **Logical properties** — `margin-inline-start` / `padding-block` instead
|
|
166
|
+
of `margin-left` / `padding-top` whenever the project might add RTL or
|
|
167
|
+
vertical-writing-mode locales. Free i18n with zero overhead.
|
|
168
|
+
- **`color-mix()`** — derive hover / focus / disabled states from semantic
|
|
169
|
+
tokens without inventing new tokens
|
|
170
|
+
(`color-mix(in oklch, var(--color-action-primary) 90%, black)`).
|
|
171
|
+
- **`@scope`** — scope CSS to a subtree without selector specificity wars or
|
|
172
|
+
CSS-in-JS. Useful when migrating off CSS Modules / styled-components.
|
|
173
|
+
|
|
174
|
+
## Form quality (always-on requirements)
|
|
175
|
+
|
|
176
|
+
These apply to every form, every project — they are not "nice to have":
|
|
177
|
+
|
|
178
|
+
- `<label>` associated to input via `htmlFor` / `id` (never wrap-only — fails
|
|
179
|
+
some screen readers).
|
|
180
|
+
- `autocomplete=` filled for every personal-data field
|
|
181
|
+
(`email | tel | given-name | family-name | street-address | postal-code |
|
|
182
|
+
cc-number | one-time-code` …). Required by WCAG 2.1 SC 1.3.5.
|
|
183
|
+
- Validation **on blur**, not on every keystroke. Re-validate on submit.
|
|
184
|
+
- Error messages are **actionable** ("Email manca @ — esempio:
|
|
185
|
+
nome@dominio.it"), never generic ("Invalid input").
|
|
186
|
+
- `aria-invalid` + `aria-describedby` linking the input to its error
|
|
187
|
+
element. Error element has `role="alert"` only when it appears
|
|
188
|
+
dynamically.
|
|
189
|
+
- `inputMode=` set when it differs from `type` (e.g. `type="text"
|
|
190
|
+
inputMode="numeric"` for SMS codes — keeps the field text-shaped but
|
|
191
|
+
triggers the numeric keypad).
|
|
192
|
+
- Paste handling normalizes whitespace and format BEFORE validating
|
|
193
|
+
(cc-number without spaces, tel without separators).
|
|
194
|
+
- Submit button disabled only **after** a failed attempt — never blocked
|
|
195
|
+
pre-emptively; users should be allowed to try and receive feedback.
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
75
199
|
## Prototipi Standalone e Demo
|
|
76
200
|
|
|
77
201
|
Quando il task richiede un prototipo HTML interattivo, demo animata, slide deck, mockup iOS/app, o design exploration **NON legato alla codebase Next.js** (nessun contesto `src/app/`), invocare la skill `huashu-design` in aggiunta o al posto di questa skill. Essa fornisce:
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lsp-bootstrap
|
|
3
|
+
description: >
|
|
4
|
+
Install, verify, and document the LSP symbol-search layer for this project.
|
|
5
|
+
Detects languages (TypeScript, Python, Go, Rust, Ruby), installs the matching
|
|
6
|
+
language servers (npm devDep where possible, system command otherwise),
|
|
7
|
+
verifies binaries are reachable, and writes lsp.installed_servers to
|
|
8
|
+
baldart.config.yml. Use when the user says /lsp-bootstrap, "install LSP",
|
|
9
|
+
"set up symbol search", or after enabling features.has_lsp_layer for the
|
|
10
|
+
first time. Idempotent — re-running on an already-configured project
|
|
11
|
+
re-verifies and reports drift.
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# LSP Bootstrap
|
|
15
|
+
|
|
16
|
+
Set up the LSP (Language Server Protocol) layer that lets agents and skills
|
|
17
|
+
search by symbol instead of by string. Without this layer, code search burns
|
|
18
|
+
context on textual collisions; with it, references resolve to the same symbol
|
|
19
|
+
**before** Claude reads any file.
|
|
20
|
+
|
|
21
|
+
## Project Context
|
|
22
|
+
|
|
23
|
+
**Reads from `baldart.config.yml`:** `features.has_lsp_layer`, `lsp.installed_servers`, `lsp.auto_verify`.
|
|
24
|
+
**Gated by features:** `features.has_lsp_layer` — this skill refuses to run when the flag is `false`, prompting the user to flip it via `npx baldart configure` first.
|
|
25
|
+
**Overlay:** loads `.baldart/overlays/lsp-bootstrap.md` if present — project-specific install commands (e.g. a system-managed pyright via uv, a non-standard gopls path).
|
|
26
|
+
**On missing keys:** ask the user; do not assume defaults. See `framework/agents/project-context.md` § 3.
|
|
27
|
+
|
|
28
|
+
## What This Skill Does
|
|
29
|
+
|
|
30
|
+
1. Reads `baldart.config.yml` and confirms `features.has_lsp_layer: true`.
|
|
31
|
+
2. Probes the cwd via `src/utils/lsp-adapters/` to detect which languages are
|
|
32
|
+
present (markers: `tsconfig.json`, `pyproject.toml`, `go.mod`, `Cargo.toml`,
|
|
33
|
+
`Gemfile`, plus heuristic fallbacks).
|
|
34
|
+
3. For each detected language:
|
|
35
|
+
- **npm-dev** adapters (TypeScript, Python via pyright): runs `npm install
|
|
36
|
+
--save-dev <pkg>` with user confirmation.
|
|
37
|
+
- **system** adapters (Go gopls, Rust rust-analyzer, Ruby ruby-lsp): prints
|
|
38
|
+
the install command for the user to run in a separate terminal. Does NOT
|
|
39
|
+
execute system-level installs automatically.
|
|
40
|
+
4. Verifies each binary is reachable (`<binary> --version`).
|
|
41
|
+
5. Updates `lsp.installed_servers` in `baldart.config.yml` with the verified
|
|
42
|
+
set. System-mode servers are recorded even if not yet reachable (the user
|
|
43
|
+
may have a pending install) — `baldart doctor` will flag the mismatch.
|
|
44
|
+
6. Prints a summary table and points the user to
|
|
45
|
+
`framework/agents/code-search-protocol.md` for runtime behavior.
|
|
46
|
+
|
|
47
|
+
## Workflow
|
|
48
|
+
|
|
49
|
+
1. **Refusal check.** If `features.has_lsp_layer: false` (or missing):
|
|
50
|
+
```
|
|
51
|
+
This project hasn't opted in to the LSP layer yet.
|
|
52
|
+
Run `npx baldart configure` and answer YES to "Enable LSP symbol-search layer?"
|
|
53
|
+
then re-run /lsp-bootstrap.
|
|
54
|
+
```
|
|
55
|
+
Stop here. Do not proceed.
|
|
56
|
+
|
|
57
|
+
2. **Probe.** Call the BALDART installer (internally `src/utils/lsp-installer.js`):
|
|
58
|
+
```
|
|
59
|
+
node -e 'const L=require("./.framework/src/utils/lsp-installer"); console.log(JSON.stringify(new L().recommend(),null,2))'
|
|
60
|
+
```
|
|
61
|
+
Show the detected languages with their `installMode`.
|
|
62
|
+
|
|
63
|
+
3. **Confirm per server.** For each recommended server, ask the user. Skip the
|
|
64
|
+
ones already in `lsp.installed_servers` unless they fail verify.
|
|
65
|
+
|
|
66
|
+
4. **Install.** Run the appropriate `installCommand()`. Capture failures into a
|
|
67
|
+
"Skipped" bucket — never abort the whole skill on one failure.
|
|
68
|
+
|
|
69
|
+
5. **Verify.** For each installed server, call its `verifyCommand()`. Mark the
|
|
70
|
+
results.
|
|
71
|
+
|
|
72
|
+
6. **Persist.** Update `baldart.config.yml`:
|
|
73
|
+
```yaml
|
|
74
|
+
lsp:
|
|
75
|
+
installed_servers: [typescript, python]
|
|
76
|
+
auto_verify: true
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
7. **Output.** A compact one-line status, in the project's `identity.language`
|
|
80
|
+
from `baldart.config.yml` (English default). Matches the brevity of
|
|
81
|
+
`/cont` rather than its specific Italian phrasing.
|
|
82
|
+
|
|
83
|
+
## Output Contract
|
|
84
|
+
|
|
85
|
+
A single short status block — never a multi-page report. Format:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
LSP bootstrap:
|
|
89
|
+
✓ typescript-language-server (npm devDep, verified)
|
|
90
|
+
✓ pyright (npm devDep, verified)
|
|
91
|
+
⚠ gopls — run `go install golang.org/x/tools/gopls@latest`, then `baldart doctor`
|
|
92
|
+
· ruby — not detected (no Gemfile)
|
|
93
|
+
Config updated: baldart.config.yml lsp.installed_servers = [typescript, python, go]
|
|
94
|
+
Next: codebase-architect will now prefer LSP find-references over Grep for symbols.
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Notes
|
|
98
|
+
|
|
99
|
+
- This skill never edits source code or installs binaries that aren't language
|
|
100
|
+
servers — its only side effect is `npm install --save-dev <lsp-package>` and a
|
|
101
|
+
YAML write to `baldart.config.yml`.
|
|
102
|
+
- For Claude Code users: in addition to the binaries, you may need to load a
|
|
103
|
+
code-intelligence plugin (`/plugin` in Claude Code). That step is documented
|
|
104
|
+
in the printed output when applicable, but the skill does NOT manage Claude
|
|
105
|
+
Code plugins directly.
|
|
106
|
+
- Re-run safely. The skill diffs the current `lsp.installed_servers` against
|
|
107
|
+
recommended + verified, so additions / removals / repairs are all idempotent.
|
|
108
|
+
|
|
109
|
+
## See Also
|
|
110
|
+
|
|
111
|
+
- `framework/agents/code-search-protocol.md` — runtime fallback rules
|
|
112
|
+
- `src/utils/lsp-adapters/` — per-language install/verify recipes
|
|
113
|
+
- `src/commands/configure.js` — same install flow when first enabling the flag
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Accessibility & Modern Motion APIs
|
|
2
|
+
|
|
3
|
+
## `prefers-reduced-motion` — collapse, don't disable
|
|
4
|
+
|
|
5
|
+
```css
|
|
6
|
+
:root {
|
|
7
|
+
--motion-duration-fast: 150ms;
|
|
8
|
+
--motion-duration-base: 250ms;
|
|
9
|
+
--motion-duration-slow: 400ms;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
@media (prefers-reduced-motion: reduce) {
|
|
13
|
+
:root {
|
|
14
|
+
--motion-duration-fast: 0.01ms;
|
|
15
|
+
--motion-duration-base: 0.01ms;
|
|
16
|
+
--motion-duration-slow: 0.01ms;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**Why 0.01ms, not 0?** Some Safari/WebKit versions skip the `transitionend`
|
|
22
|
+
event entirely when duration is exactly `0` — state machines that wait on
|
|
23
|
+
that event hang. `0.01ms` is functionally instant but keeps the event
|
|
24
|
+
pipeline intact.
|
|
25
|
+
|
|
26
|
+
**What stays vs. what goes** when reduced-motion is requested:
|
|
27
|
+
|
|
28
|
+
- KEEP: opacity fades < 200ms (no vestibular impact), color cross-fades,
|
|
29
|
+
scale changes < 5%, subtle elevation changes.
|
|
30
|
+
- COLLAPSE: translate / parallax / scale > 5% / rotate / skew / 3D
|
|
31
|
+
perspective / spring overshoot — anything with apparent motion across the
|
|
32
|
+
viewport.
|
|
33
|
+
|
|
34
|
+
**Don't** apply a global `* { animation: none !important }` reset — that
|
|
35
|
+
breaks loading spinners, focus indicators, and any animation that
|
|
36
|
+
*communicates state*. Token-level collapse is the right primitive.
|
|
37
|
+
|
|
38
|
+
## View Transitions API
|
|
39
|
+
|
|
40
|
+
For same-document navigation (SPA route change, list ↔ detail, tab switch):
|
|
41
|
+
|
|
42
|
+
```js
|
|
43
|
+
function navigate(to) {
|
|
44
|
+
if (!document.startViewTransition) {
|
|
45
|
+
applyDom(to); // graceful fallback — no transition
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
document.startViewTransition(() => applyDom(to));
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
For shared-element morph (hero image survives the route change):
|
|
53
|
+
|
|
54
|
+
```css
|
|
55
|
+
.hero-image {
|
|
56
|
+
view-transition-name: hero-image; /* unique per shared element */
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
::view-transition-old(hero-image),
|
|
60
|
+
::view-transition-new(hero-image) {
|
|
61
|
+
animation-duration: var(--motion-duration-base);
|
|
62
|
+
animation-timing-function: cubic-bezier(0.2, 0, 0, 1); /* emphasized */
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
For cross-document transitions (MPA, Chrome 126+, behind opt-in CSS):
|
|
67
|
+
|
|
68
|
+
```css
|
|
69
|
+
@view-transition { navigation: auto; }
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**Accessibility**: View Transitions automatically respect
|
|
73
|
+
`prefers-reduced-motion` when the page exposes the reduced-motion media
|
|
74
|
+
query — no extra wiring needed beyond the token collapse above.
|
|
75
|
+
|
|
76
|
+
**Use it for**: navigation, list ↔ detail morphs, sort / filter reorders,
|
|
77
|
+
modal hero reveal. **Don't use it for**: per-frame interactive feedback
|
|
78
|
+
(hover, focus, drag) — those need direct CSS / spring animations.
|
|
79
|
+
|
|
80
|
+
## Spring vs. timing function — when to pick which
|
|
81
|
+
|
|
82
|
+
| Use case | Pick |
|
|
83
|
+
|---|---|
|
|
84
|
+
| Direct manipulation (drag release, swipe, pull-to-refresh) | Spring |
|
|
85
|
+
| Page / view transition | Cubic-bezier (deterministic, easy to choreograph) |
|
|
86
|
+
| Acknowledgment / tap feedback | Cubic-bezier (short, predictable) |
|
|
87
|
+
| Interruptible animation that should "settle naturally" | Spring |
|
|
88
|
+
| Stagger choreography | Cubic-bezier (timeline easier to reason about) |
|
|
89
|
+
|
|
90
|
+
**Spring rule of thumb**: stiffness 250–350 + damping 18–24 = "standard
|
|
91
|
+
feel". Higher stiffness = snappier; lower damping = more oscillation. Cap
|
|
92
|
+
total settle time at 600ms — beyond that the user perceives "lag", not
|
|
93
|
+
physicality.
|
|
94
|
+
|
|
95
|
+
## Choreography budget
|
|
96
|
+
|
|
97
|
+
- Single-element transition: 100–500ms (see `timing-easing-tables.md`).
|
|
98
|
+
- Stagger of multiple children: each child delay 30–50ms, **total budget
|
|
99
|
+
≤ 600ms** (faster on dense lists — cap at 400ms for >10 items).
|
|
100
|
+
- Page-load sequence: hero ≤ 250ms, secondary content stagger ≤ 400ms
|
|
101
|
+
total. Beyond that the user is staring at incomplete UI.
|
|
102
|
+
|
|
103
|
+
## Animation that communicates state — never collapse these
|
|
104
|
+
|
|
105
|
+
Reduced-motion does NOT mean *no feedback*. Always preserve:
|
|
106
|
+
|
|
107
|
+
- Focus ring appearance (instant is fine — but visible).
|
|
108
|
+
- Loading indicators (a static spinner or skeleton is still feedback).
|
|
109
|
+
- Validation error appearance (color + icon — duration can be 0).
|
|
110
|
+
- Toast / notification appearance (fade-in opacity ≤ 200ms is acceptable
|
|
111
|
+
under reduced-motion).
|
|
112
|
+
|
|
113
|
+
Stripping these leaves users without feedback that an action registered —
|
|
114
|
+
worse than the animation they tried to avoid.
|
|
@@ -236,7 +236,7 @@ For each card, execute these phases in order:
|
|
|
236
236
|
- If NOT `DONE` → HALT: log in `## Issues & Flags` and ask the user: "Card <CARD-ID> depends on <DEP-ID> which is `<status>`. Proceed anyway, or wait?" Do not start implementation until the user responds explicitly.
|
|
237
237
|
- If `DONE` → continue.
|
|
238
238
|
3. Update `${paths.references_dir}/project-status.md` Active Code Context (skip when the file does not exist in the project).
|
|
239
|
-
4. Invoke the **codebase-architect** agent (MUST per AGENTS.md) to understand the relevant codebase area, existing patterns, and architecture before any implementation.
|
|
239
|
+
4. Invoke the **codebase-architect** agent (MUST per AGENTS.md) to understand the relevant codebase area, existing patterns, and architecture before any implementation. When `features.has_lsp_layer: true`, the architect uses LSP find-references for any identifier-shaped lookups inside the card (transitive via `agents/code-search-protocol.md`).
|
|
240
240
|
4b. **Plan-auditor grounding check** — invoke the **plan-auditor** agent in QUICK mode with this prompt:
|
|
241
241
|
```
|
|
242
242
|
Quick grounding check only (not a full audit). Verify this backlog card's requirements are grounded in the actual codebase.
|