Skip to content

feat: add --background flag for non-intrusive browser tab operations#1215

Open
yangyaofei wants to merge 3 commits intovercel-labs:mainfrom
yangyaofei:feat/background-mode
Open

feat: add --background flag for non-intrusive browser tab operations#1215
yangyaofei wants to merge 3 commits intovercel-labs:mainfrom
yangyaofei:feat/background-mode

Conversation

@yangyaofei
Copy link
Copy Markdown

Summary

Add --background flag to prevent agent-browser from stealing browser focus when creating or switching tabs. This is essential when using --cdp or --auto-connect to control a user's existing Chrome browser where the user is actively browsing.

Problem

When connected to an existing Chrome via --cdp or --auto-connect, tab new and tab switch commands activate the target tab via CDP's Target.createTarget (which activates by default) and Page.bringToFront. This pulls the user's current tab away, making it impossible for an AI agent to operate in the background without disrupting the user.

Additionally, the navigate (open) command never called Page.bringToFront, so opened pages were not brought to the foreground even in normal (non-background) mode.

Solution

Add a --background boolean flag (config key: background, env var: AGENT_BROWSER_BACKGROUND) that works as a per-command flag — each command can independently specify whether it should operate in background mode, regardless of how the daemon was started.

When --background is set:

  • tab new: passes background: true to CDP Target.createTarget, creating the tab without activating it
  • tab switch: skips Page.bringToFront, switching only the internal active page index
  • navigate (open): skips Page.bringToFront, navigating the page in the background
  • click --new-tab: creates the new tab in the background

The agent can still fully interact with background tabs (snapshot, click, fill, etc.) since those operations don't require the tab to be in the foreground.

Usage

# Per-command: open in foreground, then work in background
agent-browser open https://example.com
agent-browser --background tab new https://news.ycombinator.com
agent-browser --background snapshot -i
agent-browser --background click @e1
agent-browser --background tab 0

# Config file (agent-browser.json) — sets default for all commands
{"background": true}

# Environment variable — sets default for all commands
AGENT_BROWSER_BACKGROUND=1 agent-browser snapshot -i

# CLI flag overrides config/env for that specific command
agent-browser --background false tab new https://example.com

@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Apr 11, 2026

@yangyaofei is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

## 问题/错误
When using agent-browser with --auto-connect to control an existing Chrome browser, tab_new and tab_switch commands steal browser focus via Target.activateTarget and Page.bringToFront CDP calls. This disrupts the user who is actively browsing in the same browser instance.

## 发现过程
Tested agent-browser and playwright-cli against a Chrome browser with 100+ tabs. Both tools activate tabs when creating or switching, pulling the user's current tab away. The CDP protocol supports background:true on Target.createTarget which avoids this, but neither tool exposes it.

## 实现方案
Add a --background boolean flag (config: background, env: AGENT_BROWSER_BACKGROUND) that:
1. Passes background:true to Target.createTarget in tab_new - new tabs open without activating
2. Skips Page.bringToFront in tab_switch - tab switches are internal only, no visual focus change

This allows an AI agent to operate tabs in the background while the user continues browsing undisturbed.

## 实现过程
- Added background field to CreateTargetParams (cdp/types.rs)
- Added background to Config, Flags, parse_flags, clean_args (flags.rs)
- Modified tab_new to accept and pass background parameter (browser.rs)
- Modified tab_switch to skip bringToFront when background is true (browser.rs)
- Added background field to DaemonState, initialized from env var (actions.rs)
- Added background to DaemonOptions and apply_daemon_env (connection.rs, main.rs)
- Updated all CreateTargetParams construction sites (state.rs, browser.rs)
- Added --background to help output (output.rs)
- Updated test fixtures (commands.rs)

## 总结
9 files changed, 45 insertions, 11 deletions. All 622 unit tests pass. The flag defaults to false (existing behavior preserved). Users can enable via --background CLI flag, AGENT_BROWSER_BACKGROUND=1 env var, or background:true in agent-browser.json config.
…igate

## 问题/错误
--background only worked when set at daemon startup time. Commands sent
to an already-running daemon with --background had no effect. Also,
the navigate (open) command never called Page.bringToFront, so the tab
wasn't brought to the foreground even in non-background mode.

## 发现过程
Testing showed that a daemon started without --background would ignore
the flag on subsequent commands. The background state was only read from
DaemonState (initialized once at daemon start), not from individual
command JSON. Additionally, handle_navigate lacked bringToFront, so
opening a page didn't activate the tab.

## 实现方案
1. Inject background:true into the command JSON in main.rs before
   sending to the daemon, so each command carries its own background flag
2. Read background from command JSON first (cmd.background), falling
   back to DaemonState.background as default
3. Add Page.bringToFront after navigate when not in background mode

## 实现过程
- main.rs: inject cmd["background"] = true when flags.background is set
- actions.rs handle_tab_new: read background from cmd, fallback to state
- actions.rs handle_tab_switch: read background from cmd, fallback to state
- actions.rs handle_click (new-tab): read background from cmd, fallback to state
- actions.rs handle_navigate: add Page.bringToFront when not background

## 总结
2 files changed, 22 insertions, 4 deletions. Now --background works as a
per-command flag regardless of daemon startup mode.
…igate

## 问题/错误
connect_auto_with_fresh_tab hardcoded background=false, causing focus theft
during auto-connect even when --background was enabled. Also navigate
(handle_open) never called Page.bringToFront, so pages weren't activated.

## 发现过程
Code review identified that connect_auto_with_fresh_tab ignored the
DaemonState.background setting, and handle_navigate lacked bringToFront.

## 实现方案
Pass state.background to connect_auto_with_fresh_tab, and add
Page.bringToFront after navigate when not in background mode.

## 实现过程
- connect_auto_with_fresh_tab: accept background param, skip bringToFront
- auto_launch: pass state.background to connect_auto_with_fresh_tab
- handle_launch: pass state.background to connect_auto_with_fresh_tab
- handle_navigate: add bringToFront when not background

## 总结
1 file changed, 14 insertions, 15 deletions.
@yangyaofei yangyaofei force-pushed the feat/background-mode branch from ce2b7a1 to 4eaf577 Compare April 13, 2026 09:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant