## Summary
- Send a serializable Live2D expression snapshot from the stage renderer
to the separate Settings window.
- Route expression changes back to the renderer that owns the loaded
model, with owner ID checks for stale-window isolation.
- Add browser regressions for the component boundary and the complete
BroadcastChannel round trip.
Fixes#2450
## Verification
- `pnpm typecheck`
- `pnpm lint`
- `../../node_modules/.bin/vitest run --project browser
src/components/scenarios/settings/model-settings/live2d.browser.test.ts`
- `node_modules/.bin/vitest run --config
apps/stage-tamagotchi/vitest.config.ts --project browser
apps/stage-tamagotchi/src/renderer/composables/model-settings-runtime.browser.test.ts`
- `./node_modules/.bin/electron-vite build`
- Vishot Electron capture with the issue Live2D fixture on the merge
base and this branch
- `sem diff upstream/main...HEAD --no-cosmetics -v --file-exts .ts .tsx`
## Visual changes
| Before | After |
|---|---|
|

|

|
| Settings / Models / Live2D expressions: empty list | Settings / Models
/ Live2D expressions: model entries are available |
## Description
Let `dev` and `start` scripts run `install-electron` before
`electron-vite`.
Electron 42 removed the `postinstall` script. The `electron` package now
downloads its binary on its `bin` entry's first run. `electron-vite`
reads `node_modules/electron/path.txt` directly, so it never starts that
download. A fresh install therefore fails with:
```
error during start dev server and electron app:
Error: Electron uninstall
at getElectronPath (...)
...
```
`install-electron` runs the same code as the removed `postinstall`
script. It returns immediately when the binary is already present.