Repository navigation
feat(claude-code): make agent-browser the default browser tool, via an image-managed skill - #175
Merged
Merged
Conversation
…n image-managed skill Replaces the per-project sandbox-playwright skill with devcontainer-browser, shipped by the image at /etc/claude-code/.claude/skills/ (Claude Code's managed skills location). Every project gets it without a copy, and it wins a name clash with a project skill. - devcontainer-browser: agent-browser first, for opening the app, UI checks, screenshots, DPR/srcset measurement, scripted checks and React render profiling. Playwright only for a project's committed @playwright/test suite, vitest browser mode or Storybook tests, Firefox/WebKit, or a missing agent-browser. Keeps the executablePath wiring matrix and the never-download-a-browser rules. Defers agent-browser command docs to the version-matched `agent-browser skills get core`. - managed-settings.json: a claudeMd routing rule loaded in every session, and permissions.allow for Bash(agent-browser:*). - agent-browser moves from the default target into base, so the sandbox target has it too; sandbox also sets AGENT_BROWSER_EXECUTABLE_PATH. - CI verify checks agent-browser, its env var, the managed skill, and both new managed-settings keys on both targets. - devcontainer-upstream-sync 1.3.0: sandbox-playwright is a retired path (delete), since a leftover copy would load alongside the new skill. - README: built-in browser skill section, migration note, and the "default target only" notes for agent-browser removed. Removing the Playwright MCP plugin is separate: #174 (review 2026-11-25).
6 tasks
…rowser # Conflicts: # .github/workflows/ci.yml # claude-code/.devcontainer/Dockerfile
…ached - Pin agent-browser's config with AGENT_BROWSER_CONFIG=/etc/agent-browser/config.json. Without it, the CLI auto-loads ./agent-browser.json, which can declare plugin executables and Chromium args, so a repo could run code under the pre-allowed Bash(agent-browser *) rule. The image config turns on contentBoundaries and maxOutput, following upstream's recommended agent config. - Managed permissions.deny for `agent-browser install` / `upgrade`: install --with-deps runs sudo apt-get, and upgrade bypasses the Renovate pin. - Write the allow rule in the space form the permissions docs use. - Move the managed settings/skill COPYs to the end of the shared stage, so editing the skill no longer rebuilds Chromium and Claude Code. - Skill: drop the `ss` step (iproute2 is sandbox-only, so in the default target it silently printed nothing), and replace the maintainer section, which repeated the README and told agents to delete project files. - upstream-sync: add the Workflow 2 step for `retired: delete`, confirmed with the user like every other adopt step.
Bash(agent-browser *) approves any arguments. --config overrides the AGENT_BROWSER_CONFIG pin (the CLI flag is checked first), and --executable-path / --args start any binary, so a page that tricks the agent could run code without a prompt. Prefix rules can't block these reliably (`agent-browser --json install` gets past the deny rules). The image keeps the deny rules, the config pin and the skill routing; agent-browser prompts on first use. The README gives a one-line per-project opt-in in .claude/settings.local.json for trusted projects.
gatezh
added a commit
that referenced
this pull request
Oct 8, 2026
…config changes #175 added two files the image copies in, managed-skills/devcontainer-browser/SKILL.md and agent-browser.json, but build-claude-code.yml's push paths didn't include them. An edit to either alone would merge to master and never be published.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Makes agent-browser the default browser tool for agents in both claude-code images, with Playwright as the fallback. This is done with one skill that the image ships, instead of a copy in every project.
sandbox-playwrightis rewritten and renameddevcontainer-browser, and ships at/etc/claude-code/.claude/skills/devcontainer-browser/, Claude Code's managed skills location. Every project gets it with nothing to copy, and it wins a name clash with a project skill.claude-code/.devcontainer/managed-skills/, DockerfileclaudeMdrouting rule, loaded in every session (projects can't exclude it).managed-settings.jsonpermissions.denyblocksagent-browser installandupgrade:install --with-depsrunssudo apt-get, andupgradebypasses the Renovate pin. agent-browser is not pre-allowed (see Notes); the README gives a one-line per-project opt-in.managed-settings.json, READMEAGENT_BROWSER_CONFIG=/etc/agent-browser/config.jsonpins agent-browser's config. Otherwise the CLI auto-loads./agent-browser.json, which can declare plugin executables and Chromium args, so a repo could run code through any agent-browser command. The image config turns oncontentBoundariesandmaxOutput(upstream's recommended agent config).agent-browser.json, Dockerfiledefaultinto thesharedstage, so thesandboxtarget has it too. It keeps master's cache mount and per-arch binary trim. The managed settings, skill and configCOPYs come last inshared, so editing them doesn't rebuild Chromium or Claude Code.ci.ymldevcontainer-upstream-sync1.3.0 lists.claude/skills/sandbox-playwright/as a retired path. Workflow 2 deletes it after confirming with the user. A leftover copy has a different name, so it would load alongside the new skill and contradict it.The skill's routing
set viewport <w> <h> 2), which srcset candidate loaded, and layout. Scripted multi-step checks, isolated sessions, network mocking and HAR, accessibility audits, React render profiling.@playwright/testsuite, vitest browser mode and Storybook tests, Firefox or WebKit, orcommand -v agent-browserfinds nothing.It keeps what made
sandbox-playwrightuseful: the per-consumerexecutablePathwiring matrix, never installing or downloading a browser, discovering the dev-server port instead of assuming one, and thefindpattern that works under RTK. For command usage it defers toagent-browser skills get core, which the CLI serves for the installed version, so the skill doesn't go stale on Renovate bumps.Verification
master(shared-layer refactor perf(claude-code): install Claude Code last and cache CI layers #183/#adeef37, agent-browser 0.38.2, Claude Code 2.1.294) with no rebase or force-push.ci.ymland passes in its image, including after the final commit.session id --scope worktreeoutput is unaffected by content boundaries, so the skill'sexport AGENT_BROWSER_SESSION="$(…)"works;get textandeval --stdinoutput is wrapped inAGENT_BROWSER_PAGE_CONTENTmarkers;set viewport 390 844 2givesdevicePixelRatio2;./agent-browser.jsonis ignored. WithAGENT_BROWSER_CONFIGunset, the same file warns (control), so the pin is what skips it (load_configreturns early).SKILL.mdedit reran only the last twoCOPYlayers; Chromium, Claude Code and agent-browser stayedCACHED.hadolint-action@v3.0.0uses) with.hadolint.yaml, and actionlint, pass.claude-codedefault container (agent-browser 0.38.1) against a live Next.js site: srcset picks at DPR 2,console,errors,close, andopen --enable react-devtoolsfollowed byreact renders start/stop.Not covered
ralphex-fehas Chromium and its ownmanaged-settings.jsonbut no agent-browser. The same pattern applies there, as a follow-up.sandbox-playwrightcopy until they delete it; the migration note and upstream-sync's retired-path entry cover that.claude-sandboxfirewall hasn't been exercised. It drives local Chromium over CDP, so no new domains should be needed, but worth watching.Notes
Bash(agent-browser *)approves any arguments.--config <file>overrides the config pin (the CLI flag is checked first), and--executable-path/--argsstart any binary, so a page that tricks the agent could run code without a prompt. Prefix rules can't block that reliably (agent-browser --json installgets past a deny rule). Instead, the first agent-browser command in a project prompts and shows the full command; "don't ask again" keeps the answer, or a trusted project can opt in with one line in.claude/settings.local.json.