---
title: "Annotate your app and let agents test it"
url: "https://docs.alisx.com/how-to/alis-build/watch-and-help-your-agents-browser/"
---
# Annotate your app and let agents test it

Open the app your agents are building in your own browser, point at what should change, and let the agents test it there or in a browser of their own, signed in as you.

A workstation serves every port at an address of its own (`https://<port>-<id>-ws.<org>.alis.dev`, listed in the ports bar at the top of the terminal page, and what `alis preview` and your dev server's "open" link go to). Every address asks for the platform sign-in: you, or the people you share that port with. Every page it serves carries the **Alis toolbar**, a small bar at the bottom right: the Alis mark opens a menu, the crosshair starts Annotate. The agents' own browsers are private headless Playwright browsers on the workstation; there is no shared Chrome any more.

## Prerequisites

- A workstation on the current image (`alis workstation get <id> --json` says `currentImage: true`; else `alis workstation restart <id>`).
- You are the workstation's owner, or somebody the owner shared the port with.

## The Alis toolbar

Open the port's address in your browser. The bar sits at the bottom right of every page:

- **The Alis mark** opens the menu: who you are signed in as, which agent session receives the notes left on this port's pages, **Agent activity**, **Pause agents in this tab**, and, for the owner, **Sign my agents in to this app**, whom the port is shared with, and a link to the workstation page.
- **The crosshair** starts Annotate (also Alt+Shift+A; Esc leaves). Hide the bar for the tab from the menu; Alt+Shift+A brings it back.

## Who receives notes

Each port sends its notes to one agent session: a terminal on the workstation or a herdr pane with a coding agent in it, or a Claude Code session that runs in neither, such as one the Claude desktop app starts on the workstation over SSH.

- `alis run` attaches the port it serves to the session it runs in, so an agent that starts the app gets the notes (`alis run --port <n>` names the port when the service folder does not).
- Otherwise the workstation attaches the terminal, pane or agent session the server was started in.
- Or choose one yourself: the **Ports** panel on the terminal page has a session for every port (the toolbar's menu links there).

A session the Claude desktop app started has no terminal on the workstation. The **Ports** panel lists it by its conversation's name, and its notes arrive in the app's conversation. It stops when the app disconnects and resumes when the app is back: until then the port shows the session as away and keeps a note as it does with no agent attached. A session that stays away for a day is let go.

Every note carries the email of the person who made it, the owner's included, taken from their sign-in; the agent sees it on the line and in the note's file, and nothing in the page can forge it. With no agent attached, the owner's note is copied to their clipboard and saved on the workstation for the next agent (`preview_notes`); a reviewer's is saved and they are told so. Attach a session and the saved notes are there for it.

## Send the agent a note

1. Press the crosshair, or Alt+Shift+A. Allow the browser to share this tab when it asks, once per page: that is where the screenshot comes from, for your notes and for your agents, and it stays allowed until you leave the page, press the browser's own Stop sharing, or pause agents. Decline it and notes go without one.
2. Point at an element; the page outlines it. Click it (shift and drag for an area). A comment box opens beside it, saying which agent it goes to and as whom.
3. Write what should change. **Send** types one line into that agent's terminal and presses Enter; **Stage** types it and leaves Enter to you:

    ```text
    > [preview] from you@example.com: main > button.pay "Pay now" on https://5173-<id>-ws.<org>.alis.dev/cart (source: src/Pay.tsx:12) | make it full width (screenshot: ~/.alis/browser/notes/note-1.png) (note: ~/.alis/browser/notes/note-1.json)
    ```

4. The agent reads the line, the screenshot and the note's file (which also holds the element's own markup and the page's last console errors), makes the change, and checks the page.

Notes and their screenshots stay in `~/.alis/browser/notes/` for a week.

## Share a port

To gather feedback on what an agent is building, share the port with people:

```bash title="Terminal, or an agent's"
alis run --share reviewer@example.com --share pm@example.com
```

or add them in the **Ports** panel. They open the port's address, sign in as themselves, and get the same toolbar: their notes arrive in the port's agent session with their email on them. Somebody the port is not shared with sees a page saying whom to ask. A share of the port is not a share of the workstation's terminals, and the other way round.

## Let agents test in your browser

Any page of the app you have open from its port address is also a page your agents can drive, the owner's and a shared reviewer's alike: the toolbar keeps a line back to the workstation, and an agent can navigate it, read it as an accessibility tree, click, type, pick options, run a snippet, read the console and wait for something to appear - in your browser, with your logins. Ask the agent to "check the sign-up form in my browser" and it will.

- The bar says who is driving while it happens. **Pause agents in this tab**, in the menu, stops it for that tab; the agent is told why. **Resume agents** lets them back in.
- A screenshot needs the tab's picture: once you have allowed the share for Annotate, the agent uses it too; otherwise an **Allow** button appears in the page and the browser asks once to share the tab. **Not now** sends the agent on without one; its snapshot of the page works regardless.
- An agent can only reach pages on your workstation's own addresses. A tab you take to another site has no toolbar and cannot be driven.

Agents do this with the `page_*` tools of the `alis-preview` MCP server (`page_tabs`, `page_snapshot`, `page_click`, `page_type`, `page_navigate`, `page_evaluate`, `page_screenshot`, `page_console`, `page_wait_for` and a few more); `page_tabs` names whose each tab is.

## Follow and message the agent

**Agent activity** in the Alis menu shows the conversation of the agent session attached to the port - what was asked, what the agent answered, the steps it took - for the owner and for everybody the port is shared with, refreshed every few seconds. The box at its foot sends the agent a message about the page as a whole, the way a note does for a part of it; **‹** goes back to the menu.

Keys typed into the toolbar - a note, a message - stay in the toolbar: the app's own keyboard shortcuts do not see them.

## Share your sign-in with agents

An agent's own browser is signed into nothing. When it tests the app itself - a page you do not have open, a flow it wants to run end to end - and the app needs a sign-in, give it yours:

1. Open the app from its port address and sign into it, as you would.
2. Open the Alis menu and press **Sign my agents in to this app**. The page's cookies for this port and its localStorage are saved on the workstation, for the agents' browsers alone, as `~/.alis/browser/signin/<port>.json`, and the agent session attached to the port (Claude Code or Codex) is told where it is and how to load it.
3. The agent loads it into its browser (`browser_set_storage_state` in its `playwright` tools; `agent-browser --state` for the Antigravity CLI) and opens the app at `http://localhost:<port>`, signed in as you - not the port's public address, which asks for the platform sign-in. `preview_ports` tells it which ports have one.

An agent that reaches a sign-in it cannot do asks: every tab you have open of the app shows "<agent> is waiting for you: <reason>" with **Share sign-in and continue**, which does step 2 and lets the agent carry on, and **Dismiss**. The menu says when a sign-in was shared; **Forget** removes it, and so does the × beside it in the **Ports** panel.

A sign-in is per port, and the owner's to share. Playwright's storage state carries cookies and localStorage; an app that keeps its session in sessionStorage or IndexedDB needs its own path.

## How it is put together

The toolbar is a script the workstation's port proxy puts into the pages it forwards, the way a dev server puts its own client in. It talks to the page's own origin, under `/__alis/annotate/`, with the sign-in the port's gate already gave you, so no cookie crosses an origin; a page whose own security policy forbids even that is left as it is. The agents' side is the shell's loopback local API on the workstation, which their `alis-preview` MCP server talks to. The agents' browsers are Playwright's own, one per agent, with a persistent profile each.

Related: [Use workstations](https://docs.alisx.com/how-to/alis-build/use-workstations.md), [Preview a service frontend](https://docs.alisx.com/how-to/alis-build/preview-a-service-frontend.md), [alis run](https://docs.alisx.com/reference/cli/run.md).
