# afhttp CLI reference
<!-- Generated by `afhttp --docs`. Do not edit by hand. -->
Give your AI agent its own private browser — so it reads the real page, past logins and bot walls, without ever touching yours.
`afhttp` is compiled from a closed `cli-spec-v1` registry: one source for argv parsing, typed invocation values, which parameter combinations are legal, output contracts, and help. An invocation runs only when it matches exactly one registered combination.
## Global arguments
AFDATA registers these itself, so the syntax in [Commands](#commands) leaves them out.
| Argument | Where | What it does |
|---|---|---|
| `--help` | every command | Every legal shape of that command, complete, plus its subcommands. JSON by default; `--output plain` for a terminal. |
| `--version` | afhttp only | Name, version, and build identity as one protocol result. |
| `--docs` | afhttp only | This document, rendered from the registry. |
| `--output <FORMAT>` | per output contract | Render as json (default `json`). |
| `--output-to <DESTINATION>` | per output contract | Route results and diagnostics to split, stdout, stderr (default `split`). |
| `--stdout-file <PATH>`, `--stderr-file <PATH>` | per output contract | Append that stream to a file instead. |
Success output is protocol events, on those terms, unless a command's own **Output** line says otherwise.
A **shape** is one legal set of arguments that may appear together, under a stable id. Where a command has more than one, each id is a heading below. `--help` returns them all at once, so discovering a command costs one call; there is no recursive mode across commands, and this document is that view.
## Commands
- [`afhttp capabilities`](#afhttp-capabilities) — Query a host's /capabilities endpoint.
- [`afhttp cdp`](#afhttp-cdp) — Send one raw CDP method to a tab and return its result.
- [`afhttp container install`](#afhttp-container-install) — Build the host image if missing, run the container, and print the client command.
- [`afhttp container logs`](#afhttp-container-logs) — Capture the container logs, or stream them raw.
- [`afhttp container status`](#afhttp-container-status) — Report whether the host is running, with its endpoint and client command.
- [`afhttp container uninstall`](#afhttp-container-uninstall) — Stop and remove the container.
- [`afhttp fetch`](#afhttp-fetch) — Fetch a URL over HTTP or a real browser and write the requested artifacts.
- [`afhttp health`](#afhttp-health) — Query a host's /health endpoint.
- [`afhttp host`](#afhttp-host) — Run the browser host: launch a backend browser and serve /cdp for clients.
- [`afhttp panel`](#afhttp-panel) — Mint a short-lived takeover URL for a running takeover-ready host.
- [`afhttp profile cookies`](#afhttp-profile-cookies) — Show the non-expired cookies in a profile's jar, with values redacted.
- [`afhttp profile delete`](#afhttp-profile-delete) — Delete a profile and all of its on-disk state.
- [`afhttp profile downloads`](#afhttp-profile-downloads) — List files captured in a profile's browser download directory.
- [`afhttp profile info`](#afhttp-profile-info) — Show one profile's size, last use, and lock state.
- [`afhttp profile list`](#afhttp-profile-list) — List the on-disk profiles under the profiles root.
- [`afhttp profile lock-status`](#afhttp-profile-lock-status) — Report whether a profile is currently locked by a running host.
- [`afhttp profile prune`](#afhttp-profile-prune) — Delete profiles whose last use is older than a cutoff.
- [`afhttp skill install`](#afhttp-skill-install) — Install or refresh the Agent-First HTTP skill.
- [`afhttp skill status`](#afhttp-skill-status) — Show whether the Agent-First HTTP skill is installed, valid, and up to date.
- [`afhttp skill uninstall`](#afhttp-skill-uninstall) — Remove an afhttp-managed Agent-First HTTP skill.
- [`afhttp tabs close`](#afhttp-tabs-close) — Close one CDP target by its target id.
- [`afhttp tabs list`](#afhttp-tabs-list) — List the CDP targets currently attached to a host.
- [`afhttp ui takeover`](#afhttp-ui-takeover) — Put the takeover panel in front of a person and block until that session ends.
- [`afhttp upload`](#afhttp-upload) — Upload a local file into a browser tab's file input via DOM.setFileInputFiles.
### `afhttp capabilities`
Query a host's /capabilities endpoint.
```
afhttp capabilities [--endpoint-url <URL>] [--token-secret <SOURCE>]
```
| Argument | Meaning |
|---|---|
| `--endpoint-url` | CDP endpoint of a running host; falls back to AFHTTP_ENDPOINT_URL, then to the local afhttp-host container |
| `--token-secret` | Token for a protected host; falls back to AFHTTP_TOKEN_SECRET, then to the discovered host's own token (the value, or where to read it: env:NAME, file[+FORMAT]:PATH#DOT_PATH, container:NAME, literal:VALUE) |
### `afhttp cdp`
Send one raw CDP method to a tab and return its result.
```
afhttp cdp <METHOD> [--endpoint-url <URL>] [--token-secret <SOURCE>] --tab <TARGET_ID> [--params <JSON|@->] [--wait-event <EVENT:TIMEOUT>]
```
| Argument | Meaning |
|---|---|
| `METHOD` | CDP method name |
| `--endpoint-url` | CDP endpoint of a running host; falls back to AFHTTP_ENDPOINT_URL, then to the local afhttp-host container |
| `--token-secret` | Token for a protected host; falls back to AFHTTP_TOKEN_SECRET, then to the discovered host's own token (the value, or where to read it: env:NAME, file[+FORMAT]:PATH#DOT_PATH, container:NAME, literal:VALUE) |
| `--tab` | CDP target id to drive |
| `--params` | Method parameters as a JSON literal, or @- to read them from stdin |
| `--wait-event` | Wait for a CDP event before exiting, for example Page.loadEventFired:5s |
### `afhttp container install`
Build the host image if missing, run the container, and print the client command.
#### `container-install` — Build from the release pinned to this binary's version
```
afhttp container install [--runtime <docker|podman|apple>] [--name <NAME>] [--port <PORT>] [--profile <NAME>] [--shm-size <SIZE>] [--takeover-provider <off|kasmvnc>] [--with <lightpanda|fingerprint-chromium|camoufox|chrome|brave|kasmvnc>...] [--rebuild] [--reveal-token-secret] [<HOST_ARG>...]
```
#### `container-install-from-source` — Compile from a source checkout, which always rebuilds
```
afhttp container install [--runtime <docker|podman|apple>] [--name <NAME>] [--port <PORT>] [--profile <NAME>] [--shm-size <SIZE>] [--takeover-provider <off|kasmvnc>] [--with <lightpanda|fingerprint-chromium|camoufox|chrome|brave|kasmvnc>...] --from-source [--context <DIR>] [--reveal-token-secret] [<HOST_ARG>...]
```
Arguments across every shape above:
| Argument | Meaning |
|---|---|
| `--runtime` | Container runtime; auto-detected when omitted, then AFHTTP_CONTAINER_RUNTIME |
| `--name` | Container name |
| `--port` | Host CDP port, published on 127.0.0.1 |
| `--profile` | Initial profile inside the container; defaults to - for ephemeral |
| `--shm-size` | Chromium /dev/shm size; defaults to 1g, or 2g when takeover is on |
| `--takeover-provider` | Takeover provider for the built host; off builds a lean headless host |
| `--with` | Extra image component to build |
| `--rebuild` | Rebuild the image even if it already exists |
| `--from-source` | Compile the image from a source checkout instead of a prebuilt release |
| `--context` | Source checkout for --from-source; defaults to the current directory, then this binary's own checkout |
| `--reveal-token-secret` | Include the long-lived host token in the result instead of redacting it |
| `HOST_ARG` | Arguments forwarded to `afhttp host` inside the container, after -- |
### `afhttp container logs`
Capture the container logs, or stream them raw.
#### `container-logs` — Capture the logs to a file and return a JSON summary of the tail
```
afhttp container logs [--runtime <docker|podman|apple>] [--name <NAME>]
```
#### `container-logs-raw` — Forward the runtime's own log bytes; the only shape that can follow
```
afhttp container logs [--runtime <docker|podman|apple>] [--name <NAME>] [--follow] --raw
```
Output differs by combination:
- protocol events; `--output` json (default `json`), `--output-to` split/stdout/stderr (default `split`); redirect with `--stdout-file` or `--stderr-file`
- raw bytes on success; rejects `--output` and `--output-to`; redirect with `--stdout-file` or `--stderr-file`. Failures are still strict JSON on stderr
Arguments across every shape above:
| Argument | Meaning |
|---|---|
| `--runtime` | Container runtime; auto-detected when omitted, then AFHTTP_CONTAINER_RUNTIME |
| `--name` | Container name |
| `--follow` | Keep following the log output |
| `--raw` | Stream raw runtime logs instead of returning a JSON summary |
### `afhttp container status`
Report whether the host is running, with its endpoint and client command.
```
afhttp container status [--runtime <docker|podman|apple>] [--name <NAME>] [--port <PORT>] [--reveal-token-secret]
```
| Argument | Meaning |
|---|---|
| `--runtime` | Container runtime; auto-detected when omitted, then AFHTTP_CONTAINER_RUNTIME |
| `--name` | Container name |
| `--port` | Published host port, used to format the endpoint and client command |
| `--reveal-token-secret` | Include the long-lived host token in the result instead of redacting it |
### `afhttp container uninstall`
Stop and remove the container.
```
afhttp container uninstall [--runtime <docker|podman|apple>] [--name <NAME>] [--purge]
```
| Argument | Meaning |
|---|---|
| `--runtime` | Container runtime; auto-detected when omitted, then AFHTTP_CONTAINER_RUNTIME |
| `--name` | Container name |
| `--purge` | Also remove the built image and the cached context |
### `afhttp fetch`
Fetch a URL over HTTP or a real browser and write the requested artifacts.
#### `fetch` — Fetch with no request body
```
afhttp fetch <URL> [--endpoint-url <URL>] [--token-secret <SOURCE>] [--browser <auto|chromium|chrome|fingerprint-chromium|edge|brave|lightpanda|camoufox>] [--browser-bin <PATH>] [--render <none|auto|always>] [--tab <new|<id>>] [--profile <NAME>] [--wait <SPEC>] [--header <NAME:VALUE>...] [--cookie <NAME=VALUE>...] [--user-agent <UA>] [--evaluate-after-wait <JS>...] [--want <body|rendered_html|text|content|content_json|screenshot|network|console|observation|storage>...] [--method <METHOD>] [--network-bodies <off|xhr|all>] [--network-body-max-bytes <BYTES>] [--readiness-idle-ms <MS>] [--readiness-stable-ms <MS>] [--readiness-min-text-bytes <BYTES>] [--no-network-redact] [--out <DIR>] [--cookie-jar <PATH>] [--no-cookie-jar] [--observe-main-wait-ms <MS>] [--max-response-bytes <BYTES>] [--retry <N>] [--backoff-ms <MS>] [--proxy-url <URL>] [--ca-cert <PATH>] [--tls-insecure] [--timeout-ms <MS>] [--capture-ws] [--capture-sse]
```
#### `fetch-data` — Fetch with a raw request body from --data
```
afhttp fetch <URL> [--endpoint-url <URL>] [--token-secret <SOURCE>] [--browser <auto|chromium|chrome|fingerprint-chromium|edge|brave|lightpanda|camoufox>] [--browser-bin <PATH>] [--render <none|auto|always>] [--tab <new|<id>>] [--profile <NAME>] [--wait <SPEC>] [--header <NAME:VALUE>...] [--cookie <NAME=VALUE>...] [--user-agent <UA>] [--evaluate-after-wait <JS>...] [--want <body|rendered_html|text|content|content_json|screenshot|network|console|observation|storage>...] [--method <METHOD>] --data <STRING|@FILE> [--network-bodies <off|xhr|all>] [--network-body-max-bytes <BYTES>] [--readiness-idle-ms <MS>] [--readiness-stable-ms <MS>] [--readiness-min-text-bytes <BYTES>] [--no-network-redact] [--out <DIR>] [--cookie-jar <PATH>] [--no-cookie-jar] [--observe-main-wait-ms <MS>] [--max-response-bytes <BYTES>] [--retry <N>] [--backoff-ms <MS>] [--proxy-url <URL>] [--ca-cert <PATH>] [--tls-insecure] [--timeout-ms <MS>] [--capture-ws] [--capture-sse]
```
#### `fetch-form` — Fetch with URL-encoded fields from --form
```
afhttp fetch <URL> [--endpoint-url <URL>] [--token-secret <SOURCE>] [--browser <auto|chromium|chrome|fingerprint-chromium|edge|brave|lightpanda|camoufox>] [--browser-bin <PATH>] [--render <none|auto|always>] [--tab <new|<id>>] [--profile <NAME>] [--wait <SPEC>] [--header <NAME:VALUE>...] [--cookie <NAME=VALUE>...] [--user-agent <UA>] [--evaluate-after-wait <JS>...] [--want <body|rendered_html|text|content|content_json|screenshot|network|console|observation|storage>...] [--method <METHOD>] --form <NAME=VALUE>... [--network-bodies <off|xhr|all>] [--network-body-max-bytes <BYTES>] [--readiness-idle-ms <MS>] [--readiness-stable-ms <MS>] [--readiness-min-text-bytes <BYTES>] [--no-network-redact] [--out <DIR>] [--cookie-jar <PATH>] [--no-cookie-jar] [--observe-main-wait-ms <MS>] [--max-response-bytes <BYTES>] [--retry <N>] [--backoff-ms <MS>] [--proxy-url <URL>] [--ca-cert <PATH>] [--tls-insecure] [--timeout-ms <MS>] [--capture-ws] [--capture-sse]
```
#### `fetch-takeover` — Hand a wall to a human, with no request body
```
afhttp fetch <URL> [--endpoint-url <URL>] [--token-secret <SOURCE>] [--browser <auto|chromium|chrome|fingerprint-chromium|edge|brave|lightpanda|camoufox>] [--browser-bin <PATH>] [--render <auto|always>] [--tab <new|<id>>] --takeover [--profile <NAME>] [--wait <SPEC>] [--header <NAME:VALUE>...] [--cookie <NAME=VALUE>...] [--user-agent <UA>] [--evaluate-after-wait <JS>...] [--want <body|rendered_html|text|content|content_json|screenshot|network|console|observation|storage>...] [--method <METHOD>] [--network-bodies <off|xhr|all>] [--network-body-max-bytes <BYTES>] [--readiness-idle-ms <MS>] [--readiness-stable-ms <MS>] [--readiness-min-text-bytes <BYTES>] [--no-network-redact] [--out <DIR>] [--cookie-jar <PATH>] [--no-cookie-jar] [--observe-main-wait-ms <MS>] [--max-response-bytes <BYTES>] [--retry <N>] [--backoff-ms <MS>] [--proxy-url <URL>] [--ca-cert <PATH>] [--tls-insecure] [--timeout-ms <MS>] [--capture-ws] [--capture-sse]
```
#### `fetch-takeover-data` — Hand a wall to a human, with a raw request body from --data
```
afhttp fetch <URL> [--endpoint-url <URL>] [--token-secret <SOURCE>] [--browser <auto|chromium|chrome|fingerprint-chromium|edge|brave|lightpanda|camoufox>] [--browser-bin <PATH>] [--render <auto|always>] [--tab <new|<id>>] --takeover [--profile <NAME>] [--wait <SPEC>] [--header <NAME:VALUE>...] [--cookie <NAME=VALUE>...] [--user-agent <UA>] [--evaluate-after-wait <JS>...] [--want <body|rendered_html|text|content|content_json|screenshot|network|console|observation|storage>...] [--method <METHOD>] --data <STRING|@FILE> [--network-bodies <off|xhr|all>] [--network-body-max-bytes <BYTES>] [--readiness-idle-ms <MS>] [--readiness-stable-ms <MS>] [--readiness-min-text-bytes <BYTES>] [--no-network-redact] [--out <DIR>] [--cookie-jar <PATH>] [--no-cookie-jar] [--observe-main-wait-ms <MS>] [--max-response-bytes <BYTES>] [--retry <N>] [--backoff-ms <MS>] [--proxy-url <URL>] [--ca-cert <PATH>] [--tls-insecure] [--timeout-ms <MS>] [--capture-ws] [--capture-sse]
```
#### `fetch-takeover-form` — Hand a wall to a human, with URL-encoded fields from --form
```
afhttp fetch <URL> [--endpoint-url <URL>] [--token-secret <SOURCE>] [--browser <auto|chromium|chrome|fingerprint-chromium|edge|brave|lightpanda|camoufox>] [--browser-bin <PATH>] [--render <auto|always>] [--tab <new|<id>>] --takeover [--profile <NAME>] [--wait <SPEC>] [--header <NAME:VALUE>...] [--cookie <NAME=VALUE>...] [--user-agent <UA>] [--evaluate-after-wait <JS>...] [--want <body|rendered_html|text|content|content_json|screenshot|network|console|observation|storage>...] [--method <METHOD>] --form <NAME=VALUE>... [--network-bodies <off|xhr|all>] [--network-body-max-bytes <BYTES>] [--readiness-idle-ms <MS>] [--readiness-stable-ms <MS>] [--readiness-min-text-bytes <BYTES>] [--no-network-redact] [--out <DIR>] [--cookie-jar <PATH>] [--no-cookie-jar] [--observe-main-wait-ms <MS>] [--max-response-bytes <BYTES>] [--retry <N>] [--backoff-ms <MS>] [--proxy-url <URL>] [--ca-cert <PATH>] [--tls-insecure] [--timeout-ms <MS>] [--capture-ws] [--capture-sse]
```
Arguments across every shape above:
| Argument | Meaning |
|---|---|
| `URL` | URL to fetch |
| `--endpoint-url` | CDP endpoint of a running host; falls back to AFHTTP_ENDPOINT_URL, then to the local afhttp-host container |
| `--token-secret` | Token for a protected host; falls back to AFHTTP_TOKEN_SECRET, then to the discovered host's own token (the value, or where to read it: env:NAME, file[+FORMAT]:PATH#DOT_PATH, container:NAME, literal:VALUE) |
| `--browser` | Browser backend for the inline host; ignored when --endpoint-url is set |
| `--browser-bin` | Browser binary for the inline host when auto-discovery cannot find one |
| `--render` | Render strategy: none is the HTTP fast path, auto escalates on failure, always uses the browser |
| `--tab` | new allocates a temporary target; a CDP target id reuses and keeps it |
| `--takeover` | Escalate captcha, login, or 2FA walls to human takeover |
| `--profile` | Host profile to switch to for this fetch; defaults to the URL's registrable domain under --takeover |
| `--wait` | Readiness signal: auto | load | idle | selector:<css> | selector-visible:<css> | ms:<n> |
| `--header` | Request header, as Name:value |
| `--cookie` | Request cookie, in Set-Cookie syntax |
| `--user-agent` | Override the User-Agent header for this fetch |
| `--evaluate-after-wait` | JavaScript evaluated in page context after readiness |
| `--want` | Artifact to capture; defaults to body on the HTTP path and the browser set when rendering. storage is sensitive and opt-in |
| `--method` | HTTP method |
| `--data` | Request body; @ reads the rest as a file path |
| `--form` | URL-encoded form field; sends application/x-www-form-urlencoded |
| `--network-bodies` | Capture network response bodies; xhr captures XHR/fetch only |
| `--network-body-max-bytes` | Per-body byte cap for captured network sub-requests |
| `--readiness-idle-ms` | Network quiet window used by --wait auto |
| `--readiness-stable-ms` | DOM/text unchanged window used by --wait auto |
| `--readiness-min-text-bytes` | Low visible-text threshold that only warns about --wait auto quality |
| `--no-network-redact` | Write raw Authorization/Cookie headers and token query parameters to network.json |
| `--out` | Directory for artifacts; defaults to afhttp-out under the temp directory |
| `--cookie-jar` | Override the profile cookie-jar path; must match the host profile. Honors AFHTTP_COOKIE_JAR |
| `--no-cookie-jar` | Replay no cookies and merge no Set-Cookie back; wins over --cookie-jar |
| `--observe-main-wait-ms` | Maximum wait for the browser's main-document event |
| `--max-response-bytes` | Maximum main HTTP-path response body size; 0 disables the cap |
| `--retry` | Retry attempts after the first, for retryable errors only |
| `--backoff-ms` | Fixed delay between retries |
| `--proxy-url` | Upstream proxy for the HTTP fast path; ambient HTTP_PROXY is never honored |
| `--ca-cert` | PEM file with extra root CAs for the HTTP path |
| `--tls-insecure` | Disable TLS certificate verification on the HTTP path |
| `--timeout-ms` | Overall fetch timeout for both the HTTP and browser paths |
| `--capture-ws` | Capture WebSocket frame payloads; treat the artifact as sensitive |
| `--capture-sse` | Capture SSE event payloads; treat the artifact as sensitive |
### `afhttp health`
Query a host's /health endpoint.
```
afhttp health [--endpoint-url <URL>] [--token-secret <SOURCE>]
```
| Argument | Meaning |
|---|---|
| `--endpoint-url` | CDP endpoint of a running host; falls back to AFHTTP_ENDPOINT_URL, then to the local afhttp-host container |
| `--token-secret` | Token for a protected host; falls back to AFHTTP_TOKEN_SECRET, then to the discovered host's own token (the value, or where to read it: env:NAME, file[+FORMAT]:PATH#DOT_PATH, container:NAME, literal:VALUE) |
### `afhttp host`
Run the browser host: launch a backend browser and serve /cdp for clients.
#### `host` — Serve no takeover surface; --display picks headless or headful
```
afhttp host --listen <tcp:HOST:PORT|unix:PATH> [--profile <NAME>] [--display <headless|headful>] [--takeover-provider off] [--browser <auto|chromium|chrome|fingerprint-chromium|edge|brave|lightpanda|camoufox>] [--browser-bin <PATH>] [--token-secret <SOURCE>] [--no-health] [--health-public <off|minimal>] [--engine-env <NAME=VALUE>...] [--browser-arg <FLAG>...] [--proxy-url <URL>] [--recent-requests-cap <N>]
```
#### `host-takeover` — Serve a KasmVNC real-display takeover, which is always headful
```
afhttp host --listen <tcp:HOST:PORT|unix:PATH> [--profile <NAME>] --takeover-provider kasmvnc [--takeover-quality-percent <PERCENT>] [--browser <auto|chromium|chrome|fingerprint-chromium|edge|brave|lightpanda|camoufox>] [--browser-bin <PATH>] [--token-secret <SOURCE>] [--no-health] [--health-public <off|minimal>] [--engine-env <NAME=VALUE>...] [--browser-arg <FLAG>...] [--proxy-url <URL>] [--recent-requests-cap <N>]
```
Output: protocol events; `--output` json (default `json`), `--output-to` split/stdout/stderr (default `stdout`); redirect with `--stdout-file` or `--stderr-file`.
Arguments across every shape above:
| Argument | Meaning |
|---|---|
| `--listen` | Listener address; a non-loopback TCP address also requires --token-secret |
| `--profile` | Initial profile name, or - for an ephemeral profile |
| `--display` | Browser display mode |
| `--takeover-provider` | Real-display takeover provider served at /takeover/panel |
| `--takeover-quality-percent` | Takeover image quality from 0 to 100; lower trades clarity for bandwidth |
| `--browser` | Browser backend |
| `--browser-bin` | Override the browser binary path |
| `--token-secret` | Token this host requires from callers (the value, or where to read it: env:NAME, file[+FORMAT]:PATH#DOT_PATH, container:NAME, literal:VALUE) |
| `--no-health` | Stop serving /health and /capabilities, which are on by default |
| `--health-public` | Serve /health unauthenticated with a minimal payload |
| `--engine-env` | Environment variable for the browser subprocess; all others are scrubbed |
| `--browser-arg` | Raw backend flag appended after the host's defaults |
| `--proxy-url` | Upstream browser proxy; ambient HTTP_PROXY is never inherited |
| `--recent-requests-cap` | Enable /recent-requests with a bounded ring of N entries; 0 is off |
### `afhttp panel`
Mint a short-lived takeover URL for a running takeover-ready host.
```
afhttp panel [--endpoint-url <URL>] [--token-secret <SOURCE>]
```
| Argument | Meaning |
|---|---|
| `--endpoint-url` | CDP endpoint of a running host; falls back to AFHTTP_ENDPOINT_URL, then to the local afhttp-host container |
| `--token-secret` | Token for a protected host; falls back to AFHTTP_TOKEN_SECRET, then to the discovered host's own token (the value, or where to read it: env:NAME, file[+FORMAT]:PATH#DOT_PATH, container:NAME, literal:VALUE) |
### `afhttp profile cookies`
Show the non-expired cookies in a profile's jar, with values redacted.
```
afhttp profile cookies <NAME> [--backend <BACKEND>] [--profile-root <DIR>]
```
| Argument | Meaning |
|---|---|
| `NAME` | Profile name |
| `--backend` | Browser backend scope; required when one profile name exists under several |
| `--profile-root` | Profiles root directory; defaults to $XDG_DATA_HOME/afhttp/profiles |
### `afhttp profile delete`
Delete a profile and all of its on-disk state.
```
afhttp profile delete <NAME> [--backend <BACKEND>] --confirm <NAME> [--profile-root <DIR>]
```
| Argument | Meaning |
|---|---|
| `NAME` | Profile name to delete |
| `--backend` | Browser backend scope; required when one profile name exists under several |
| `--confirm` | Confirmation guard; must equal the profile name |
| `--profile-root` | Profiles root directory; defaults to $XDG_DATA_HOME/afhttp/profiles |
### `afhttp profile downloads`
List files captured in a profile's browser download directory.
```
afhttp profile downloads <NAME> [--backend <BACKEND>] [--profile-root <DIR>]
```
| Argument | Meaning |
|---|---|
| `NAME` | Profile name |
| `--backend` | Browser backend scope; required when one profile name exists under several |
| `--profile-root` | Profiles root directory; defaults to $XDG_DATA_HOME/afhttp/profiles |
### `afhttp profile info`
Show one profile's size, last use, and lock state.
```
afhttp profile info <NAME> [--backend <BACKEND>] [--profile-root <DIR>]
```
| Argument | Meaning |
|---|---|
| `NAME` | Profile name |
| `--backend` | Browser backend scope; required when one profile name exists under several |
| `--profile-root` | Profiles root directory; defaults to $XDG_DATA_HOME/afhttp/profiles |
### `afhttp profile list`
List the on-disk profiles under the profiles root.
```
afhttp profile list [--profile-root <DIR>]
```
| Argument | Meaning |
|---|---|
| `--profile-root` | Profiles root directory; defaults to $XDG_DATA_HOME/afhttp/profiles |
### `afhttp profile lock-status`
Report whether a profile is currently locked by a running host.
```
afhttp profile lock-status <NAME> [--backend <BACKEND>] [--profile-root <DIR>]
```
| Argument | Meaning |
|---|---|
| `NAME` | Profile name |
| `--backend` | Browser backend scope; required when one profile name exists under several |
| `--profile-root` | Profiles root directory; defaults to $XDG_DATA_HOME/afhttp/profiles |
### `afhttp profile prune`
Delete profiles whose last use is older than a cutoff.
```
afhttp profile prune --older-than <DURATION> [--dry-run] [--profile-root <DIR>]
```
| Argument | Meaning |
|---|---|
| `--older-than` | Age cutoff such as 30d or 12h; profiles last used before it are removed |
| `--dry-run` | Report what would be deleted without deleting anything |
| `--profile-root` | Profiles root directory; defaults to $XDG_DATA_HOME/afhttp/profiles |
### `afhttp skill install`
Install or refresh the Agent-First HTTP skill.
#### `skill-install-every-agent` — Target every agent that supports the scope
```
afhttp skill install [--agent all] [--scope <personal|workspace>] [--force]
```
#### `skill-install-one-agent` — Target one named agent; only this shape accepts --skills-dir
```
afhttp skill install --agent <codex|claude-code|opencode|hermes> [--scope <personal|workspace>] [--skills-dir <DIR>] [--force]
```
Arguments across every shape above:
| Argument | Meaning |
|---|---|
| `--agent` | Agent to manage |
| `--scope` | Skill scope |
| `--skills-dir` | Directory that contains skill folders |
| `--force` | Overwrite or remove an Agent-First HTTP skill this tool did not manage |
### `afhttp skill status`
Show whether the Agent-First HTTP skill is installed, valid, and up to date.
#### `skill-status-every-agent` — Target every agent that supports the scope
```
afhttp skill status [--agent all] [--scope <personal|workspace>]
```
#### `skill-status-one-agent` — Target one named agent; only this shape accepts --skills-dir
```
afhttp skill status --agent <codex|claude-code|opencode|hermes> [--scope <personal|workspace>] [--skills-dir <DIR>]
```
Arguments across every shape above:
| Argument | Meaning |
|---|---|
| `--agent` | Agent to manage |
| `--scope` | Skill scope |
| `--skills-dir` | Directory that contains skill folders |
### `afhttp skill uninstall`
Remove an afhttp-managed Agent-First HTTP skill.
#### `skill-uninstall-every-agent` — Target every agent that supports the scope
```
afhttp skill uninstall [--agent all] [--scope <personal|workspace>] [--force]
```
#### `skill-uninstall-one-agent` — Target one named agent; only this shape accepts --skills-dir
```
afhttp skill uninstall --agent <codex|claude-code|opencode|hermes> [--scope <personal|workspace>] [--skills-dir <DIR>] [--force]
```
Arguments across every shape above:
| Argument | Meaning |
|---|---|
| `--agent` | Agent to manage |
| `--scope` | Skill scope |
| `--skills-dir` | Directory that contains skill folders |
| `--force` | Overwrite or remove an Agent-First HTTP skill this tool did not manage |
### `afhttp tabs close`
Close one CDP target by its target id.
```
afhttp tabs close --tab <TARGET_ID> [--endpoint-url <URL>] [--token-secret <SOURCE>]
```
| Argument | Meaning |
|---|---|
| `--tab` | CDP target id to close |
| `--endpoint-url` | CDP endpoint of a running host; falls back to AFHTTP_ENDPOINT_URL, then to the local afhttp-host container |
| `--token-secret` | Token for a protected host; falls back to AFHTTP_TOKEN_SECRET, then to the discovered host's own token (the value, or where to read it: env:NAME, file[+FORMAT]:PATH#DOT_PATH, container:NAME, literal:VALUE) |
### `afhttp tabs list`
List the CDP targets currently attached to a host.
```
afhttp tabs list [--endpoint-url <URL>] [--token-secret <SOURCE>]
```
| Argument | Meaning |
|---|---|
| `--endpoint-url` | CDP endpoint of a running host; falls back to AFHTTP_ENDPOINT_URL, then to the local afhttp-host container |
| `--token-secret` | Token for a protected host; falls back to AFHTTP_TOKEN_SECRET, then to the discovered host's own token (the value, or where to read it: env:NAME, file[+FORMAT]:PATH#DOT_PATH, container:NAME, literal:VALUE) |
### `afhttp ui takeover`
Put the takeover panel in front of a person and block until that session ends.
#### `ui-takeover` — Mint a fresh panel credential from a running host, then deliver it
```
afhttp ui takeover [--endpoint-url <URL>] [--token-secret <SOURCE>] [--mode <window|link|session>]
```
#### `ui-takeover-url` — Deliver a panel URL that was already minted; needs no host of its own
```
afhttp ui takeover --takeover-url-secret <URL> [--mode <window|link|session>]
```
Output: protocol events; `--output` json (default `json`), `--output-to` split/stdout/stderr (default `stdout`); redirect with `--stdout-file` or `--stderr-file`.
Arguments across every shape above:
| Argument | Meaning |
|---|---|
| `--endpoint-url` | CDP endpoint of a running host; falls back to AFHTTP_ENDPOINT_URL, then to the local afhttp-host container |
| `--token-secret` | Token for a protected host; falls back to AFHTTP_TOKEN_SECRET, then to the discovered host's own token (the value, or where to read it: env:NAME, file[+FORMAT]:PATH#DOT_PATH, container:NAME, literal:VALUE) |
| `--takeover-url-secret` | Panel URL a previous `panel` or `fetch --takeover` already minted |
| `--mode` | How this reaches the person: window a browser window is open on this machine; link the page is reachable from this machine's network at the link URL; session the session is registered only; open it with `afui session open` or reach it through `afui session serve`. Falls back to AFUI_DELIVERY, then window |
### `afhttp upload`
Upload a local file into a browser tab's file input via DOM.setFileInputFiles.
```
afhttp upload [--endpoint-url <URL>] [--token-secret <SOURCE>] --tab <TARGET_ID> --selector <CSS> --file <PATH>
```
| Argument | Meaning |
|---|---|
| `--endpoint-url` | CDP endpoint of a running host; falls back to AFHTTP_ENDPOINT_URL, then to the local afhttp-host container |
| `--token-secret` | Token for a protected host; falls back to AFHTTP_TOKEN_SECRET, then to the discovered host's own token (the value, or where to read it: env:NAME, file[+FORMAT]:PATH#DOT_PATH, container:NAME, literal:VALUE) |
| `--tab` | CDP target id to operate in |
| `--selector` | CSS selector for the <input type=file> element |
| `--file` | Local file to upload |
## Exit codes
| Code | Meaning |
|---|---|
| 0 | The command ran and succeeded. |
| 1 | The command ran and failed. The event carries a domain `error.code`. |
| 2 | The invocation was rejected before anything ran. `error.code` is one of the `cli_*` codes below. |
The split is the useful one for a caller: exit 2 means the call was never made, so retrying it unchanged cannot help, while exit 1 means it was.
## CLI errors
Every structural failure emits one strict JSON `kind:"error"` event on stderr, leaves stdout empty, and exits 2. The `code` names the failure — `cli_unknown_argument` for an unknown spelling, `cli_unregistered_combination` for registered arguments in a mixture that is not, and one each for `cli_unknown_command`, `cli_missing_argument_value`, `cli_invalid_argument_value`, `cli_duplicate_argument`, `cli_unexpected_positional`, and `cli_invalid_utf8`. `message` identifies a safe argument spelling or the failure category and `hint` gives the command to run next; neither ever quotes a raw value, including secrets. These are decided before any config, secret source, filesystem, network, or domain I/O.
Two exit-1 codes describe the tool itself rather than the call: `cli_invocation_invalid` means the program misread its own resolved invocation — an unknown action id, or an argument id the selected combination cannot produce — and `output_setup_failed` means an output sink (`--stdout-file`, `--stderr-file`, stream redirection) could not be established. Both are defects to report, not inputs to correct; retrying the same command cannot help.
Domain failures (exit 1) carry their own stable `error.code` instead, drawn from whatever this tool defines rather than from the `cli_*` set. Error events are routinely logged, so a message never quotes a value that came from an argument able to carry a credential — a header, a cookie, a token, a password, a proxy URL, an environment value, a form field. Such an error names the argument and the shape that was wrong, and stops there. A value that cannot be a secret — a path, a dot-path, a session name — is quoted, because an error that cannot say which one it means is not worth logging either.