> ## Documentation Index
> Fetch the complete documentation index at: https://tesser.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# A browser on a box

> Let the agent look at the page from the workbench, at the same address you open on the laptop

The agent that runs your boxes can look at the pages they serve. When its
harness has a browser on the laptop, it opens the address `tesser dev`
printed, `http://<box_id>.localhost:<port>`, and that is the whole story.
When it does not, or when the browser should outlive the laptop's lid, it
runs one on the worktree's workbench instead. The workbench reaches every
box in the org at that same address (see
[localhost](/docs/localhost#every-box-has-an-address)), so nothing has to be
tunnelled, declared, or wired for it.

## Setup

Once per workbench. This installs
[agent-browser](https://github.com/vercel-labs/agent-browser), a CLI that
drives a headless Chrome and keeps it running between calls, and the Chrome
it needs.

```sh theme={"theme":"css-variables"}
tesser exec -- bash -c 'sudo npm i -g --prefix /usr/local --allow-scripts=agent-browser agent-browser && agent-browser install --with-deps && mkdir -p ~/.agent-browser && echo "{\"args\":\"--no-sandbox\"}" > ~/.agent-browser/config.json'
```

Three things in there are box facts rather than agent-browser facts.
`--allow-scripts` is npm 11 asking permission for the package's postinstall,
which downloads the platform binary. `--prefix /usr/local` puts the binary
where `exec` finds it. And `--no-sandbox` in the config is Ubuntu 24.04:
it restricts unprivileged user namespaces, and Chrome refuses to start
without them unless told to skip its sandbox. Writing the flag to
`~/.agent-browser/config.json` once beats passing it on every call.

The workbench keeps all of it until `tesser rm`, sleep included.

## Looking at a page

```sh theme={"theme":"css-variables"}
BOX=$(tesser dev web)
tesser exec -- agent-browser open "http://$BOX.localhost:3000"
tesser exec -- agent-browser snapshot                      # the page as a tree of refs
tesser exec -- agent-browser click @e3
tesser exec -- agent-browser fill @e5 "hello"
tesser exec -- agent-browser get text body
tesser exec -- agent-browser screenshot /tmp/page.png
tesser exec -- cat /tmp/page.png > page.png                # bring it home
```

Each `exec` is a round trip of about a second. The browser is one process
on the workbench that agent-browser starts on the first command and keeps
around, so the page, its cookies, and a sign-in persist across calls, and
across a `tesser sync` of the box being looked at. `agent-browser --help`
lists everything else it can do; `agent-browser close` ends the session.

Any box in the org is reachable this way, not only your own: a teammate's
dev box, or the shared instance of `api` at `http://api.localhost:<port>`.
A port the box does not declare is refused. Bare `localhost:<port>` on the
workbench is the workbench itself, which runs no server.

## When the workbench sleeps

A workbench sleeps after ten minutes without a command from the laptop,
and the browser is a user process, so it goes with the box. The next `exec`
wakes the box (about a minute) and the next `open` starts a fresh browser;
the install stays. While the agent is driving it, every `exec` resets the
idle clock.
