feat(tabs): reuse an open tab instead of duplicating a page
Testing / remote-protocol-compat (0.15.0) (push) Successful in 42s
Testing / remote-protocol-compat (0.16.0) (push) Successful in 47s
Testing / test (push) Successful in 50s

- Add browser_cli/url_match.py with a canonical URL key for tab matching
- Canonicalize scheme, host, default ports, www., trailing slash, query order
- Support reuse modes none, exact, similar and origin via normalize_mode()
- Pick the closest match when several tabs qualify, preferring identical URLs
- Skip the reload when the reused tab already shows the requested page
- Expose nav.reusable_tab() so callers can look up a tab without side effects
- Accept reuse/reuse_domain/reuse_title in tabs.open(), not just nav.open()
- Add --reuse-exact to nav open and nav open-wait; --reuse is now fuzzy
- Default MCP tabs_open to reuse="similar" and return a reused flag
- Tell MCP agents in the server instructions to reuse before opening
- Document the reuse modes in README for MCP, CLI and Python API
- Cover url_match, SDK reuse paths and MCP reuse behaviour with new tests
- Bump package and extension version to 0.16.9
- Refresh uv.lock for the updated dependency set
This commit is contained in:
2026-10-19 10:47:56 +02:00
parent 6c0f77e416
commit 7cb034dfc2
12 changed files with 600 additions and 203 deletions
+24
View File
@@ -179,6 +179,21 @@ optional `tab_id` and act on the active tab when it is omitted, so a caller
does not need a preceding `browser_tabs_list` round trip. `browser_tabs_close`
reports the tab it closed.
`browser_tabs_open` does not duplicate pages. It takes over an already-open tab
whose URL is nearly the same and reports `reused` next to the tab metadata, so
an agent that re-opens a page keeps working in the tab the user already has.
The `reuse` argument selects the match:
| `reuse` | Matches |
|---------|---------|
| `similar` (default) | Same site and page, ignoring fragment, trailing slash, query order, `www.` and default ports — plus any tab of the site when the requested URL is its root |
| `exact` | Only a character-for-character identical URL |
| `origin` | Any tab of the same site, whatever its path |
| `none` | Never reuse, always open a new tab |
A reused tab is only navigated when it is not already on the requested page, so
no reload throws away page state.
Available tools:
- `browser_tabs_list`, `browser_tabs_open`, `browser_tabs_close`
- `browser_navigate`, `browser_page_info`
@@ -244,6 +259,12 @@ browser-cli nav open https://example.com --focus # bring opened tab/w
browser-cli nav open https://example.com --window work # into a named window
browser-cli nav open https://example.com --group research # into a tab group (name or ID)
# Reuse an open tab instead of duplicating a page
browser-cli nav open https://example.com/app --reuse # nearly identical URL (fragment, trailing slash, query order, www)
browser-cli nav open https://example.com/app --reuse-exact # only a character-for-character match
browser-cli nav open https://example.com/app --reuse-domain # any tab of the same site
browser-cli nav open https://example.com/app --reuse-title "App" # tab whose title contains the text
# Reload
browser-cli nav reload # reload active tab
browser-cli nav reload 1234 # reload tab by ID
@@ -456,6 +477,9 @@ b.nav.search("google", "python asyncio")
tabs = b.tabs.list() # list[Tab]; in multi-browser mode each tab.browser is set
tab = b.tabs.open("https://example.com") # returns a bound Tab object
tab = b.tabs.open("https://example.com", wait=True, timeout=10)
tab = b.tabs.open("https://example.com/app", reuse=True) # reuse a tab with a nearly identical URL
tab = b.tabs.open("https://example.com/app", reuse="origin") # reuse any tab of that site
existing = b.nav.reusable_tab("https://example.com/app", reuse=True) # Tab or None, without touching the browser
active = b.tabs.active() # active Tab object
tab = b.tabs.get(1234) # tab by ID
tab = b.tabs.first("github") # first matching tab or None