| name | Browser Daemon |
| description | Persistent browser automation via Playwright daemon. Keep a browser window open and send it commands (navigate, execute JS, inspect console). Perfect for interactive debugging, development, and testing web applications. Use when you need to interact with a browser repeatedly without opening/closing it. |
| version | 7.2.0 |
| author | hypatia-earth |
| tags | browser, automation, debugging, playwright, daemon, console-logs, screenshots |
Browser Daemon - Persistent Browser Automation
Persistent browser daemon that keeps Chrome open and accepts commands via file-based IPC.
Quick Start
Start the daemon (once per session)
cd ~/.claude/skills/playwright-skill
node browser-daemon.js [--size=quarter|dev|full|WIDTHxHEIGHT] [--persist]
Options:
--size=dev- Fixed 900×860 viewport (default, good for development)--size=quarter- Screen size divided by 2 (e.g., 1512×948 → 756×474)--size=full- Full screen size--size=1024x768- Custom width×height--persist- Preserve IndexedDB, localStorage, cookies across restarts
Or ask: "Start the browser daemon in the background"
The browser window opens and stays open.
Send commands
cd ~/.claude/skills/playwright-skill
# Navigate
node browser-client.js navigate "http://localhost:8080/..."
# Reload current page
node browser-client.js reload
# Execute JavaScript
node browser-client.js exec "document.title"
node browser-client.js exec "document.querySelectorAll('div').length"
# Console logs
node browser-client.js console
node browser-client.js console-clear
# Status & Inspection
node browser-client.js status
node browser-client.js inspect
node browser-client.js list
# Screenshots
node browser-client.js screenshot /path/to/output.png
node browser-client.js screenshot /path/to/output.png fullpage
# Resize viewport
node browser-client.js resize 1920 1080
# Shutdown
node browser-client.js shutdown
Window close behavior
New: Close window = shutdown daemon
- Closing the browser window (Cmd-W or red X button) automatically shuts down the daemon
- No restart - daemon exits completely
- Clean shutdown with proper cleanup of state files
Architecture
Claude (Bash tool)
↓
browser-client.js (writes .browser-command)
↓
browser-daemon.js (polls, executes, writes .browser-result)
↓
Chrome Browser (Playwright-controlled)
IPC Files:
.browser-command- Command input (JSON).browser-result- Command output (JSON).browser-ready- Ready signal (exists when daemon is running)
Files created/deleted automatically during operation.
Commands
navigate
Navigate to URL and wait for page load. Clears console logs.
node browser-client.js navigate "http://localhost:8080/page"
Returns: { success: true, url: string, title: string }
reload
Reload current page (like F5 or Cmd-R). Clears console logs.
node browser-client.js reload
Returns: { success: true, url: string, title: string }
exec
Execute JavaScript in browser context.
node browser-client.js exec "document.querySelectorAll('div').length"
Returns: { success: true, result: any }
console
Get all captured console logs.
node browser-client.js console
Returns: { success: true, logs: [{ type, text, location }] }
console-clear
Clear console log buffer.
node browser-client.js console-clear
Returns: { success: true }
status
Check daemon status and current page info.
node browser-client.js status
Returns: { success: true, url, title, consoleLogsCount }
inspect
Get detailed daemon status information.
node browser-client.js inspect
Returns detailed status including:
- Process: PID, uptime, memory usage, size preset
- Browser: connection status, type, version
- Page: URL, title, viewport dimensions
- Console log count
list
Check if daemon is running and show basic info.
node browser-client.js list
Shows daemon status and suggests how to start if not running.
screenshot ⚠️ Requires Permission
Capture screenshot of current page.
IMPORTANT: This command writes files to disk and requires explicit user permission before use.
node browser-client.js screenshot /path/to/output.png
node browser-client.js screenshot /path/to/output.png fullpage
node browser-client.js screenshot /path/to/output.png .selector
Returns: { success: true, path: string, selector?: string }
Options:
- Default: Captures viewport only
fullpage: Captures entire scrollable page.selector: Captures specific element only
screenshot-clean ⚠️ Requires Permission
Capture canvas/element screenshot without UI overlay.
IMPORTANT: This command writes files to disk and requires explicit user permission before use.
Temporarily hides UI elements, captures the canvas, then restores UI. Perfect for WebGPU/WebGL canvas screenshots without overlaid controls.
node browser-client.js screenshot-clean /path/to/output.png
node browser-client.js screenshot-clean /path/to/output.png .scene-canvas
node browser-client.js screenshot-clean /path/to/output.png .scene-canvas #app
Returns: { success: true, path: string, selector: string, hidden: string }
Arguments:
path: Output file path (required)canvas-selector: Element to capture (default:.scene-canvas)hide-selector: Element to hide during capture (default:#app)
resize
Resize browser viewport.
node browser-client.js resize 1920 1080
Returns: { success: true, width, height }
shutdown
Gracefully shutdown the daemon.
node browser-client.js shutdown
Returns: { success: true, message: string }
Closes browser and exits daemon process cleanly.
wait-for-load (helper script)
Wait for page to signal it's loaded via console marker.
./wait-for-load.sh
Polls console logs for [PAGE_LOADED] marker (30s timeout).
Useful for automation - ensures page is fully initialized before taking screenshots or running tests.
Complete Screenshot Workflow
Automated sequence: open → navigate → wait → screenshot → cleanup
# Start daemon with dev size viewport
node browser-daemon.js --size=dev &
# Wait for daemon to start
sleep 3
# Navigate to target URL
node browser-client.js navigate http://localhost:8080
# Wait for page to signal it's loaded (smart wait)
./wait-for-load.sh
# Take screenshot
node browser-client.js screenshot /path/to/screenshot.png
# Clean shutdown
node browser-client.js shutdown
Alternative: Manual timing
# Navigate to target URL
node browser-client.js navigate http://localhost:8080
# Wait for page to fully load (fixed wait)
sleep 5
# Verify page loaded by checking console
node browser-client.js console | tail -20
This workflow is perfect for:
- Automated visual regression testing
- Documentation screenshots
- CI/CD screenshot capture
- Periodic monitoring snapshots
Daemon Behavior
- Launches Chrome (not Chromium) for H.264 codec support
- Viewport size configured at startup via
--sizeflag - Automatically captures all console output (log, warn, error, debug, pageerror)
- Polls for commands every 100ms
- Window close detection: Closing browser window shuts down daemon completely
- Single instance: Each daemon controls one browser window
Browser Configuration
chromium.launch({
channel: 'chrome', // Use Google Chrome, not Chromium
headless: false, // Visible window
args: ['--start-maximized']
})
Viewport size set after launch based on --size preset or calculated from screen dimensions.
Important Quirks
Manual window resizing does NOT work:
- Playwright controls viewport independently from window
- Manually resizing browser window does NOT change viewport
- Window resize does NOT trigger JavaScript resize events
- Use
resizecommand instead:node browser-client.js resize 1024 768
DevTools overlay:
- Opening DevTools does NOT resize viewport - overlays on top
- Does NOT trigger resize events
- Does NOT change
window.innerWidth/Height
Viewport vs Window:
window.innerWidth/Height- The viewport (controlled by Playwright)window.outerWidth/Height- The window size- Only viewport can be changed via
resizecommand
Window close behavior:
- Closing browser window (Cmd-W or red X) triggers clean shutdown
- No automatic restart - daemon exits completely
- All state files cleaned up on exit
Use Cases
Interactive development: Keep browser open while testing changes, reload and check console without manual interaction.
Debugging console logs: Track down log sources with automatic source location capture.
Inspecting page state: Query DOM, check element counts, inspect computed styles via JavaScript execution.
Testing workflows: Automate multi-step browser interactions (navigate, fill forms, submit, check results).
Automated screenshots: Capture page state for documentation, testing, or monitoring.
Visual regression testing: Take screenshots before/after changes to detect visual differences.
Troubleshooting
Daemon not responding:
# Check if daemon is running
node browser-client.js list
# Or check for ready file
ls ~/.claude/skills/playwright-skill/.browser-ready
# Restart daemon
cd ~/.claude/skills/playwright-skill && node browser-daemon.js
Commands timing out:
- Check if browser window is still open
- Use
shutdowncommand to cleanly stop daemon - Clean up stuck files:
rm -f .browser-command .browser-result .browser-ready
Multiple instances running:
# List running daemons
ps aux | grep browser-daemon
# Kill all instances
pkill -f browser-daemon
# Clean up state files
rm -f ~/.claude/skills/playwright-skill/.browser-*
Browser window closed accidentally:
- Daemon automatically shuts down when window is closed
- Start new daemon:
node browser-daemon.js [--size=...]
Setup (First Time)
cd ~/.claude/skills/playwright-skill
npm install
This installs Playwright and downloads Chrome browser.
Advanced Capabilities
See META_COMMANDS.md for comprehensive reference of Playwright's meta-level capabilities beyond basic testing:
- Page events (console, network, dialogs, workers, frames, lifecycle)
- Content capture (screenshots, PDFs, HTML, video)
- Network control (interception, mocking, HAR replay, WebSockets)
- Script injection and Node.js function exposure
- Performance metrics and garbage collection
- Chrome DevTools Protocol (CDP) access for low-level browser control
- Browser context events and meta methods
Integration Notes
When user requests browser interaction:
- Check if daemon is running:
node browser-client.js list - If not running, start daemon in background (it never returns):
node ~/.claude/skills/playwright-skill/browser-daemon.js --size=dev & - Use
browser-client.jscommands (these return quickly):node ~/.claude/skills/playwright-skill/browser-client.js navigate "http://example.com" - Report results back to user
- Shutdown when done:
browser-client.js shutdown(or let user close window)
Important: The daemon process runs forever until shutdown. Always start with & or as a background task.
User can request additional features - the codebase is straightforward and well-documented for extensions.
Version History
v7.2.0 (Current)
--persistflag: preserves IndexedDB, localStorage, cookies across restarts- Data stored in
.browser-data/directory
v7.1.0
- New
screenshot-cleancommand: captures canvas without UI overlay screenshotnow supports element selector (e.g.,.scene-canvas)- Perfect for WebGPU/WebGL canvas screenshots
v7.0.0
- Added viewport size presets (
--size=quarter|dev|full|WxH) - Window close detection triggers daemon shutdown
- New commands:
inspect,shutdown,list - Improved single-instance behavior
- Enhanced screenshot workflow documentation
v6.0.0
- Initial documented version with core functionality