Skip to content

Update @wordpress/components from 28 to 41 as the base for the design system redesign - #563

Merged
zaerl merged 2 commits into
trunkfrom
update/wordpress-components-41
Sep 30, 2026
Merged

zaerl merged 2 commits into
trunkfrom
update/wordpress-components-41

Conversation

@zaerl

@zaerl zaerl commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Why

The redesign in #542 is built on @wordpress/ui and @wordpress/theme, and both are developed against the current @wordpress/components. The app is on 28, thirteen majors behind, so nothing from the design system can be added until the renderer stands on 41. This is the first step of #542 and changes no behaviour.

What changes

  • @wordpress/components moves from ^28.2.0 to ^41.0.0 and @wordpress/icons from ^10.7.0 to ^17.0.0. React stays on 18.3.1, which both packages support.
  • The edit icon was removed from @wordpress/icons; pencil is the same glyph under its current name.
  • build.files excludes the thirteen packages the update brought into the packaged app. @wordpress/components 41 depends on @wordpress/ui and @wordpress/theme, and @wordpress/theme names esbuild as an optional peer, so npm stopped marking esbuild as dev-only and electron-builder started shipping its binary. None of the thirteen is loaded at run time: the renderer is the esbuild bundle, and nothing under src/ requires them.
  • The sidebar title is kept on one line. Buttons are set in a heavier weight now, and the wider "Collapse" button wrapped "Contributor Toolkit" onto two.
  • Text inputs are now 40px tall instead of 36px. So the buttons are slightly smaller. But they will be removed anyway.

Deliberately not in this PR: adding @wordpress/ui or @wordpress/theme as dependencies of the app, any use of design tokens, and any layout change. Those are the next steps of #542.

How to test this

Platforms: any. Nothing here touches paths, spawning or signing. Use the Buildkite build for the current head of this branch.

The journeys carry the behavior: npm run test:e2e from the repository root drives every flow the renderer has through the updated components, and npm run test:e2e:packaged, after CSC_IDENTITY_AUTO_DISCOVERY=false npm run pack:dir, proves the packaged app still boots without the excluded packages. What they cannot see is how the app looks, so that is what a person should check.

Starting state: the app open with at least one site that has finished setup.

  1. Look at the sidebar. "Contributor Toolkit" is on one line, beside "Collapse".
  2. Click "Collapse", then the arrow to expand again. The sidebar returns to the same layout.
  3. Click the pencil beside the site name. The "Rename site" dialog opens; close it.
  4. Open the menu at the top right of the site. It lists "Copy path", the file manager entry, "Update to latest trunk" and "Delete this site".
  5. Click "Create a site". The dialog shows "Site name", "Contribute to" with two choices, and "Site location"; close it.
  6. Scroll to "Logs" and click each tab. The selected tab is underlined and its content changes.

What must not have happened:

  • No button, field or menu has lost its label or become unreachable.
  • No text is clipped or overlapping where a control grew: text fields are 40px tall instead of 36px, and button labels are heavier.

Risks and limitations

  • The look changes slightly, and that is the design system's doing. Button labels are heavier, text fields are taller, menu items are more compact, and the selected tab is marked in neutral grey and black where it was blue. Details under Screenshots.
  • The docs screenshots are not retaken. The twelve the harness can produce differ slightly from the app after this. Contributor Toolkit WDS redesign #542 retakes all of them, and the harness is not reproducible across runs (Screenshot harness is still not reproducible across a full run #326), so refreshing them here would add churn twice.
  • Checked on macOS only by hand and by local runs. Windows is covered by CI's journeys and packaged smoke, not by a person.
  • The exclusion list is by name. A future update that adds another renderer-only package will ship it until someone adds a line. Excluding the whole renderer-only tree is the real fix and overlaps with Stop shipping build-only deps in the app #23.
  • The first commit of this branch was pushed to trunk by mistake and removed again. trunk is back at 0dc54da; anyone who fetched in between has b6a6151 on their local trunk.
  • Review: 2 [fix here], both fixed; 1 [follow-up] deferred.

