feat: XDG config discovery, extraArgs support, and WSL2/container fixes#45
feat: XDG config discovery, extraArgs support, and WSL2/container fixes#45mjdaly wants to merge 10 commits intoSawyerHood:mainfrom
Conversation
Adds support for Chrome for Testing via CDP and multi-agent concurrency. - External browser mode keeps browser open after automation - Auto-detects Chrome for Testing installation - New config file at ~/.dev-browser/config.json - Better support for multi-agent workflows Source: SawyerHood#24 Co-authored-by: Matthew O'Riordan <matthew@ably.com>
- Switch to lightweight HTTP-only client (12MB → 30KB memory per agent) - Extract shared routes to eliminate code duplication - Add complete HTTP API for all page operations - Map-based page registry for O(1) lookup (was O(n) CDP scan) - Auto-shutdown after 30 minutes of inactivity - Stale server cleanup on startup Source: SawyerHood#25 Co-authored-by: Matthew O'Riordan <matthew@ably.com>
Config file discovery now follows this priority: 1. DEV_BROWSER_CONFIG environment variable (explicit override) 2. .dev-browser/config.json in cwd or ancestors (project config) 3. $XDG_CONFIG_HOME/dev-browser/config.json (XDG compliant) 4. ~/.config/dev-browser/config.json (XDG default) 5. ~/.dev-browser/config.json (legacy fallback) State files (active-servers.json) use XDG_STATE_HOME when set, falling back to ~/.local/state/dev-browser or ~/.dev-browser. This enables: - Per-project browser configurations - Proper XDG compliance on Linux - Container-friendly config via env vars - Backward compatibility with existing ~/.dev-browser setups Also fixes test that expected old default port (9222 -> 19222) and adds proper test isolation via config module mocking. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d2156e8b48
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| export async function findAvailablePort(config?: DevBrowserConfig): Promise<number> { | ||
| const { portRange } = config || loadConfig(); | ||
| const { start, end, step } = portRange; | ||
|
|
||
| for (let port = start; port < end; port += step) { |
There was a problem hiding this comment.
Try the configured end port in allocation loop
The portRange.end value is documented as the “last port to try,” but the loop uses port < end, so the end port is never checked. If the only free port is exactly end (or start === end), findAvailablePort will throw “No available ports” even though a valid port exists. Consider using <= end or clarifying that end is exclusive.
Useful? React with 👍 / 👎.
| if (!entry) { | ||
| // Create new page in the persistent context (with timeout to prevent hangs) | ||
| const page = await withTimeout(context.newPage(), 30000, "Page creation timed out after 30s"); |
There was a problem hiding this comment.
Preserve viewport on page creation
The server no longer applies GetPageRequest.viewport when creating a new page. Existing callers (e.g., client.page(name, { viewport })) still send a viewport and expect it to be applied, but this handler now ignores it, so viewport sizing silently regresses. This breaks the documented API behavior for viewport on creation unless clients are updated to call the new set-viewport endpoint.
Useful? React with 👍 / 👎.
| if (process.platform === "darwin" && browserPath.endsWith(".app")) { | ||
| console.log(`Launching macOS app: ${browserPath}`); | ||
| console.log(` (App handles CDP port and user data dir internally)`); | ||
|
|
||
| const child = spawn("open", ["-a", browserPath], { |
There was a problem hiding this comment.
Pass CDP args when launching .app on macOS
When browserPath ends with .app, launchBrowserDetached calls open -a without --args, so neither --remote-debugging-port nor --user-data-dir is applied. That means cdpPort/userDataDir are ignored and the auto-launched browser won’t open the configured CDP port, causing getCdpEndpoint to time out on macOS when users follow the documented .app path configuration.
Useful? React with 👍 / 👎.
- Tests for getXdgConfigHome() and getXdgStateHome() - Tests for findProjectConfig() directory walking - Tests for getConfigFilePath() priority chain - Tests for getStateDir() fallback logic - Export config functions to enable testing 20 new tests, all passing. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove confusing "/" fallback in findProjectConfig - the parent === dir check handles root detection on all platforms - Add test for "both XDG and legacy exist" scenario - Add integration tests for loadConfig() that verify: - Project config is loaded when present - Browser path validation triggers warning and fallback The integration test caught that loadConfig() validates browser paths exist before using them - important behavior to document. 77 tests passing. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Document config file discovery priority order - Add Project-Level Configuration section - Add XDG Base Directory Support section with table - Add Environment Variable Override section - Document state file locations for XDG compliance Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Document config file discovery priority order - Add example config with common settings - Explain project-level and container/CI usage Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Chrome refuses to enable CDP debugging when using the default profile, failing with: "DevTools remote debugging requires a non-default data directory. Specify this using --user-data-dir." Now dev-browser always sets --user-data-dir: - Uses explicit config value if provided - Otherwise defaults to $XDG_STATE_HOME/dev-browser/chrome-profile This ensures CDP debugging works out of the box without requiring manual configuration. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Document why dev-browser uses a dedicated profile by default - Explain how to configure userDataDir to use existing logged-in sessions - Add common profile locations for macOS, Linux, Windows - Note potential conflicts when using default profile with Chrome running Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
b2561d4 to
7a4e5b5
Compare
Adds support for passing extra command-line arguments to Chrome via
the config file. Useful for environment-specific flags like --disable-gpu
in WSL2/container environments where GPU virtualization causes SIGILL
crashes on complex pages.
Example config:
```json
{
"browser": {
"extraArgs": ["--disable-gpu", "--no-sandbox"]
}
}
```
Also documents the WSL2 SIGILL issue and recommended flags:
- --disable-gpu (disable hardware acceleration)
- --disable-software-rasterizer (disable software GPU fallback)
- --disable-dev-shm-usage (use /tmp for shared memory)
- --no-sandbox (required in some containers)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This PR depends on the following unmerged PRs being merged first:
config.ts)client-lite.ts)The files modified in this PR (
config.ts,client-lite.test.ts) do not exist in upstream main yet.Summary
This PR adds several configuration improvements for better cross-platform and container support:
1. XDG and Project-Level Config Discovery
.dev-browser/config.json)DEV_BROWSER_CONFIGenvironment variable for explicit config path override~/.dev-browser/setups2. Browser Extra Arguments (
browser.extraArgs)3. Default User Data Directory for CDP
$XDG_STATE_HOME/dev-browser/chrome-profilebrowser.userDataDirfor using existing profiles4. WSL2/Container SIGILL Fix Documentation
--disable-gpu,--disable-software-rasterizer,--no-sandboxConfig Discovery Priority
Config file:
DEV_BROWSER_CONFIGenvironment variable.dev-browser/config.jsonin cwd or ancestor directories (project config)$XDG_CONFIG_HOME/dev-browser/config.json(XDG compliant)~/.config/dev-browser/config.json(XDG default)~/.dev-browser/config.json(legacy fallback)State files (active-servers.json, chrome-profile):
$XDG_STATE_HOME/dev-browser/~/.local/state/dev-browser/~/.dev-browser/(legacy)New Config Options
{ "browser": { "path": "/opt/google/chrome/google-chrome", "userDataDir": "/path/to/profile", "extraArgs": ["--disable-gpu", "--no-sandbox"] } }browser.userDataDirbrowser.extraArgs["--disable-gpu"])WSL2/Container Example
For environments with GPU virtualization issues:
{ "browser": { "path": "/opt/google/chrome/google-chrome", "extraArgs": [ "--disable-gpu", "--disable-software-rasterizer", "--disable-dev-shm-usage", "--no-sandbox" ] } }Test plan
Code changes
src/config.tsextraArgsin interfacesrc/external-browser.tsscripts/get-browser-config.tsBROWSER_EXTRA_ARGSscripts/start-external-browser.tsserver.shSKILL.md🤖 Generated with Claude Code