Skip to content

feat(tabs): add --filter and --limit to tab list - #2515

Open
Rutvij97 wants to merge 4 commits into
vercel-labs:mainfrom
Rutvij97:feat/tab-list-filter-limit
Open

Rutvij97 wants to merge 4 commits into
vercel-labs:mainfrom
Rutvij97:feat/tab-list-filter-limit

Conversation

@Rutvij97

@Rutvij97 Rutvij97 commented Nov 9, 2026

Copy link
Copy Markdown

Fixes #2095.

tab list returns every open tab. When agent-browser is attached to a daily browser over --cdp or --auto-connect, that can be dozens of rows, and an agent pays for all of them in tokens when it only wants one or two. This adds two optional, composable controls from the issue's first suggestion.

What changes

  1. tab list --filter <text> keeps tabs whose title or URL contains <text>, ignoring ASCII case (the same folding read --filter uses). It is a literal substring, not a glob or regex. --filter=<text> also works, and is how you filter on text that starts with --.
  2. tab list --limit <n> returns at most n tabs in tab order, applied after the filter. n must be 1 or more.
  3. Both flags work after tab or tab list, combine in any order, and leave the JSON shape unchanged. A filter that matches nothing returns []; text output prints No matching tabs.
  4. MCP parity: agent_browser_tab_list accepts optional filter (string) and limit (integer, minimum 1). The handler goes through the normal CLI parser using the attached --filter= / --limit= form, so a filter value that looks like a flag is passed through as text. packages/@agent-browser/sandbox/mcp-tools.json was regenerated with pnpm mcp-tools:sync.
  5. Docs: --help in output.rs, docs/content/docs/commands.mdx (with the matching docs-edits.json fixture entry), and skill-data/core/references/commands.md.

Stale titles in background tabs

While writing the e2e test I found that background tabs kept the title they had while loading (usually the URL), so a title filter missed them. Chrome does not reliably send Target.targetInfoChanged when a background tab sets document.title, but Target.getTargets returns the current titles. tab list now calls a new BrowserManager::refresh_page_target_infos, which runs Target.getTargets with a 2 second timeout and updates the tracked pages only. If the call fails or times out, the cached values are used as before. This also fixes stale titles in plain tab list output.

Behavior change to review

tab list previously ignored arguments it did not recognize. It now rejects unknown options and extra positional arguments with an error, the same way read does. tab, tab list, tab new, tab close, tab <n> and tab <id> route exactly as before (covered by parser tests).

Tests

  • cargo test --locked: 2136 passed, 0 failed, 213 ignored. New unit tests cover the parser (both forms, order, = values, flag-like text, missing values, empty filter, limit 0 / negative / fractional / non-numeric / overflow, unknown flags, extra positionals, routing of the other tab subcommands), filtering in browser.rs (URL and title match, case, filter before limit, no match, rows keep every field and active), the target refresh (updates tracked pages only, keeps the cache when the browser does not answer), and the MCP tool (schema, argument mapping, invalid limit values rejected).
  • cargo fmt --check and cargo clippy -- -D warnings: clean.
  • e2e against real Chrome (cargo test e2e_tab -- --ignored --test-threads=1): all 13 tab tests pass, including the new e2e_tab_list_filter_and_limit. Other e2e tests that call tab list (pin, wedge diagnostics, externally opened tab, a11y) also pass. The recording e2e tests need ffmpeg, which was not installed on my machine; they fail identically on unmodified main.
  • Docs: pnpm --filter docs test (54/54), type-check, build and test:routes (439/439) pass. Package tests: launcher 4/4, sandbox 27/27, eve 37/37.
  • Manually checked the built binary: filter, = form, limit, empty result, --limit 0 error, extra argument rejected, missing value, help text, and an MCP stdio call with filter and limit (limit: 0 returns -32602).

Notes

  • feat(tabs): identify each tab's browser profile with tab list --profiles #2089 (--profiles) touches nearby tab and help code but is a separate feature; whichever lands second should rebase cleanly.
  • AI disclosure: this change was written with Claude Code (Claude Opus 5.5). Codex was used as a read-only reviewer for the design. I reviewed the full diff line by line and ran every test listed above locally.

🤖 Generated with Claude Code

Rutvij97 and others added 4 commits November 9, 2026 23:41
`tab list` returns every open tab, which is noisy when attached to a
daily browser with dozens of tabs. `--filter <text>` keeps tabs whose
title or URL contains the text (ASCII case-insensitive) and `--limit <n>`
caps the result after filtering, in tab order. Both also work after a
bare `tab` and accept the attached `--opt=value` form. Unknown options
and stray arguments are now rejected instead of silently ignored.

The active flag is computed from each tab's real position, so it stays
correct when earlier tabs are filtered out.

`tab list` also refreshes titles and URLs from Target.getTargets (2s
best-effort timeout) because Chrome does not reliably emit
Target.targetInfoChanged when a background tab sets its title, which left
background tabs listed with their loading-time title.

Refs vercel-labs#2095

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The tool forwards both as attached CLI options, so a filter such as
"--json" stays literal text. Empty filters and non-positive limits are
rejected as invalid params. The sandbox tool catalog is regenerated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Serves pages whose titles are set by script and never appear in their
URLs, so the title match is exercised on background tabs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

@RebelCorp-Official is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

@Rutvij97
Rutvij97 force-pushed the feat/tab-list-filter-limit branch from a3f421b to c5d2688 Compare November 10, 2026 07:46

This branch has not been deployed

No deployments
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.

tab_list has no filter or limit, returns every tab of every browser profile

1 participant