Related

Part of #542.
Fixes #548.


Design decisions and alternatives considered

Excluding in build.files rather than moving the renderer's dependencies to devDependencies. Moving them would stop the whole renderer-only tree from shipping, not just what this update added, but that is a change to how the app is packaged and #23 is already about it. This PR only undoes the growth it would otherwise cause.

One jump from 28 to 41 rather than a major at a time. The renderer uses seventeen components, all of which still exist with the same props. The only break was the removed icon alias, which fails the build rather than the app.

Review outcome (required — see AGENTS.md)

2 [fix here] · 1 [follow-up] — both [fix here] fixed.

  • Architecture, medium, [fix here], fixed: the packaged app shipped the esbuild binary, because @wordpress/theme names esbuild as an optional peer and electron-builder collects optional packages.
  • Performance, medium, [fix here], fixed: twelve more packages the update added were collected into the app and never loaded.
  • Performance, low, [follow-up], deferred: the whole renderer dependency tree ships although only the bundle is loaded. It predates this branch and is the subject of Stop shipping build-only deps in the app #23.

Style notes, not applied: with white-space: nowrap the sidebar title can paint outside the sidebar during the 200ms expand animation; the esbuild@0.23.1 entry in allowScripts has been stale since #538.

  • Review: completed — fresh agent context, local, before the PR existed; head b6a6151 / base 0dc54da; committed work only, working tree clean; outcome above. CodeRabbit: not run yet.
  • Since review: b6a6151 → 4b2d52e checked. The difference is the thirteen exclusion lines in build.files that fix the two findings. It was not reviewed again by a fresh context; it was verified by packaging and running the packaged smoke test.

Checks on 4b2d52e, macOS, local:

Check Result
npm run lint clean
npm test 1676 tests, 1674 pass, 2 skipped, 0 fail
npm run test:electron 1676 pass, 0 fail
npm run test:e2e 33 of 33 pass
npm run test:e2e:packaged 15 of 15 pass

Lint, the unit tests and the journeys ran on b6a6151; the second commit changes build.files only, which none of the three reads.

Implementation notes

app.asar on macOS arm64, unsigned, npm run pack:dir:

State Size
After the update, before the exclusions 238,010,661 bytes
With the exclusions 199,873,553 bytes

The size on trunk was not measured.

Packages excluded: esbuild, @esbuild/*, @base-ui/*, @date-fns/*, @daypicker/*, react-day-picker, reselect, tabbable, colorjs.io, @wordpress/base-styles, @wordpress/kebab-case, @wordpress/style-runtime, @wordpress/ui. The list is the difference between the two lockfiles in what is not marked dev-only.

@wordpress/components 41 injects part of its CSS at run time through @wordpress/style-runtime. The renderer's content security policy already allows it (style-src 'self' 'unsafe-inline').

Screenshots or recording

No images attached. The comparison was made between the committed docs screenshots and the same twelve shots captured on this branch with npm run shots. What differs:

  • Button labels are set in weight 500.
  • Text fields are 40px tall instead of 36px.
  • Menu items are more compact.
  • In "Logs", the selected tab has black text and a grey underline; it was blue.
  • The sidebar title wrapped onto two lines before the fix in this PR, and is on one line with it.

🤖 Generated with Claude Code

zaerl and others added 2 commits September 29, 2026 17:07
…10 to 17

First step of the WordPress Design System redesign (#542): @wordpress/ui
and @wordpress/theme are built against the current components release,
so the renderer has to stand on it before either can be added.

The `edit` icon no longer exists in @wordpress/icons 17; `pencil` is the
same glyph under its current name.

The sidebar title is kept on one line: buttons are set in a heavier
weight now, and the wider "Collapse" button wrapped "Contributor
Toolkit" onto two lines.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…d app

@wordpress/components 41 depends on @wordpress/ui and @wordpress/theme,
and @wordpress/theme names esbuild as an optional peer. npm therefore
stopped marking esbuild as dev-only, and electron-builder, which
collects optional packages, started shipping its binary along with
twelve other packages the update added.

None of them is loaded at run time: the renderer is the esbuild bundle,
and nothing under src/ requires them.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 29, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository: WordPress/contributor-toolkit/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 6025038c-a5f3-43dc-a326-2d3b5010a662

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@zaerl
zaerl merged commit f6930f3 into trunk Sep 30, 2026
8 checks passed
@zaerl
zaerl deleted the update/wordpress-components-41 branch September 30, 2026 07:28
zaerl added a commit that referenced this pull request Sep 30, 2026
…ns at the renderer's root (#564)

## Why

The redesign in #542 styles the app with the WordPress Design System's
tokens and builds its new screens from `@wordpress/ui`. Neither is
available to the renderer yet: the tokens stylesheet is not loaded, so a
`var(--wpds-…)` written in the app resolves to nothing, and there is no
provider to set colour or corner radius from. This is the second step of
#542, after #563.

## What changes

- `@wordpress/theme` and `@wordpress/ui` become dependencies of the app.
Both were already installed through `@wordpress/components` 41, so no
package is new to the tree.
- The renderer imports `@wordpress/theme/design-tokens.css` and mounts
inside `<ThemeProvider isRoot>` at its defaults. `isRoot` is what lets a
later override reach a modal or a popover, which are portalled to
`body`, outside the provider's tree.
- The next-action live region uses `VisuallyHidden` from
`@wordpress/ui`, and the hand-written `.sr-only` rule is removed. This
is the one use of `@wordpress/ui`, and it is here on purpose: the
package adds its styles to the document at run time, and this makes that
path run in the app and not only in the bundle.
- `@wordpress/theme` joins the packages kept out of the packaged app. It
is hoisted to the top of `node_modules` now that the app depends on it,
where the exclusion of `@wordpress/ui` from #563 no longer covers it.

Deliberately not in this PR: any colour or corner radius set on the
provider, any use of a token in the app's own styles, any new
`@wordpress/ui` component. The 333 hardcoded colours stay where they are
until their own step.

## How to test this

Platforms: any. Use the Buildkite build for the current head of this
branch.

The launch journey carries this. `npx playwright test --project=journeys
-g "launches from source"`, from the repository root, asserts that a
token resolves, that the provider's wrapper and the live region have the
styles added at run time, and that the app rendered inside the provider.
It is red without the tokens import, red without `'unsafe-inline'` in
the window's style policy, red when the app renders nothing, and red
when the live region is a plain element; each was checked by breaking
it.

What the journey cannot reach is how it looks and how it sounds:

**Starting state:** the app open with at least one site that has
finished setup and whose dev server is stopped.

1. Look at "Start dev server" and "Create a site". The labels are
readable on the blue; they are very slightly off-white, not pure white.
2. Press Tab until a button has the focus ring. The ring is visible and
thinner than before on a high-density screen.
3. Collapse and expand the sidebar, open "Create a site", open the
site's menu. The layout is as it was.
4. With a screen reader running, open the site. It announces "Next
step:" followed by the step.

**What must not have happened:**

- No text reading "Next step: …" is visible anywhere on the page.
- The window has not lost its full-height layout: the sidebar still
reaches the bottom.

## Risks and limitations

- **Two things change on screen, and only two.** With the tokens
defined, the components stop using fallbacks that only approximated
them: a primary button's label is `#eff0f2` rather than `#fff`, and the
focus ring is 1.5px rather than 2px on a high-density screen. The second
is read from the stylesheet; the screenshots are captured at 1x and
cannot show it.
- **The screen reader was not tried.** The live region keeps its role,
its `aria-live` and its text, all asserted by the journey, but nobody
listened to it.
- **Checked on macOS only by hand and by local runs.** Windows is
covered by CI's journeys and packaged smoke.
- **The renderer bundle grows** by about 179 KB of JavaScript and 10 KB
of CSS. The packaged app does not: 199,750,409 bytes of `app.asar`
against 199,873,553 before.
- Review: 3 [fix here], all low and all in the tests, all fixed.

## Related

Closes #549

Part of #542. Follows #563.

---

<details>
<summary>Design decisions and alternatives considered</summary>

**The provider at its defaults, not at the prototype's settings.** The
prototype sets `cornerRadius="moderate"` and its own colour seeds.
Setting them here would round every existing control while the rest of
the app still has the old layout. They belong with the shell.

**One real use of `@wordpress/ui` rather than none.** Declaring the
dependency with nothing importing it would have left its run-time styles
untested until the first screen built on them. `VisuallyHidden` replaces
a rule the app had written by hand, changes nothing on screen, and is
enough to show that the window's content security policy lets those
styles in.

**No build plugin for token fallbacks.** `@wordpress/theme` ships an
esbuild plugin that writes a fallback into every `var(--wpds-…)`. The
app loads the tokens stylesheet itself, in the one document it has, so
there is nothing for a fallback to cover.

</details>

<details>
<summary>Review outcome (required — see AGENTS.md)</summary>

**3 [fix here] · 0 [follow-up]** — all 3 fixed.

- Tests, low, [fix here], fixed: `#root > *` in the launch journey and
the packaged smoke test was the proof that the app painted; the provider
is now always that child, so it passed with nothing inside. Both look at
`#root > * > *`.
- Tests, low, [fix here], fixed: the live region was found by
`[data-visually-hidden]`, which `@wordpress/components` also puts on its
own hidden text with inline styles, so the first match could pass with
no injected style. It is found by role and by what it says, and its
`aria-live` is asserted.
- Tests, low, [fix here], fixed: the design system's checks were a test
of their own and cost an app launch on every pull request. They moved
into the launch test.

Style note, applied: a comment said the tokens import had to come before
the components' stylesheet. The order does not matter.

- **Review:** completed — fresh agent context, local, before the PR
existed; head 47b8827 / base
f6930f3; committed work only, working
tree clean; outcome above. CodeRabbit: not run yet.
- **Since review:** `47b8827 → 6fdf0d0` checked. The difference is the
three fixes and the comment. It was not reviewed again by a fresh
context; it was verified by the runs below and by breaking each
assertion in turn.

Checks on 6fdf0d0, macOS, local:

| Check | Result |
|---|---|
| `npm run lint` | clean |
| `npm test` | 1674 pass, 2 skipped, 0 fail |
| `npm run test:electron` | 1676 pass, 0 fail |
| `npm run test:e2e` | 33 of 33 pass |
| `npm run test:e2e:packaged` | 15 of 15 pass |

</details>

<details>
<summary>Implementation notes</summary>

`ThemeProvider` renders a wrapper `<div>` with `display: contents`, so
it takes no part in the layout. That rule, like every style in
`@wordpress/theme` and `@wordpress/ui`, is added to the document as a
`<style>` element when the module loads. The window's policy is
`style-src 'self' 'unsafe-inline'`, which allows it; the journey is what
notices if that ever changes.

How the two on-screen changes were found: every `var(--wpds-…,
fallback)` in the components' stylesheet was compared with the value the
tokens stylesheet now gives it. 50 of 57 pairs are equal, 3 fall back to
a variable holding the same value, and 3 only differ under a corner
radius preset the provider does not set. The remaining one is the
primary button's label colour. The focus ring's 1.5px comes from a media
query for high-density screens in the tokens stylesheet.

</details>

<details>
<summary>Screenshots or recording</summary>

No images attached. The twelve shots `npm run shots` captures were taken
on `trunk` and on this branch and compared pixel by pixel. Six are
identical. Four differ only on primary buttons, by at most 16 levels per
channel, which is the label colour above. The last two, `site-menu` and
`gutenberg-site-view`, also differ between two runs on `trunk`, so they
show nothing either way.

</details>

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
@zaerl zaerl self-assigned this Oct 1, 2026
@ryanwelcher ryanwelcher mentioned this pull request Oct 1, 2026
@zaerl zaerl added this to the v2.0.0 milestone Oct 7, 2026
zaerl added a commit that referenced this pull request Oct 23, 2026
…braries and Chromium locales (#707)

## Why

The packaged app is about 920 MB on disk on macOS (320 MB zipped), and
about a third of that is code it never loads. That is a long download on
a Contributor Day network, where everyone fetches the app at the same
time. It is the same problem #23 reported. That PR has since gone stale
against trunk, and its claim that `@xterm/xterm` is unused no longer
holds, so this branch starts again from trunk.

## What changes

Three things the app ships and never loads are left out:

- **The asyncify PHP builds, about 220 MB.** Each `@php-wasm/node-*`
package carries every PHP version twice, as `jspi/` and as `asyncify/`,
and `@php-wasm/node` reads `asyncify/` only when `"Suspending" in
WebAssembly` is false. Electron 43.6.0 has JSPI, so those folders never
load. `@php-wasm/node-5-2` goes too, because the app offers only
`SupportedPHPVersions` (7.4–8.5). Both are `build.files` exclusions;
`node_modules` is untouched.
- **The renderer's libraries, about 95 MB in `app.asar`.** esbuild
already bundles React, Emotion, xterm and the `@wordpress` UI packages
into `src/renderer/index.js`, but they were listed in `dependencies`, so
electron-builder copied their trees in as well. They move to
`devDependencies`. `@wordpress/i18n` and `@wordpress/hooks` stay,
because the main process loads them. The 22 hand-kept `build.files`
exclusions that trimmed part of that tree since #563 are now unnecessary
and are removed.
- **Chromium's locales for languages the app has no catalog for, about
43 MB.** The app shows English for those anyway, so
`build.electronLanguages` keeps English and the Chromium locale of each
catalog in `src/languages`. **`npm run i18n:download` now writes that
list** whenever it adds or removes a catalog, so the version-bump PR
carries the change with no manual step. `scripts/chromium-locales.cjs`
maps a catalog to the locale Chromium itself would load, including
Chromium's regional folding (`es-mx` → `es-419`, `pt` → `pt-PT`, `zh-hk`
→ `zh-TW`, `en-ca` → `en-GB`). Every regional locale is written in both
spellings, `pt-BR` for Windows and Linux and `pt_BR` for macOS, because
electron-builder matches file names.

Unit tests guard the cuts:

- `electron-wasm-jspi` asks the bundled Electron for
`WebAssembly.Suspending`, so an Electron bump that loses JSPI fails CI
instead of the first dev server start.
- `electron-languages` asserts that the list equals the one the catalogs
call for, which catches both a missing entry and a stale one. It also
checks that electron-builder keeps every locale file the list names.
- `chromium-locales` covers the mapping with both platforms' locale
names.
- `php-builds` fails when an installed `@php-wasm/node-X-Y` whose
version `SupportedPHPVersions` does not offer would ship, and when a
version the settings offer is excluded.

Run against translate.wordpress.org today, the script adds `sr` and `tr`
for two catalogs that are above the cut-off but not yet in the
repository, and leaves out `lo`, which Chromium has no locale for.

Not in this PR: dropping PHP versions the settings offer (a product
decision since #559), and the `intl` extension and ICU data, which
core's tests use.

| macOS arm64, unsigned, same `node_modules` | trunk | this branch |
|---|---|---|
| `.app` on disk | 920 MB | **571 MB** |
| zipped | 320 MB | **218 MB** |
| `app.asar` | 205 MB | 108 MB |
| `app.asar.unpacked` | 436 MB | 228 MB |
| Electron Framework | 277 MB | 234 MB |

## How to test this

Platforms: macOS and Windows, both needed, because the PHP runtime is
chosen when the server starts and no CI job starts the real Playground
server (see the Electron pin note in AGENTS.md). Use the Buildkite
artifact for the current head commit.

**Starting state:** the app from this branch's Buildkite build, with a
site that has finished setup and whose server is stopped.

1. Open the site and click **Start development server**. The server
comes up, and the site's front page and `/wp-admin/` both load in the
browser.
2. Open the app's log for that site. It has no `Cannot find module`
error, and no path containing `asyncify`.
3. In the settings, change the PHP version to 7.4, then start the server
again. The site loads, and the log names PHP 7.4.
4. Use the app as usual: the site list, the terminal (xterm), the
changed files, a dialog. Everything draws as before. The renderer no
longer reaches `node_modules` for any of it.
5. On macOS, compare the size of the app with a trunk build in Finder
(Get Info): about 570 MB against about 920 MB.

**What must not have happened:**

- The dev server failing to start, or starting on a PHP version other
than the one chosen.
- A blank or unstyled window, which would mean the renderer still needed
a package that is no longer shipped.
- Native form strings, such as a validation bubble, in a different
language from before for cs, hu, nl, pl or English.

## Risks and limitations

- The asyncify cut depends on Electron keeping JSPI. That is what
`electron-wasm-jspi` guards.
- On macOS, electron-builder also removes the grammatical-gender
overlays (`cs_FEMININE.lproj` and similar) for the kept languages; each
holds an 18-byte `locale.pak`. Chromium should fall back to the base
locale, but I have not checked a macOS user with a grammatical gender
set.
- `electron-languages` copies electron-builder's matching rule, because
it is not exported. An electron-builder release that changes that rule
would not be caught.
- Chromium's regional folding rules in `scripts/chromium-locales.cjs`
follow `CheckAndResolveLocale` in Chromium's `l10n_util.cc`, but no
Chromium source is vendored here to check them against. Only `en-ca` →
`en-GB` affects today's list, and `en-GB` is kept for `en-gb` anyway.
- `npm run i18n:download` now needs an installed Electron, which it
downloads on first use. It reads Electron's locales before changing any
catalog, so a failed download leaves everything as it was.
- The packaged smoke suite passed locally only with `--user-data-dir`
added to its launch, because a dev copy of the app held the
single-instance lock. Trunk's build failed the same way without it. CI's
run on this PR is the unmodified one.
- Review: one completed fresh-context review, 0 findings; details below.

## Related

- Fixes #703: the `asyncify/` folder of every PHP build is left out,
which is the exclusion the issue proposes, and `electron-wasm-jspi`
guards the JSPI it depends on.
- Fixes #704: `@php-wasm/node-5-2`, the only installed build whose
version `SupportedPHPVersions` does not report, is left out.
`php-builds` fails when a Playground update changes which builds those
are, and names the exclusion to add or remove.
- Fixes #705: `build.electronLanguages` keeps only English and the
Chromium locales of the app's catalogs, and `npm run i18n:download`
keeps it in step.
- Follow-up to #23, which reported the renderer-library half. That PR
belongs to its author and is left as it is.

---

<details>
<summary>Design decisions and alternatives considered</summary>

- **Exclusions in `build.files`, not a `postinstall` prune.**
`node_modules` stays complete for development, the tests and the
journeys. Only what electron-builder copies changes.
- **`devDependencies` rather than more `!node_modules/...` lines.** The
exclusion list from #563 had to grow every time a `@wordpress` package
gained a dependency. Moving the cause leaves nothing to maintain, and
lets 22 lines go.
- **A hand-written `electronLanguages` list with a test, rather than one
generated at build time.** A generated list would need a JS build config
or a hook; a static list plus a test that names the missing entry is
simpler, and changes only when a catalog is added.
- **Chromium locales for the app's catalogs only.** Keeping a broader
set would leave Chromium's strings in, say, Italian around an English
app, which is no better than English.

</details>

<details>
<summary>Review outcome (required — see AGENTS.md)</summary>

0 [fix here] · 0 [follow-up]. One style note was applied: the
`electron-languages` header claimed Chromium's strings follow the app's
language, but they follow the operating system's.

- **Review:** completed. Reviewer: a separate Claude agent context,
given only the diff and
`.github/instructions/code-review.instructions.md`. Reviewed head
`a7be033` against base `2dda92c` (`origin/trunk`). Evidence: `npm run
lint` passed; `npm test` passed with 2202 tests, 2200 pass, 0 fail, 2
skipped; `npm run test:electron` passed with 2202 tests, 2201 pass, 0
fail, 1 skipped. The five dimensions found nothing. Specifically
checked: no main-process, preload or runner import of a moved package;
no production dependency still reaching a formerly excluded package;
asyncify reached only when JSPI is absent, including for intl and
xdebug; PHP 5.2 unreachable from the settings; electronLanguages against
electron-builder's matching rule and the app's locale resolution.
- **Since review:** `a7be033 → 7ac9e25` checked. The only change is the
comment wording in `tests/unit/electron-languages.test.cjs`, and that
test still passes.
- **Since review:** `7ac9e25 → 8e1d005`, a CI fix, re-checked by the
author against the same standard: 0 findings. CI's unit job failed
because Electron 43's npm package downloads its binary on the first
`require('electron')`, and three test files now asked for it at the same
moment. I reproduced that locally by removing
`node_modules/electron/dist`: two downloads ran and two tests failed. A
`pretest` script now asks once before `node --test` starts, and the
workflow comment that said `npm ci` fetches Electron is corrected. Run
from a missing binary, `npm test` downloads once and passes 2200 tests
with 0 failures, and `npm run test:electron` and `npm run lint` pass
too.
- **Review of `8e1d005 → dde0f94`** (the `i18n:download` change):
completed by a separate Claude agent context against the same standard,
in the context of `origin/trunk...dde0f94`. Result: 1 [fix here] · 0
[follow-up], fixed in `26e9250`. The finding: Electron's locale names
were read after the catalogs had been replaced, so a failed Electron
download would leave the run half applied. They are now read before
anything is written. One style note was applied as well, a test title
that claimed more than it asserted. The reviewer also ran about 130
slugs through the mapping without a crash, and checked that rewriting
`package.json` reproduces the file byte for byte. Lint passes, and `npm
test` and `npm run test:electron` each pass 2212 tests with 0 failures.
- **Since that review:** `dde0f94 → 26e9250`. Only that fix and the
renamed test changed; the suites above ran on `26e9250`.
- **Since that review:** `26e9250 → 55ab855` adds only
`tests/unit/php-builds.test.cjs`, for #704. I checked it against the
standard myself: 0 findings. Broken both ways in turn (5.2 kept, 8.3
excluded), it fails each time, and it passes as committed. `npm test`
and `npm run test:electron` each pass 2214 tests with 0 failures.
- **CodeRabbit:** not requested yet.

</details>

<details>
<summary>Implementation notes</summary>

- Sizes come from `electron-builder --dir` with `-c.mac.identity=null
-c.mac.notarize=false`, run twice from the same `node_modules` with
trunk's and this branch's `package.json` and lockfile, then zipped with
`ditto -c -k`. Signed artifacts will differ slightly.
- Locally, from the trimmed package, `@php-wasm/node` booted PHP 7.4.33,
8.3.33 and 8.5.10 with `intl` loaded, run on the packaged binary with
`ELECTRON_RUN_AS_NODE=1`.
- `npm run test:e2e:packaged` passed all 15 tests on the trimmed build,
including the first window painting, the preload bridge, and the
`build.files` allow-list checks.
- In the lockfile, the moved packages and their trees change from
`devOptional` to `dev`. No versions change.
- `pretest` runs `node -e "require('electron')"`. The electron package
downloads its binary on the first `require`, so this fetches it once
before `node --test` runs its files in parallel, where concurrent
downloads raced. `npm run test:electron` already did this in its runner,
and a single file run with `node --test <file>` has nothing to race
with.
- The asyncify choice is made in `@php-wasm/node/index.cjs`
(`loadNodeRuntime`) and in each `@php-wasm/node-X-Y/index.cjs`
(`getPHPLoaderModule` and the extension paths).

</details>

<details>
<summary>Screenshots or recording</summary>

Nothing on screen changes.

</details>

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bump @wordpress/components to 41 and icons to 17

1 participant