mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
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:
@@ -26,17 +26,25 @@ Do not start, restart, or stop the dev server yourself. If the app is unreachabl
|
||||
|
||||
Default to a fresh isolated `playwright-cli` browser session. If the requested verification depends on auth, cookies, extensions, open tabs, or other existing browser state and the parent agent did not specify session mode, stop and ask whether to use a fresh browser or the contributor's current browser session.
|
||||
|
||||
### Step 2: Navigate and Snapshot
|
||||
### Step 2: Navigate and Snapshot Sequentially
|
||||
|
||||
Use playwright-cli to check the relevant page in all three browser engines with separate sessions:
|
||||
Choose short task-specific session names. Use the shared wrapper to check the relevant page in all three browser engines one at a time:
|
||||
|
||||
```bash
|
||||
playwright-cli -s=verify-chrome open https://5chan.localhost --browser=chrome
|
||||
playwright-cli -s=verify-firefox open https://5chan.localhost --browser=firefox
|
||||
playwright-cli -s=verify-webkit open https://5chan.localhost --browser=webkit
|
||||
./scripts/pw-session.sh open verify-chrome https://5chan.localhost --browser=chrome
|
||||
# Complete the Chrome desktop/mobile flow.
|
||||
./scripts/pw-session.sh close verify-chrome
|
||||
|
||||
./scripts/pw-session.sh open verify-firefox https://5chan.localhost --browser=firefox
|
||||
# Complete the Firefox desktop/mobile flow.
|
||||
./scripts/pw-session.sh close verify-firefox
|
||||
|
||||
./scripts/pw-session.sh open verify-webkit https://5chan.localhost --browser=webkit
|
||||
# Complete the WebKit desktop/mobile flow.
|
||||
./scripts/pw-session.sh close verify-webkit
|
||||
```
|
||||
|
||||
Navigate each engine session to the specific page/route where the change should be visible.
|
||||
Navigate the current engine session to the specific page/route where the change should be visible. Always close that session in a finally-style cleanup, even when a check fails, before opening the next engine. If the wrapper exits 75 the slot is busy: retry with `./scripts/pw-session.sh open --wait <session> ...`, or report it to the parent so the check can be rescheduled. Never bypass the lock.
|
||||
|
||||
### Step 3: Verify the Changes
|
||||
|
||||
@@ -49,14 +57,12 @@ Based on what the parent agent asked you to check:
|
||||
- Check mobile viewport in each engine if the change is layout-related:
|
||||
|
||||
```bash
|
||||
playwright-cli -s=verify-chrome resize 375 812
|
||||
playwright-cli -s=verify-chrome snapshot
|
||||
playwright-cli -s=verify-firefox resize 375 812
|
||||
playwright-cli -s=verify-firefox snapshot
|
||||
playwright-cli -s=verify-webkit resize 375 812
|
||||
playwright-cli -s=verify-webkit snapshot
|
||||
playwright-cli -s=SESSION resize 375 812
|
||||
playwright-cli -s=SESSION snapshot
|
||||
```
|
||||
|
||||
Replace `SESSION` with the currently open engine session. Finish its mobile check before closing it and moving to the next engine.
|
||||
|
||||
### Step 4: Report Back
|
||||
|
||||
```
|
||||
@@ -87,4 +93,5 @@ playwright-cli -s=verify-webkit snapshot
|
||||
- If the dev server is unreachable, report the error and stop
|
||||
- Never attach to a live personal browser session without explicit permission
|
||||
- If current-session reuse is requested, use the supported attach path only when available; otherwise report the limitation instead of silently switching to a fresh session
|
||||
- Never run multiple browser engines at once, and never use `playwright-cli close-all` or `kill-all`
|
||||
- Don't modify any code — you are read-only, verification only
|
||||
|
||||
@@ -32,9 +32,11 @@ Since each `goto` creates a new document, data resets per route — collect **be
|
||||
Open a blank page, inject instrumentation via `addInitScript` (runs before any page script in every new document), then navigate:
|
||||
|
||||
```bash
|
||||
playwright-cli -s=SESSION open about:blank
|
||||
./scripts/pw-session.sh open SESSION about:blank
|
||||
```
|
||||
|
||||
If the wrapper exits 75 another browser workflow owns the slot. Block on `./scripts/pw-session.sh open --wait <session> about:blank`, or report that to the parent and stop. Never bypass the lock.
|
||||
|
||||
```bash
|
||||
playwright-cli -s=SESSION run-code "async page => await page.addInitScript(() => {
|
||||
window.__PROFILING__=true;
|
||||
@@ -95,7 +97,7 @@ playwright-cli -s=SESSION console error
|
||||
playwright-cli -s=SESSION console warning
|
||||
playwright-cli -s=SESSION network
|
||||
playwright-cli -s=SESSION tracing-stop
|
||||
playwright-cli -s=SESSION close
|
||||
./scripts/pw-session.sh close SESSION
|
||||
```
|
||||
|
||||
### Step 4: Analyze and Report
|
||||
@@ -168,6 +170,7 @@ Routes profiled: /route1, /route2, ...
|
||||
- If `__getReactScanReport` is undefined or returns `{}`, wait ~1s and retry once (it is a dynamic import); if still empty, note "react-scan report unavailable" and rely on commit counts
|
||||
- If a route has no content or fails to load, note it in Info and move on
|
||||
- **Always stop tracing and close the browser when done, even on errors** — wrap your workflow in a try/finally mindset: if any step fails, still run `tracing-stop` and `close`
|
||||
- Never use `playwright-cli close-all` or `kill-all`; they can terminate another agent's session
|
||||
- Board codes (`biz`, `pol`, `g`, etc.) map to community addresses via the app's directory
|
||||
- High commit counts without long tasks = frequent cheap rerenders — still worth fixing for efficiency
|
||||
- React-scan report pinpoints exact components — prioritize these in recommendations
|
||||
|
||||
@@ -33,6 +33,7 @@ Batch 3 (parallel): [tasks that depend on batch 2]
|
||||
**Rules:**
|
||||
|
||||
- Max 4 concurrent subagents, to bound machine load and coordination overhead
|
||||
- Never parallelize browser-driving work. Queue browser checks behind the machine-wide `./scripts/pw-session.sh` lock and run them sequentially after implementation work.
|
||||
- Tasks touching the same file(s) go in the same subagent or sequential batches — never parallel
|
||||
- Small related tasks can be grouped into one subagent to reduce overhead
|
||||
- Large independent tasks get their own subagent
|
||||
@@ -66,7 +67,7 @@ After all batches complete:
|
||||
1. Run `yarn build` to confirm everything compiles
|
||||
2. Run `yarn lint` and `yarn type-check`
|
||||
3. If the plan touched React components/hooks, run `yarn doctor`
|
||||
4. For UI changes, verify in the browser with `playwright-cli` across `chrome`, `firefox`, and `webkit`, plus a mobile viewport flow in each engine when relevant
|
||||
4. For UI changes, verify with `./scripts/pw-session.sh` across `chrome`, `firefox`, and `webkit` sequentially, reusing each engine session for the mobile viewport flow when relevant and closing it before opening the next
|
||||
|
||||
### 6. Report
|
||||
|
||||
@@ -92,5 +93,5 @@ Summarize to the user:
|
||||
|
||||
- **You orchestrate, subagents implement.** Don't code changes yourself unless it's a trivial one-liner fix for a subagent failure.
|
||||
- **Context is precious.** Every build log and file read you do in the main thread is context you can't get back. Delegate liberally.
|
||||
- **Parallelize aggressively.** The faster batches finish, the faster the plan is done. Only serialize when dependencies demand it.
|
||||
- **Parallelize non-browser work aggressively.** Browser-driving work is always serialized by the machine-wide resource lock, even when tasks are otherwise independent.
|
||||
- **Verify at the end, not in between.** Subagents run their own build checks. You do a final holistic verification.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1,11 +1,24 @@
|
||||
---
|
||||
name: playwright-cli
|
||||
description: Automates browser interactions for web testing, form filling, screenshots, and data extraction. Use when the user needs to navigate websites, interact with web pages, fill forms, take screenshots, test web applications, or extract information from web pages.
|
||||
allowed-tools: Bash(playwright-cli:*)
|
||||
allowed-tools: Bash(playwright-cli:*), Bash(./scripts/pw-session.sh:*)
|
||||
---
|
||||
|
||||
# Browser Automation with playwright-cli
|
||||
|
||||
## Resource Budget (MUST)
|
||||
|
||||
One Playwright browser session may be active at a time, machine-wide. The budget is shared by every worktree and by any other checkout that ships this wrapper, because the contended resource is machine RAM and CPU rather than the repository. Playwright disables normal background throttling, so hidden 5chan pages keep P2P and rendering work active after a check.
|
||||
|
||||
- During iteration, use Chrome/Blink only. Run the full cross-browser matrix once the change is ready for final verification.
|
||||
- Open every fresh session through `./scripts/pw-session.sh open <session> ...`; it acquires the shared browser slot.
|
||||
- Reuse the same engine session for desktop and mobile by resizing it.
|
||||
- Close it with `./scripts/pw-session.sh close <session>` in a finally-style cleanup before opening another engine. `close` stops the browser even when the lock was already lost, so it is always the right cleanup call.
|
||||
- Run browser engines and profiler batches sequentially. Never spawn browser-driving agents in parallel.
|
||||
- Exit code 75 means the slot is busy. Finish non-browser work and retry, or block on `./scripts/pw-session.sh open --wait[=SECONDS] <session> ...` (default 300s). Do not bypass the lock.
|
||||
- Never use `playwright-cli close-all` or `kill-all` while concurrent agents may own sessions.
|
||||
- A lock left behind by an interrupted workflow clears itself: the next `open` reclaims any slot whose browser is no longer running. Inspect the holder with `./scripts/pw-session.sh status`, which reports whether that browser is still alive. `release <session>` is a last resort for the rare case where `status` cannot verify the browser state.
|
||||
|
||||
## Cross-Browser UI Verification
|
||||
|
||||
When using `playwright-cli` to verify rendering, styling, layout, or interactions in this repo, run the relevant flow in all three major browser engines:
|
||||
@@ -14,12 +27,20 @@ When using `playwright-cli` to verify rendering, styling, layout, or interaction
|
||||
- `firefox` for Gecko
|
||||
- `webkit` for Safari/WebKit coverage
|
||||
|
||||
Use separate named sessions per engine, compare the results, and record any engine-specific differences instead of treating Chromium output as sufficient.
|
||||
Use separate short named sessions per engine, compare the results, and record any engine-specific differences instead of treating Chromium output as sufficient. Run them sequentially:
|
||||
|
||||
```bash
|
||||
playwright-cli -s=verify-chrome open http://example.com --browser=chrome
|
||||
playwright-cli -s=verify-firefox open http://example.com --browser=firefox
|
||||
playwright-cli -s=verify-webkit open http://example.com --browser=webkit
|
||||
./scripts/pw-session.sh open verify-chrome http://example.com --browser=chrome
|
||||
# Run the desktop and mobile flow, then release the slot.
|
||||
./scripts/pw-session.sh close verify-chrome
|
||||
|
||||
./scripts/pw-session.sh open verify-firefox http://example.com --browser=firefox
|
||||
# Run the desktop and mobile flow, then release the slot.
|
||||
./scripts/pw-session.sh close verify-firefox
|
||||
|
||||
./scripts/pw-session.sh open verify-webkit http://example.com --browser=webkit
|
||||
# Run the desktop and mobile flow, then release the slot.
|
||||
./scripts/pw-session.sh close verify-webkit
|
||||
```
|
||||
|
||||
## Quick start
|
||||
@@ -242,6 +263,7 @@ playwright-cli -s=mysession close # stop a named browser
|
||||
playwright-cli -s=mysession delete-data # delete user data for persistent session
|
||||
|
||||
playwright-cli list
|
||||
# Never use these during concurrent agent work; they affect unrelated sessions.
|
||||
# Close all browsers
|
||||
playwright-cli close-all
|
||||
# Forcefully kill all browser processes
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
# Browser Session Management
|
||||
|
||||
Run multiple isolated browser sessions concurrently with state persistence.
|
||||
Manage isolated browser sessions with state persistence. In 5chan, keep only one session active machine-wide and use the shared wrapper for the open/close lifecycle.
|
||||
|
||||
```bash
|
||||
./scripts/pw-session.sh open verify-chrome https://5chan.localhost --browser=chrome
|
||||
playwright-cli -s=verify-chrome snapshot
|
||||
./scripts/pw-session.sh close verify-chrome
|
||||
```
|
||||
|
||||
## Named Browser Sessions
|
||||
|
||||
@@ -60,25 +66,18 @@ playwright-cli open example.com # Uses "mysession" automatically
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Concurrent Scraping
|
||||
### Sequential Cross-Browser Verification
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Scrape multiple sites concurrently
|
||||
# Keep one browser active at a time, machine-wide.
|
||||
|
||||
# Start all browsers
|
||||
playwright-cli -s=site1 open https://site1.com &
|
||||
playwright-cli -s=site2 open https://site2.com &
|
||||
playwright-cli -s=site3 open https://site3.com &
|
||||
wait
|
||||
|
||||
# Take snapshots from each
|
||||
playwright-cli -s=site1 snapshot
|
||||
playwright-cli -s=site2 snapshot
|
||||
playwright-cli -s=site3 snapshot
|
||||
|
||||
# Cleanup
|
||||
playwright-cli close-all
|
||||
for engine in chrome firefox webkit; do
|
||||
session="verify-$engine"
|
||||
./scripts/pw-session.sh open "$session" https://5chan.localhost --browser="$engine"
|
||||
playwright-cli -s="$session" snapshot
|
||||
./scripts/pw-session.sh close "$session"
|
||||
done
|
||||
```
|
||||
|
||||
### A/B Testing Sessions
|
||||
@@ -154,7 +153,8 @@ playwright-cli -s=s1 open https://github.com
|
||||
playwright-cli -s=auth close
|
||||
playwright-cli -s=scrape close
|
||||
|
||||
# Or stop all at once
|
||||
# Do not use these global commands while concurrent agents may own sessions.
|
||||
# Stop all at once
|
||||
playwright-cli close-all
|
||||
|
||||
# If browsers become unresponsive or zombie processes remain
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
---
|
||||
name: profile-browsing
|
||||
description: Profile app performance while browsing, collecting Web Vitals and React rerender data via react-scan. Orchestrates parallel profiler subagents via playwright-cli to capture navigation timing, long tasks, layout shifts, LCP, React commit counts, render bursts, and per-component render data. Use when profiling browsing performance, finding bottlenecks, diagnosing excessive rerenders, or auditing page performance.
|
||||
description: Profile app performance while browsing, collecting Web Vitals and React rerender data via react-scan. Orchestrates sequential profiler subagents via playwright-cli to capture navigation timing, long tasks, layout shifts, LCP, React commit counts, render bursts, and per-component render data without saturating the machine. Use when profiling browsing performance, finding bottlenecks, diagnosing excessive rerenders, or auditing page performance.
|
||||
---
|
||||
|
||||
# Profile Browsing Performance
|
||||
|
||||
Two-layer profiling: browser-level symptoms (Web Vitals, long tasks, scroll jank) and React-level diagnosis (commit counts, render bursts, per-component render data from react-scan). Each profiler subagent runs in its own browser session and context window.
|
||||
Two-layer profiling: browser-level symptoms (Web Vitals, long tasks, scroll jank) and React-level diagnosis (commit counts, render bursts, per-component render data from react-scan). Each profiler subagent runs in its own browser session and context window, with only one profiler active at a time.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@@ -31,7 +31,7 @@ No additional setup needed — react-scan is already a devDependency and importe
|
||||
|
||||
## Step 0: Ensure Dev Server is Running
|
||||
|
||||
Before spawning any profiler subagents, verify exactly one dev server is available:
|
||||
Before running any profiler subagents, verify exactly one dev server is available:
|
||||
|
||||
```bash
|
||||
# Check if the dev server is reachable
|
||||
@@ -44,7 +44,7 @@ curl -sf https://5chan.localhost -o /dev/null && echo "OK" || echo "NOT RUNNING"
|
||||
|
||||
## Step 1: Define Route Batches
|
||||
|
||||
Split routes into batches of 2–4 for parallel profiling.
|
||||
Split routes into batches of 2–4 for sequential profiling. Give every batch a short task-specific session name so unrelated profiling runs cannot collide.
|
||||
|
||||
**Default batches** (adjust boards as needed):
|
||||
|
||||
@@ -56,9 +56,9 @@ Split routes into batches of 2–4 for parallel profiling.
|
||||
|
||||
Keep batches balanced. Add thread views (`/:boardIdentifier/thread/:cid`) as needed.
|
||||
|
||||
## Step 2: Spawn Profiler Subagents
|
||||
## Step 2: Run Profiler Subagents Sequentially
|
||||
|
||||
Read the profiler subagent definition at `.claude/agents/profiler.md`. Then spawn one `profiler` Task per batch **in parallel** (single message, multiple Task calls):
|
||||
Read the profiler subagent definition at `.claude/agents/profiler.md`. Then spawn one `profiler` Task for the first batch:
|
||||
|
||||
```
|
||||
For each batch, create a Task:
|
||||
@@ -69,9 +69,7 @@ For each batch, create a Task:
|
||||
Any non-default app URL or extra profiling constraints
|
||||
```
|
||||
|
||||
Spawn up to 4 subagents simultaneously. Each opens its own browser session, navigates routes, scrolls, collects both Web Vitals and react-scan data per route, and returns a structured issues list.
|
||||
|
||||
**Trade-off:** Parallel is faster but may skew timing results under heavy machine load. For precise measurements, spawn sequentially.
|
||||
Wait for that profiler to close its browser and return results before spawning the next batch. Never run profiler or browser-check subagents concurrently: competing browser sessions both saturate the machine and invalidate timing measurements.
|
||||
|
||||
## Step 3: Merge Results
|
||||
|
||||
@@ -147,18 +145,17 @@ ps aux | grep 'vite.*--port' | grep -v grep
|
||||
- If the orchestrator started the dev server in Step 0, kill it now.
|
||||
- If there are multiple Vite processes (should never happen), kill the extras and warn the user.
|
||||
|
||||
Also close any leftover playwright-cli sessions:
|
||||
Confirm the profiling session released the shared browser slot:
|
||||
|
||||
```bash
|
||||
# Close any profiling sessions that weren't properly closed
|
||||
playwright-cli -s=prof-1 close 2>/dev/null
|
||||
playwright-cli -s=prof-2 close 2>/dev/null
|
||||
playwright-cli -s=prof-3 close 2>/dev/null
|
||||
./scripts/pw-session.sh status
|
||||
```
|
||||
|
||||
If a failed profiler still owns the slot, close that exact recorded session with `./scripts/pw-session.sh close <session>`. A slot whose browser already died is reclaimed by the next `open`, so it needs no manual cleanup. Never use `close-all` or `kill-all` during concurrent agent work.
|
||||
|
||||
## Notes
|
||||
|
||||
- **Session isolation**: Each subagent uses a named playwright-cli session (`-s=prof-N`).
|
||||
- **Session isolation**: Each subagent uses a short task-specific playwright-cli session (`-s=prof-<task>-N`).
|
||||
- **Context isolation**: Each subagent runs in its own context window.
|
||||
- **Per-route collection**: Data resets on each `goto` — the profiler collects before navigating away.
|
||||
- **addInitScript persistence**: Instrumentation re-injects automatically in each new document.
|
||||
|
||||
@@ -91,7 +91,7 @@ After code changes, follow repo verification rules from `AGENTS.md`:
|
||||
- run `yarn build`, `yarn lint`, and `yarn type-check`
|
||||
- run `yarn test` after adding or changing tests
|
||||
- run `yarn doctor` after React UI logic changes
|
||||
- use `playwright-cli` for UI/visual changes across `chrome`, `firefox`, and `webkit`, plus a mobile viewport flow in each engine when relevant
|
||||
- use `./scripts/pw-session.sh` for UI/visual changes across `chrome`, `firefox`, and `webkit` sequentially, plus a mobile viewport flow in each engine when relevant
|
||||
|
||||
### 5. Report back on the PR before merging
|
||||
|
||||
|
||||
Reference in New Issue
Block a user