Repository navigation
feat(browser): tabs, reload and a typed address in the browser panel - #62
Merged
Merged
Conversation
The page was always 1280 x 800, so a tall panel showed it small with an empty area below. While an app connection watches, `browser.resize` tells the daemon the room its panel has for the page: the page keeps its 1280 of width, so sites keep their desktop layout, and takes the height that gives it the room's shape, between 600 and 2000. Frames, the owner's points and the bot's scroll follow the size the page has. When the last one watching stops, the page is 1280 x 800 again. Spec 21.3, 21.7, 21.8 and 21.10 say so, and section 19 records what the real Edge does when the size changes with a page open.
The panel measures the room it has under the address row and asks for a page of that shape, 300 ms after the room stops changing. The picture is shown as large as fits, in the page's shape. Notices that come and go (the request for a hand, the bar that says the owner is in control, the line about what the bot did) do not count: they never resize the page. The preview's pages are drawn at the size the panel asks for.
Edge drops the frame of the new size while older frames wait to be confirmed, and a page that stands still sends no other: the panel kept the picture of the old size. After sizing the tabs the daemon waits for those frames to be confirmed and starts the screencast over, which sends one. The test with the real Edge now waits for a frame after each change; it failed about half the runs before.
…en tabs `BrowserState.tabs` is now the list of open tabs, in the order they opened, each with its title, address and whether it is the active one, instead of a count. Edge without a window never tells a page's title, so the daemon reads `document.title` in the isolated world when a page loads. New methods for the connection watching a bot's browser: - `browser.reload`, at any time: it does not move the bot, and the bot's next result says the owner reloaded the page. - `browser.newTab`, `browser.switchTab` and `browser.open`, only with the browser in the owner's hands: they change where the bot works. They go in the same queue as the owner's mouse and keyboard, in order, and the bot's tools wait until the queue is empty. The address the owner types opens only as http or https. When the owner gives the browser back on another tab than the one the bot was on, the bot reads before it acts: a tool that would click, type, press, scroll or go back does nothing and says so; `browser_look`, `browser_screenshot`, `browser_open` and the answer to `browser_ask_owner` carry a note with the page. A browser counts as open, and a new tab gets its address, only once the tab is set up: before that a fast page could load without the daemon seeing its events. When the active tab closes, the daemon activates the one it goes back to, so the browser shows the same tab. Spec 21.3, 21.7, 21.8, 21.10 and 21.11 (N3.2); section 19 records what Edge 154 does and what is left to see with real Claude Code.
The panel shows a tab for each page the bot has open, with its title and site, in place of the count. They only show while the browser is the bot's; with it in the owner's hands a click switches tabs and + opens a new one, with the cursor in the address row, where Enter takes the tab to what the owner typed. The bar that says the owner is in control tells that the bot goes on in the tab left open. The address row has a reload button, which works at any time. FakeBotloft has the tabs and the four new methods, and the preview's Scout has three tabs and waits while the owner has its browser.
This was referenced Sep 30, 2026
Merged
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.
Stacked on #53 (the page filling the panel): until that one merges, this diff shows its three commits too. The two commits of this PR are the last two.
What
The panel only said "6 tabs". Now the owner sees the tabs the bot opened, reloads the page, and with the browser in their hands switches tabs, opens a new one and types where it goes.
BrowserState.tabsis the list of open tabs in the order they opened (BrowserTab {id, title, url, active}), not a count. Edge without a window tells a tab's new address but never its title, so the daemon readsdocument.titlein the isolated world when a page loads.browser.reload, from the connection watching the browser.browser.newTab,browser.switchTab,browser.open, only from the connection that has the browser in the owner's hands. They go in the same queue as the owner's mouse and keyboard, in order.+at the end), a reload button (RotateCw) in the address row, and the address becomes a field while the owner is in control: Enter goes there, Esc drops what was typed.+opens a blank tab with the cursor already in the address. Texts in en, pt-BR and es.Decisions (spec 21.10)
refgives the usual error and it reads again.browser_click,browser_type,browser_select,browser_press,browser_scroll,browser_back) does nothing and answers that the owner switched tabs and to callbrowser_look.browser_look,browser_screenshot,browser_openand the answer tobrowser_ask_ownerwork and carry "The owner switched tabs while they had your browser. This is the tab that is open now.", once. Given back on the same tab, nothing is said.httpandhttps; without a scheme,https://. Sites the owner opens still do not count as allowed for the bot (as before).controlandaskcame: app and daemon ship together and the app updates an older daemon before connecting.tabsdoes change type, so an app and a daemon from different builds of the same version do not match.Found on the way
Page.enable, and the daemon missed its events. Now the tab has to be set up first (also a new tab of the owner's before it gets an address).Tests
crates/botloftd/tests/browser_tabs.rs, with the real Edge: reload with and without watching and what the bot reads; the tab list and titles; a new tab, addresses that open and that are refused, switching and the frames that follow; and the bot after the owner gave the browser back on the same tab, on another tab (a tool that acts, a tool that reads) and throughbrowser_ask_owner.tabs.test.tsxwithFakeBotloft: the tabs by title and site, inert without control, reload at any time, and with control switching, a new tab with the cursor in the address, Enter, Esc and an address that is refused.cargo fmt,clippy -D warnings,cargo test --workspaceandpnpm checkpass. The browser tests ran 10 times in a row with the whole daemon suite.pnpm dev): Scout has three tabs; taking control, switching,+, typing an address and giving it back.Still to see with real Claude Code
Spec 19 has the row "Abas nas mãos do dono com o Claude Code real", marked manual:
browser_look), read the new tab, and either go on there or open the page it needs again, without acting blindly.