← Back to docs
# Headless documentation
Persistent browser control for agents, without Playwright scripts or screen coordinates.
## First run
```sh
headless start
headless session create qa
headless --session qa visit localhost:3000/designers/dashboard
headless --session qa inspect --context summary --task "finish onboarding"
```
On macOS, agent startup opens visible browser windows behind the app currently in use. Change the persistent default with `headless config set startup-presentation foreground` or restore background startup with `headless config set startup-presentation background`; inspect it with `headless config get startup-presentation`. `headless start --foreground` and `headless start --background` are one-launch overrides. Settings and overrides apply only when launching a new host and do not reorder an already-running host.
## QA workflow
```sh
headless --session qa record start --fps 10
headless --session qa click --role button --name Continue
headless --session qa wait --url /next --settled
headless --session qa record stop --output dashboard-flow.mp4
headless --session qa qa report
```
## Command groups
### Host lifecycle
```sh
version | --version
start [--background|--foreground] | status | stop | runtime
config get startup-presentation
config set startup-presentation background|foreground
session create [NAME] | session list | session close NAME
capabilities
```
`start` launches the host if it is not already running. `status` and `stop` control it afterwards. `runtime` reports which engine is active and where it came from.
### Navigation and interaction
```sh
visit URL
inspect [--context summary|outline|text|actions|full] [--task TEXT]
[--within @rN] [--limit N] [--budget TOKENS] [--depth N] [--text]
click REF | click --role ROLE [--name NAME]
fill REF TEXT | fill REF -- TEXT_WITH_LITERAL_FLAGS | press KEY
scroll [up|down|top|bottom] [--amount PX]
back | reload
wait [--settled] [--url PATTERN] [--text TEXT] [--timeout MS]
tour [--full-page] [--pace PX_PER_SECOND]
```
`visit` accepts HTTP/HTTPS only. Bare hostnames normalize to HTTP (`localhost:3000` → `http://localhost:3000`). URLs carrying credentials are rejected. Downloads and unsafe schemes never navigate.
### Capture and evidence
```sh
capture-info
screenshot [REF | --role ROLE --name NAME | --full-page] [--format png|jpg|jpeg] [--output FILE] [--clipboard]
screenshot --full-page --format pdf [--output FILE.pdf]
screenshot --every-viewport|--by-section [--format png|jpg|jpeg] [--output PREFIX]
artifacts list
record start [--fps N] [--format mp4|mov|webm|gif] [--quality fast|balanced|high] [--output FILE]
record status | record stop [--output FILE]
qa report | qa clear
report create [--output REPORT.json]
```
Screenshots and recordings become private artifacts in the per-user store, created `O_EXCL` with `0600`. They never overwrite and never leave it unless you copy them.
### Diagnostics
```sh
console list [--level LEVEL] [--limit N]
network list [--failed] [--status CODE] [--limit N]
network get REQUEST_ID
network emulate [--offline] [--latency MS] [--download-kbps N] [--upload-kbps N]
network mock set URL --body BODY [--status CODE] [--content-type MIME]
network mock clear
styles get REF | styles get --role ROLE [--name NAME] [--property CSS_PROPERTY]
cookies list [--values]
storage list [--scope local|session|all] [--values]
visual compare BEFORE.png AFTER.png [--output DIFF.png]
performance get | animations list
flow start | flow stop [--output FLOW.json] | flow run FLOW.json
```
`network emulate` and `network mock` are Chromium-engine features. WebKit returns `UNSUPPORTED_CAPABILITY` instead of approximating them.
## Context pruning
Inspection is progressively disclosed instead of forcing an entire page into an agent prompt. Start with `--context summary`, use `--context outline` to receive structural region references such as `@r4`, then inspect only that region with `--within @r4`. `--context text` returns bounded semantic snippets and `--context actions` returns visible executable controls. `--task`, `--limit`, `--budget`, and `--depth` rank and bound every focused response; `omitted` and `contextStats` make pruning explicit. `--context full --text` remains the explicit broad-page escape hatch.
## Scrollable page evidence
For scrollable-page QA, use `screenshot --every-viewport --output PREFIX` for up to 80 viewport-height scroll stops, always including the final bottom position. Results report `truncated` and `totalPoints` when a longer page is bounded. Use `screenshot --by-section --output PREFIX` to capture around visible headings and sections. Series capture restores the original scroll position. Add `--format jpg` for JPEG series; PDF requires `--full-page` and is not a series format. The output prefix creates numbered artifacts such as `dashboard-scroll-001.png` or `dashboard-scroll-001.jpg`.
## Safety
- No TCP control or Chromium debugger port.
- `0600` Unix socket in a `0700` per-user directory, with peer-UID checks.
- Chromium control over inherited fd 3/4 pipes.
- Isolated browser helpers and allowlisted, bounded commands.
- `0600` artifacts in a `0700` per-user directory; no path traversal or overwrite.
- HTTP/HTTPS navigation only; no file URLs, credentials, external application schemes, arbitrary JavaScript, or shell execution.
- An agent session starts on a clean page and abandons any previously opened local-file or application page before it can be inspected.
- Remote executables, installers, scripts, libraries, and disk images are blocked by extension. Archives are reported as a caution and are never downloaded or unpacked.
- Page downloads are denied; only explicit Headless artifacts are written.
- Non-root, sandboxed Chromium on Linux.
## Platforms
- macOS 13+: visible WKWebView windows.
- Linux (Ubuntu and other distros): sandboxed Chromium, headless by default or visible with `DISPLAY`.