Fresh userData サンドボックス(開発用)
初回起動フロー(Onboarding / プロファイル新規作成 / ブラウザ自動化のログイン)を、既存の %APPDATA%/broadcast-Overlay/ を破壊せずに 試すための開発ツール。
仕様: .spec-workflow/specs/dev-fresh-userdata-sandbox/
TL;DR
# 既存 DB / 設定を一切触らずに「初回起動状態」のアプリを開く
yarn dev:electron:fresh
# 念のため起動前に既存 userData を snapshot に取っておく
yarn dev:electron:fresh --snapshot
# 既存 matches.db だけは引き継いで Onboarding を試す
yarn dev:electron:fresh --seed-from-current終了時にサンドボックス(%TEMP%/broadcast-Overlay-sandbox-<ts>/)は自動削除されます。%APPDATA%/broadcast-Overlay/ は 絶対に変更されません。
なぜ必要か
通常の yarn dev:electron は %APPDATA%/broadcast-Overlay/ を userData として開くため:
- 一度プロファイルや UID を設定すると、次回起動時もそれが残る → 「初回起動」を再現できない
- ブラウザ自動化で一度ログインすると Cookie が残る → 「未ログイン状態」を試せない
- 開発中に Onboarding ダイアログを変更しても、自分の環境では一度しか出ないので確認が面倒
Fresh モードは Electron 起動時の userData パスを別ディレクトリに切り替えるだけのシンプルな仕組みで、これらすべてを解決します。
仕組み
electron/main.ts の ELECTRON_USER_DATA 環境変数 (E2E 用に既に存在) を流用します:
yarn dev:electron:freshを実行- ラッパースクリプト(
scripts/dev/fresh-userdata.ts)が%TEMP%/broadcast-Overlay-sandbox-<ts>/を作成 ELECTRON_USER_DATA=<sandbox path>を立ててyarn dev:electronを子プロセスとして起動- Electron が
ELECTRON_USER_DATAを見て userData を sandbox に差し替え - すべての DB / 設定 / Cookie / storageState は sandbox 配下に書かれる
- アプリ終了時にラッパーが sandbox を削除
E2E (tests/e2e/helpers/withTempUserData.ts) と 同じ仕組み を共有しています。
コマンド早見表
| コマンド | 用途 |
|---|---|
yarn dev:electron:fresh | 空 userData で起動 → 終了で sandbox 削除 |
yarn dev:electron:fresh --keep-sandbox | 終了後に sandbox を残す(中身を覗きたいとき) |
yarn dev:electron:fresh --user-data <abs-path> | sandbox の場所を明示指定 |
yarn dev:electron:fresh --snapshot | 起動前に既存 userData を snapshot |
yarn dev:electron:fresh --seed-from-current | 既存 matches.db のみ sandbox に copy |
yarn dev:electron:fresh --seed-from <db-path> | 任意 db を sandbox に copy |
yarn dev:userdata:snapshot --comment "<text>" | snapshot を手動作成 |
yarn dev:userdata:list | snapshot 一覧(timestamp / size / コメント) |
yarn dev:userdata:restore <timestamp> [--force] | snapshot を %APPDATA%/broadcast-Overlay/ に復元 |
Snapshot の場所と運用
- 保存先:
%APPDATA%/broadcast-Overlay.snapshots/<timestamp>/ - 取得方法: コピー(リネームではない)→ 既存 userData は物理的に無傷
- 取得後は
attrib +R /S /Dで 読み取り専用属性 が立つ → 誤上書き防止 - timestamp が衝突する場合(同一秒に 2 回取った等)は エラー終了(自動上書きしない)
- 古い snapshot は手動削除(
Remove-Item -Recurse -Force、必要なら先にattrib -R /S /D)
ユースケース別の使い方
1. Onboarding ダイアログを試したい
yarn dev:electron:fresh空 userData なので、初回起動時のフローがそのまま走る。
2. 既存設定を絶対に守りたい(念押し snapshot 付き)
yarn dev:userdata:snapshot --comment "before testing X"
yarn dev:electron:fresh万が一 %APPDATA%/broadcast-Overlay/ が壊れても snapshot から戻せる:
yarn dev:userdata:list
yarn dev:userdata:restore 2026-05-07T08-30-00-000Z --force3. 過去の試合データだけ引き継いで「初回プロファイル設定後の状態」を試す
yarn dev:electron:fresh --seed-from-current- DB だけ既存内容
- localStorage / config.json / Cookie は空
- → 「Onboarding 完了 → ダッシュボードに過去データが出る」フローを試せる
4. ブラウザ自動化の未ログイン状態を試す
yarn dev:electron:freshsandbox 内で起動したブラウザ自動化は <sandbox>/browser-automation/storageState.json に Cookie を書く。本番 userData の Cookie には絶対影響しない(electron/ipc/BrowserAutomationHandlers.ts:118 で app.getPath('userData') 配下に閉じる構造)。
複数の dev 起動を並べる(vite のポート・CDP)
yarn dev:electron(と :viewer / :fresh)は、vite のポートを VITE_PORT から読みます(既定 3000)。 scripts/dev/run-electron.cjs --wait-vite がそのポートの vite を待ってから electron を起動し、窓が読む ELECTRON_DEV_URL も同じポートに合わせます。WINGSTATS_CDP_PORT を付けると electron に --remote-debugging-port を渡すので、管理画面・オーバーレイ窓を CDP(http://127.0.0.1:<port>/json/list)で操作・確認できます。
複数のエージェントや人の本番アプリと並べるときは、次の 5 つを全部ずらします。
| env | 役割 | 既定 |
|---|---|---|
VITE_PORT | vite の dev server(wait-on と ELECTRON_DEV_URL も追従) | 3000 |
WINGSTATS_CDP_PORT | 管理画面・オーバーレイ窓の CDP | なし(開かない) |
ELECTRON_USER_DATA | userData(DB・設定・ロック)。本番の userData に書かないため必須 | %APPDATA% 配下 |
WINGSTATS_LIVE_WS_PORT | Manager⇔Recorder の操作用 WS | 47831 |
WINGSTATS_OBS_HTTP_PORT | OBS ブラウザソースの配信 | 47832 |
# 例: 別のポートと空の userData で起動する(bash)
VITE_PORT=3106 WINGSTATS_CDP_PORT=9306 WINGSTATS_LIVE_WS_PORT=48151 WINGSTATS_OBS_HTTP_PORT=48152 \
yarn dev:electron:fresh --user-data 'C:/tmp/sandbox-a' --keep-sandbox
# 管理画面で式を評価する(Runtime.evaluate)
curl -s http://127.0.0.1:9306/json/list # control.html / overlay.html の webSocketDebuggerUrl が出るPlaywright なら chromium.connectOverCDP('http://127.0.0.1:9306') で control.html のページを掴めます。 Manager が自動で起動する Recorder は run-electron.cjs を通らないので CDP は付きません(窓も無い)。 ELECTRON_USER_DATA 以外の env は Recorder にも引き継がれます。
注意:
- エージェント配下の起動は窓が画面外に出ます(バックグラウンド窓モード)。画面外の窓は Windows に「見えていない」と 判定され、renderer が背景扱い(優先度 Idle・
document.hidden)になって、PC が混んでいると CDP の評価が何十秒も 返りませんでした。このモードでは--disable-renderer-backgrounding/--disable-backgrounding-occluded-windowsを 付けて背景扱いを止めています(electron/main/backgroundWindows.ts)。人が起動したときは付きません - 終了は自分が起動した
electron.exeだけを止めます(コマンドラインの worktree パスで絞る)。止めたプロセスは後始末に 20 秒前後かかることがあり、その間はポートが空かず、すぐ起動し直すとEADDRINUSE/ CDP が開かない状態になります。 ポートが空いたのを確かめてから起動し直してください - 初回は vite の依存の事前バンドルで、ページが読まれるまで数十秒かかることがあります
トラブルシュート
sandbox が削除されない
--keep-sandbox 指定なしで終了したのに %TEMP%/broadcast-Overlay-sandbox-*/ が残る場合、ファイルが他プロセスに掴まれていた可能性。手動削除:
Get-ChildItem $env:TEMP -Filter 'broadcast-Overlay-sandbox-*' | Remove-Item -Recurse -ForceOS のテンポラリクリーンアップでも数日内に消えます。
snapshot 取得が遅い / サイズが大きい
%APPDATA%/broadcast-Overlay/ 配下に大量の試合 detail JSON が溜まっている可能性。responses/ 等のキャッシュ系ディレクトリは sandbox では不要なので、snapshot の保管先を別ドライブに変えるのが楽(自動化はしていない)。
snapshot の ReadOnly 属性で開けない
Windows Explorer で snapshot ファイルを直接編集したいときは:
attrib -R /S /D "%APPDATA%\broadcast-Overlay.snapshots\<ts>\*"または yarn dev:userdata:restore <ts> で復元してから編集する。
dev:electron と dev:electron:fresh を同時起動できる?
できます。userData が別パスなので競合しません。vite のポート(既定 3000)とアプリが開くポートは重なるので、 片方に VITE_PORT などを付けて別ポートにしてください(次の「複数の dev 起動を並べる」)。
関連
docs/operations/fresh-install-testing.md— 初回起動を実 exe で自動検証する smoke ハーネス(本ツールの自動化版。--manualで packaged 版の手動確認もできる).spec-workflow/specs/dev-fresh-userdata-sandbox/— spectests/e2e/helpers/withTempUserData.ts— E2E が使う同じ機構electron/main.ts—ELECTRON_USER_DATAの読み取り箇所