chore(agents): add a machine-wide Playwright browser resource budget

Playwright disables normal background throttling, so a hidden 5chan page keeps
doing P2P and rendering work after a check finishes. Agents verifying in
parallel across worktrees stacked whole browser engines on one machine.

Add scripts/pw-session.sh, a wrapper that permits one active Playwright browser
at a time and records who holds it:

- The lock is machine-wide, not per-repository, because the contended resource
  is RAM and CPU. Every worktree and checkout shares one slot.
- Acquisition is an atomic mkdir. Stale locks clear themselves: `open` reclaims
  any slot whose recorded browser is no longer `status: open` in
  `playwright-cli list --all`, so an interrupted workflow cannot strand the
  budget. When that list cannot be read the lock is left alone, so a broken CLI
  never silently disables the budget.
- `open` exits 75 when the slot is busy; `--wait[=SECONDS]` blocks instead.
- `close` always stops the browser, even when the lock was already lost, and
  never releases a slot held by a different session.
- `status` reports the holder and whether its browser is still alive.

Agent policy now runs browser engines and profiler batches sequentially, uses
Chrome/Blink during iteration and the full engine matrix only for final
verification, and never uses `close-all` or `kill-all` while other agents may
own sessions.

Covered by scripts/pw-session.test.js.
This commit is contained in:
Tommaso Casaburi
2026-08-01 19:21:01 +02:00
parent a67c66de0d
commit 1a33f7dc88
31 changed files with 835 additions and 169 deletions
+11 -3
View File
@@ -15,7 +15,7 @@ Use this skill to jump from a concrete DOM node in the running 5chan app to the
## Quick workflow
1. Open the target route with `playwright-cli`.
1. Open the target route with `./scripts/pw-session.sh` so the shared browser slot is respected.
2. Run `playwright-cli snapshot` and choose the relevant element ref.
3. Resolve that ref through the app helper:
@@ -33,7 +33,7 @@ The result includes:
## Session setup
```bash
playwright-cli -s=inspect open https://5chan.localhost
./scripts/pw-session.sh open inspect https://5chan.localhost
playwright-cli -s=inspect goto https://5chan.localhost/all
playwright-cli -s=inspect eval "window.__ELEMENT_SOURCE__?.ready ?? false"
playwright-cli -s=inspect snapshot
@@ -75,11 +75,17 @@ playwright-cli -s=inspect eval "async el => { const info = await window.__ELEMEN
Use `formattedStack` when you need a short, readable trace for the final report.
Close the session immediately after collecting the needed source evidence, including when resolution fails:
```bash
./scripts/pw-session.sh close inspect
```
## Profiling follow-up
When `$profile-browsing` reports a hot route or rerender-heavy area:
1. Reopen the route in a fresh playwright session.
1. Reopen the route in a fresh Playwright session through `./scripts/pw-session.sh`.
2. Snapshot the concrete list item, card, modal, or toolbar node that looks relevant.
3. Resolve it with `window.__ELEMENT_SOURCE__.resolve(...)`.
4. Use `source.filePath` as the direct edit target and `stack` to understand parent ownership.
@@ -92,3 +98,5 @@ This is a complement to `react-scan`, not a replacement. `react-scan` tells you
- Inspect the actual node the user cares about, not a distant wrapper, unless wrappers are the suspected problem.
- If `source` is null but `stack` exists, use the first useful stack frame rather than guessing.
- If both `source` and `stack` are empty, report that the node could not be resolved and pick a nearby parent element instead.
- If the browser slot is held, retry after the owning workflow finishes or block on `./scripts/pw-session.sh open --wait ...`; do not bypass the lock or use `close-all`/`kill-all`.
- Close the exact named session in a finally-style cleanup.