Skip to content

Commit e523ad9

Browse files
authored
Merge pull request #105 from 4sh/fix/FSHSP-177
Fix/fshsp 177
2 parents 5a2be0b + 15766b0 commit e523ad9

69 files changed

Lines changed: 20843 additions & 35533 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/agents/design-system-expert.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ You are an Angular 22 headless design-system expert for this starter's component
1717
| | `storybook/docs/**` (global foundations/specifications docs) |
1818
| | `scripts/**`, `.github/**` |
1919

20-
**Out-of-scope requests**: refuse and orient — domain components (project prefix, composition of `ui-*`) and core services belong to the main thread per `AGENTS.md`; token additions are proposed as a JSON diff + `npm run tokens:build`, applied only after user approval.
20+
**Out-of-scope requests**: refuse and orient — domain components (project prefix, composition of `ui-*`) and core services belong to the main thread per `AGENTS.md`; token additions are proposed as a JSON diff + `pnpm tokens:build`, applied only after user approval.
2121

2222
## Sources of truth (consult, never duplicate)
2323

@@ -76,7 +76,7 @@ If the verb matches none of these, or the phrasing is ambiguous (“check that
7676
4. Create/modify the component files, **then** the co-located `.stories.ts` and `.mdx` — both mandatory.
7777
5. Every color/spacing consumed must exist in `src/styles/src/generated/` — grep the variable name to confirm; cover light AND dark (and the 3 brands).
7878
6. Update `components-index.md` (check off / add the component).
79-
7. Verify: `npm run lint` + `npm run build-storybook` (the real AoT typecheck). For visual verification, suggest the `/verify` skill.
79+
7. Verify: `pnpm lint` + `pnpm build-storybook` (the real AoT typecheck). For visual verification, suggest the `/verify` skill.
8080
8. Final summary: files created/modified, lint/build status, propagations (new token needed → proposed JSON diff, consumers impacted via a references search).
8181

8282
### AUDIT mode — gap report, **zero modification**
@@ -136,14 +136,14 @@ For each component in scope, check:
136136
2. Risky changes (renaming an exported component, changing a public `input()`/`output()` signature, moving between categories): **propose the diff** and ask for confirmation, listing consumers via a references search.
137137
3. Trivial gaps (`*ngIf``@if`, `[ngClass]``[class]`, decorator → signal, hardcoded value → token, missing `track`): apply directly.
138138
4. **Always** update `.stories.ts` + `.mdx` when the component changes (API, prop, visible behavior) — and `CHANGELOG.md` `[Unreleased]` for user-visible changes.
139-
5. Final verification: `npm run lint` + `npm run build-storybook`.
139+
5. Final verification: `pnpm lint` + `pnpm build-storybook`.
140140

141141
## Guardrails
142142

143143
- **Out of scope**: refuse and orient (domain components, core services, token JSON, Figma).
144-
- **Missing token**: never invent a variable — propose the addition in `src/design-tokens/*.json` + `npm run tokens:build`, ask first.
144+
- **Missing token**: never invent a variable — propose the addition in `src/design-tokens/*.json` + `pnpm tokens:build`, ask first.
145145
- **Doubt about a convention**: cite the source (AGENTS.md section, rule, reference pattern). Otherwise `Grep` the kit (>10 occurrences = de-facto convention; <3 = don't generalize).
146-
- **Verification**: at minimum `npm run lint` + `npm run build-storybook` after any change; report status. Visual doubts → suggest `/verify`.
146+
- **Verification**: at minimum `pnpm lint` + `pnpm build-storybook` after any change; report status. Visual doubts → suggest `/verify`.
147147
- **Never commit** — report the touched files and let the user commit (via `/git-commit`).
148148

149149
## Output format

.claude/rules/git-conventions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Git conventions
22

3-
Full release workflow (SemVer bumps, `npm version`, tags): see `docs/VERSIONING.md`.
3+
Full release workflow (SemVer bumps, `pnpm version`, tags): see `docs/VERSIONING.md`.
44

55
## Commit format — Conventional Commits
66

.claude/settings.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
"Read",
55
"Glob",
66
"Grep",
7-
"Bash(npm run lint)",
8-
"Bash(npm run tokens:build)",
9-
"Bash(npm run build-storybook)",
7+
"Bash(pnpm lint)",
8+
"Bash(pnpm tokens:build)",
9+
"Bash(pnpm build-storybook)",
1010
"Bash(git status)",
1111
"Bash(git diff:*)",
1212
"Bash(git log:*)",

.claude/skills/generate-ui-component/SKILL.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ Rules:
113113

114114
### `///` comments = the theming doc (mandatory)
115115

116-
The doc's "Theming" table is **generated** from the `.scss` by `npm run docs:config`
116+
The doc's "Theming" table is **generated** from the `.scss` by `pnpm docs:config`
117117
(`scripts/docs.config.mjs``storybook/generated/ui-config.json`). So the SCSS comments are
118118
what write the doc: nothing to copy elsewhere.
119119

@@ -137,7 +137,7 @@ what write the doc: nothing to copy elsewhere.
137137
project rebinds the variable.
138138
- Describe the **role**, not the binding: the "Default (starter)" column and the chain to
139139
`ui-config` are inferred automatically.
140-
- **Every** config variable must have its `///``npm run docs:config` counts the missing ones
140+
- **Every** config variable must have its `///``pnpm docs:config` counts the missing ones
141141
(they don't appear in the table).
142142
- **Exposed custom properties** (override points) are documented with a `///` where the hook
143143
lives: on its declaration, or on the line reading it with its fallback
@@ -224,9 +224,9 @@ import { ConfigTable } from '<…>/storybook/blocks/config-table';
224224

225225
## Verification
226226

227-
1. `npx tsc --noEmit -p tsconfig.json` → must pass.
227+
1. `pnpm exec tsc --noEmit -p tsconfig.json` → must pass.
228228
2. Compile the SCSS: `node_modules/.bin/sass --load-path=src/styles --no-source-map --quiet <file.scss>` and check the generated selectors/values.
229-
2bis. `npm run docs:config` → the component must appear, with **0 variables missing a `///`
229+
2bis. `pnpm docs:config` → the component must appear, with **0 variables missing a `///`
230230
comment** (the script prints the count), and every line resolved to a token, a map, a list, or
231231
an accepted literal value.
232232
3. **Live Storybook** (already running on `:6006`, HMR): via the browser tools, open `iframe.html?id=components-ui-{cat}-ui-{name}--<story>&viewMode=story`, measure (getBoundingClientRect, getComputedStyle), test the interaction (click/keyboard), and take a screenshot. Wait for transitions to settle before measuring.

.claude/skills/qa-component-methodology/SKILL.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ juste à l'œil :
4747
## 3. Vérifications statiques
4848

4949
```bash
50-
npx eslint <dossier> --max-warnings 0
51-
npx tsc --noEmit -p tsconfig.app.json | grep <composant>
50+
pnpm exec eslint <dossier> --max-warnings 0
51+
pnpm exec tsc --noEmit -p tsconfig.app.json | grep <composant>
5252
```
5353

5454
## 4. Vérification visuelle/interactive dans Storybook

.claude/skills/verify/SKILL.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,24 @@ Project surface: **Storybook** (no meaningful app page; `ng serve` shows almost
1010
## Recipe that works
1111

1212
```bash
13-
npm run build-storybook # AOT of all stories → storybook-static/
13+
pnpm build-storybook # AOT of all stories → storybook-static/
1414
cd storybook-static && python3 -m http.server 6007 &
1515
```
1616

1717
Drive with Playwright + system Chrome (no browser download):
1818

1919
```js
20-
// npm i playwright in a temporary directory (e.g. /tmp/sb-verify) — not in the repo
20+
// `playwright` is now a repo devDependency,
21+
// so there is no temporary install to do any more: run the script through
22+
// `pnpm exec node <script.mjs>` and import it directly.
2123
import { chromium } from 'playwright';
2224
const browser = await chromium.launch({ channel: 'chrome', headless: true });
2325
```
2426

27+
`channel: 'chrome'` uses the system Chrome, so no browser download is needed. If it
28+
is missing, `pnpm exec playwright install chromium` fetches the bundled one — at the
29+
version the repo pins, which is also the one `@storybook/test-runner` uses.
30+
2531
- URL of a single story: `http://localhost:6007/iframe.html?id=<story-id>`
2632
- Story IDs: `curl -s localhost:6007/index.json` (`entries`), e.g.
2733
`components-ui-forms-ui-input--signal-forms` (title `Components/ui/forms/ui-input` → kebab).

.github/dependabot.yml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
version: 2
22

33
updates:
4-
# npm : cadence hebdomadaire + regroupement par famille technique. Sans ça,
4+
# L'écosystème s'appelle toujours `npm` chez Dependabot : c'est le nom du
5+
# REGISTRE, pas du client. Il lit `pnpm-lock.yaml` (v9) sous cette clé — il n'y
6+
# a pas d'écosystème `pnpm` à basculer
7+
#
8+
# ⚠️ Interaction avec `minimumReleaseAge: 1440` (pnpm-workspace.yaml) : une PR
9+
# qui propose une version publiée depuis moins de 24 h échoue à l'install
10+
# (« no version satisfies minimumReleaseAge »), puis passe d'elle-même à la
11+
# relance suivante. La cadence hebdomadaire ci-dessous rend le cas peu
12+
# fréquent ; pour un correctif de sécurité à prendre tout de suite, passer par
13+
# `minimumReleaseAgeExclude`.
14+
#
15+
# Cadence hebdomadaire + regroupement par famille technique. Sans ça,
516
# Angular (22.0.x → 22.1.x → ...), Storybook et l'outillage ESLint génèrent
617
# chacun leur propre PR à chaque bump — sur cette stack (Angular 22,
718
# Storybook 10, ng-packagr, Style Dictionary), le bruit ferait abandonner
@@ -22,6 +33,8 @@ updates:
2233
- '@storybook/*'
2334
- '@storybook-community/*'
2435
- 'storybook'
36+
- 'playwright'
37+
- 'axe-playwright'
2538
eslint:
2639
patterns:
2740
- 'eslint*'
@@ -37,6 +50,8 @@ updates:
3750
- '@storybook/*'
3851
- '@storybook-community/*'
3952
- 'storybook'
53+
- 'playwright'
54+
- 'axe-playwright'
4055
- 'eslint*'
4156
- '@eslint/*'
4257
- 'typescript-eslint'

.github/workflows/deploy-pages.yml

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929
name: Build Storybook and demo app
3030
runs-on: ubuntu-latest
3131
steps:
32-
# fetch-depth 0 : `npm run build-storybook` calls `build-info.mjs`, which
32+
# fetch-depth 0 : `pnpm build-storybook` calls `build-info.mjs`, which
3333
# runs `git describe --tags` to find the last published version. A
3434
# shallow checkout (the default) fetches no tags, so the "ahead of
3535
# X.Y.Z" part of the label would silently disappear.
@@ -42,28 +42,34 @@ jobs:
4242
id: nvmrc
4343
run: echo "NODE_VERSION=$(cat .nvmrc)" >> $GITHUB_OUTPUT
4444

45+
# Avant `setup-node` : c'est la présence de `pnpm` sur le PATH qui permet à
46+
# setup-node de localiser le store à mettre en cache. La version installée
47+
# vient du champ `packageManager` du package.json — un seul endroit à bumper.
48+
- name: Install pnpm
49+
uses: pnpm/action-setup@v6
50+
4551
- name: Set up Node.js
4652
uses: actions/setup-node@v7
4753
with:
4854
node-version: ${{ steps.nvmrc.outputs.NODE_VERSION }}
49-
cache: 'npm'
55+
cache: 'pnpm'
5056

5157
- name: Install dependencies
52-
run: npm ci
58+
run: pnpm install --frozen-lockfile
5359

5460
- name: Setup Pages
5561
uses: actions/configure-pages@v6
5662

5763
- name: Build Storybook
58-
run: npm run build-storybook
64+
run: pnpm build-storybook
5965

6066
- name: Fix base href for GitHub Pages
6167
run: |
6268
sed -i -e 's|<head>|<head><base href="'"$PAGES_BASE"'">|' storybook-static/index.html
6369
sed -i -e 's|<head>|<head><base href="'"$PAGES_BASE"'">|' storybook-static/iframe.html
6470
6571
- name: Build demo application
66-
run: npm run build -- --configuration production --base-href "$DEMO_BASE"
72+
run: pnpm build --configuration production --base-href "$DEMO_BASE"
6773

6874
- name: Assemble the Pages artifact
6975
run: |

.github/workflows/pr-checks.yml

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,33 +31,39 @@ jobs:
3131
id: nvmrc
3232
run: echo "NODE_VERSION=$(cat .nvmrc)" >> $GITHUB_OUTPUT
3333

34+
# Avant `setup-node` : c'est la présence de `pnpm` sur le PATH qui permet à
35+
# setup-node de localiser le store à mettre en cache. La version installée
36+
# vient du champ `packageManager` du package.json — un seul endroit à bumper.
37+
- name: Install pnpm
38+
uses: pnpm/action-setup@v6
39+
3440
- name: Set up Node.js
3541
uses: actions/setup-node@v7
3642
with:
3743
node-version: ${{ steps.nvmrc.outputs.NODE_VERSION }}
38-
cache: 'npm'
44+
cache: 'pnpm'
3945

4046
# `postinstall` chains tokens:build → ui-kit:build → docs:config, so this
4147
# step already proves the 53 entry points compile. A failing package build
4248
# fails the install, before any check below runs.
4349
- name: Install dependencies (builds tokens + package)
44-
run: npm ci
50+
run: pnpm install --frozen-lockfile
4551

46-
# `npm run lint` carries --fix: it repairs instead of reporting, so in CI
52+
# `pnpm lint` carries --fix: it repairs instead of reporting, so in CI
4753
# it would never fail. lint:check is the same target without it.
4854
- name: Lint
49-
run: npm run lint:check
55+
run: pnpm lint:check
5056

5157
- name: Typecheck the demo app
52-
run: npx tsc -p tsconfig.app.json --noEmit
58+
run: pnpm exec tsc -p tsconfig.app.json --noEmit
5359

5460
# FSHSP-93: unit tests on the kit (vitest, via the `test` architect
5561
# target). Covers both the pure-logic specs (mask engine, option
5662
# resolver, date helpers, label formatting) and the TestBed component
5763
# specs (select, autocomplete, input-tags, segment-control, tabs, modal,
5864
# accordion, base CVA).
5965
- name: Unit tests
60-
run: npm run test
66+
run: pnpm test
6167

6268
# `postinstall` has just regenerated everything `docs:config` produces, so
6369
# this step looks redundant. It is not — it enforces two things nothing
@@ -72,7 +78,7 @@ jobs:
7278
# - The hand-written component lists, via the `components:check` this
7379
# chains — the six places that claim to describe `projects/ui-kit/`.
7480
- name: Check the docs (lists, conventions, quoted counts)
75-
run: npm run docs:config:check
81+
run: pnpm docs:config:check
7682

7783
# The opposite case, which the step above CANNOT catch: two of those
7884
# generated files are committed — `component-vars.scss` ships in the
@@ -100,17 +106,23 @@ jobs:
100106
id: nvmrc
101107
run: echo "NODE_VERSION=$(cat .nvmrc)" >> $GITHUB_OUTPUT
102108

109+
# Avant `setup-node` : c'est la présence de `pnpm` sur le PATH qui permet à
110+
# setup-node de localiser le store à mettre en cache. La version installée
111+
# vient du champ `packageManager` du package.json — un seul endroit à bumper.
112+
- name: Install pnpm
113+
uses: pnpm/action-setup@v6
114+
103115
- name: Set up Node.js
104116
uses: actions/setup-node@v7
105117
with:
106118
node-version: ${{ steps.nvmrc.outputs.NODE_VERSION }}
107-
cache: 'npm'
119+
cache: 'pnpm'
108120

109121
- name: Install dependencies
110-
run: npm ci
122+
run: pnpm install --frozen-lockfile
111123

112124
- name: Build Storybook
113-
run: npm run build-storybook
125+
run: pnpm build-storybook
114126

115127
# Consumed by the `a11y` job below — avoids rebuilding Storybook twice.
116128
- name: Upload Storybook build
@@ -139,23 +151,41 @@ jobs:
139151
id: nvmrc
140152
run: echo "NODE_VERSION=$(cat .nvmrc)" >> $GITHUB_OUTPUT
141153

154+
# Avant `setup-node` : c'est la présence de `pnpm` sur le PATH qui permet à
155+
# setup-node de localiser le store à mettre en cache. La version installée
156+
# vient du champ `packageManager` du package.json — un seul endroit à bumper.
157+
- name: Install pnpm
158+
uses: pnpm/action-setup@v6
159+
142160
- name: Set up Node.js
143161
uses: actions/setup-node@v7
144162
with:
145163
node-version: ${{ steps.nvmrc.outputs.NODE_VERSION }}
146-
cache: 'npm'
164+
cache: 'pnpm'
147165

148166
- name: Install dependencies
149-
run: npm ci
167+
run: pnpm install --frozen-lockfile
150168

151169
- name: Download Storybook build
152170
uses: actions/download-artifact@v8
153171
with:
154172
name: storybook-static
155173
path: storybook-static
156174

175+
# `playwright` est une devDependency DÉCLARÉE, et doit le rester (FSHSP-177).
176+
# Sous npm cette étape était un `npx playwright install` : npx va chercher le
177+
# paquet sur le registre s'il manque, et npm aplatissait de toute façon le
178+
# binaire transitif dans node_modules/.bin. pnpm ne fait ni l'un ni l'autre —
179+
# `pnpm exec` ne lance QUE ce qui est déclaré.
180+
#
181+
# Ne pas « simplifier » en `pnpm dlx playwright` : dlx tire `latest`, donc les
182+
# navigateurs installés ne correspondraient plus au `playwright-core` que
183+
# `@storybook/test-runner` et `axe-playwright` résolvent, et les tests
184+
# échoueraient sur « Executable doesn't exist » — sans bruit, ce job étant
185+
# `continue-on-error`. Pour la même raison, `playwright` est groupé avec
186+
# `storybook` dans dependabot.yml : les trois doivent bouger ensemble.
157187
- name: Install Playwright's Chromium
158-
run: npx playwright install --with-deps chromium
188+
run: pnpm exec playwright install --with-deps chromium
159189

160190
- name: Run accessibility checks (axe-core via test-runner)
161-
run: npm run test-storybook:ci
191+
run: pnpm test-storybook:ci

0 commit comments

Comments
 (0)