# Screen map

The Screen map shows every screen in your app and the taps that lead between them. Use it to get to a screen, see which screens no flow tests, and start a flow on one.

## Read the map

Each card is a screen, with a picture once Squiggle has seen it. The screen the app opens on is at the top, and under each screen are the screens it opens, joined by a line labelled with the control you tap. Screens from one navigator sit together under its name.

- The screen the app is on now is ringed, and follows the app.
- A screen nobody has reached yet is dashed, and sits below the map.
- Select a screen to draw the way to it from the top, and its other ways in and out.

Zoom with the buttons in the corner, by pinching, or with `⌘` + scroll. **Fit to view** frames the whole map; **Focus** frames the selected screen.

## Where the screens come from

Squiggle combines the screens your app declares, read from React Navigation or Expo Router, with the screens it has seen during flows, agent runs, crawls and your own use. When you open a screen the map doesn’t have yet, such as one behind a sign-in, it is added with its picture. When a screen is renamed or removed, the map drops it.

## Filters

| Filter | Shows |
| --- | --- |
| All screens | Everything. |
| Reachable from here | Screens with a known way there from the current screen. |
| No flow yet | Screens no saved flow reaches. These are your gaps. |

A flow reaches the screens its last run visited. Before it has run, it reaches the screens it names in a `prerequisite`, a route assert or wait, a `navigate` or an `expectRoute`, and the screens its taps are known to open.

## Act on a screen

Select a screen on the map, or from the **Go to screen** menu. The panel shows the way there, the screens it leads to and comes from, the flows that reach it, and the testIDs and labels on it (click one to copy it as a selector). It has four actions:

| Action | What it does |
| --- | --- |
| Go there | Drives the app to the screen, with the same waits as a flow, and says why if it doesn’t arrive. |
| New flow to here | Saves a flow that walks there from the first screen and checks the screen at the end, and opens it in Flows. |
| New agentic flow here | Saves a flow that starts on this screen with an agent step for you to write. See [Find what to test](https://squiggle.sh/docs/agentic-flows/coverage). |
| Crawl from here | Presses each control on the screen, maps every new screen it opens, and comes back for the next one. |

## Fill in the map from the terminal

```shell
squiggle crawl --tour                    # every screen, photographed, and what each control opens
squiggle crawl --tour --from settings    # start from one screen
squiggle crawl --changed                 # only the screens your branch changed
squiggle crawl --tour --only /settings/billing,/orders   # tour these paths too, even unseen ones
squiggle crawl --changed --legibility    # also score each toured screen for legibility
```

A tour photographs each screen and presses each control to learn what it opens. Before pressing a form’s buttons, it fills the fields your saved flows type into, so a sign-in signs in and the screens behind it are mapped too. It never presses controls whose names say they crash, throw an error, reset, clear or stress the app, or sign out, and it closes any link that leaves the app. Press Ctrl-C, or **Stop crawl** in Studio, to stop and keep what it found.

`--only` takes comma-separated paths and tours them as well, including screens the map has never seen. `--legibility`, with `--tour` or `--changed`, scores how easily an agent can drive each screen it tours and prints the score per screen; see [Make controls easy to select](https://squiggle.sh/docs/flows/selectors#make-controls-easy-to-select) for how to raise it.

> **Screens that need parameters**
>
> A crawl never guesses a screen’s parameters, so a screen like `product/[id]` is only mapped when a tap leads to it.
