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

# Reference

> Every Jam CLI command, flag, exit code, and environment variable. Install, authenticate, read and write Jams, record, and manage recording links.

Every command the Jam CLI ships, with its flags and output shape. For the agent workflow and quickstart, start at [CLI](/docs/cli).

<Info>
  The CLI runs on macOS, Linux, and Windows (x64 and arm64). Windows publishes an x64 binary, and Windows on ARM runs it under the built-in x64 emulation. You can also run the CLI under Windows Subsystem for Linux (WSL). On WSL, authenticate with a personal access token (see [Authenticate](#authenticate)).
</Info>

## Install

<Tabs>
  <Tab title="macOS / Linux">
    Run the installer:

    ```bash theme={"theme":"css-variables"}
    curl -fsSL https://native.jam.dev/install | bash
    ```

    The script detects your OS and architecture, downloads the matching binary into `~/.local/bin/jam`, and adds that directory to your shell `PATH`. Open a new shell or `source` your rc file, then confirm the install:

    ```bash theme={"theme":"css-variables"}
    jam --version
    ```
  </Tab>

  <Tab title="Windows">
    Open PowerShell and run:

    ```powershell theme={"theme":"css-variables"}
    powershell -c "irm https://native.jam.dev/install.ps1 | iex"
    ```

    The script downloads the binary into `%LOCALAPPDATA%\Programs\Jam`, points a `jam` command at it, and adds it to your user `PATH`. Open a new terminal, then confirm the install:

    ```powershell theme={"theme":"css-variables"}
    jam --version
    ```

    <Note>
      Only an x64 binary is published. Windows on ARM runs it under the built-in x64 emulation, so the same one-liner works with no extra steps.
    </Note>

    **Locked-down PowerShell.** If your environment blocks `irm | iex` (a restricted execution policy is common on managed machines), install by hand: download the binary from [`https://native.jam.dev/download/windows/x64`](https://native.jam.dev/download/windows/x64), save it as `jam.exe` in a folder such as `%LOCALAPPDATA%\Programs\Jam\bin`, then add that folder to your `PATH` under **Settings → Edit environment variables for your account**. Open a new terminal and run `jam --version`.
  </Tab>
</Tabs>

### Creating video Jams needs ffmpeg

`jam create jam` extracts the poster image and probes the audio track with `ffmpeg`/`ffprobe` when you create a **video** Jam. Every other command works without it. Install ffmpeg if you plan to create video Jams from the CLI:

<CodeGroup>
  ```bash macOS theme={"theme":"css-variables"}
  brew install ffmpeg
  ```

  ```bash Linux theme={"theme":"css-variables"}
  sudo apt install ffmpeg
  ```

  ```powershell Windows theme={"theme":"css-variables"}
  winget install ffmpeg
  ```
</CodeGroup>

Or skip ffmpeg entirely by passing `posterImagePath`, `durationMs`, `width`, `height`, and `micEnabled` explicitly on the create payload.

### Recording with jam record

`jam record` captures a window or the whole desktop and uploads it as a video Jam. Nothing has to be a browser. A desktop app, a terminal, a simulator, an editor: they all record the same way. Use it from a script, a CI job, or a coding agent that needs to show its work. The Chrome extension remains the capture path in the browser. `jam doctor` reports recording readiness and names any missing packages.

<Info>
  `jam record` runs on macOS and Linux. On Windows the command exits with a message that the platform is unsupported. Everything else the CLI does still works there.
</Info>

<CodeGroup>
  ```bash macOS theme={"theme":"css-variables"}
  # Captures through the embedded ScreenCaptureKit helper. Grant Screen Recording
  # permission to your terminal app in System Settings → Privacy & Security.
  jam doctor
  ```

  ```bash Linux theme={"theme":"css-variables"}
  # X11 only (Wayland is not supported). Window capture is a screen-region grab,
  # so an overlapping window appears in the recording.
  sudo apt-get install -y ffmpeg wmctrl x11-xserver-utils x11-utils util-linux
  jam doctor
  ```

  ```powershell Windows theme={"theme":"css-variables"}
  # `jam record` is not supported on Windows. Use macOS or Linux.
  jam doctor
  ```
</CodeGroup>

On macOS, a window is captured on its own (it can sit behind other windows). The CLI draws a lime outline around the recorded window on your screen. That outline is not in the video. On Linux, keep the target window uncovered.

## Authenticate

Every read and write command needs an authenticated session. The CLI supports two modes.

<Note>
  On WSL, use a personal access token. The browser login flow expects your browser and the CLI to share the same local address, which WSL splits between Windows and Linux, so token auth is the reliable path for now.
</Note>

<Tabs>
  <Tab title="Browser OAuth">
    Run:

    ```bash theme={"theme":"css-variables"}
    jam auth login
    ```

    The CLI opens an OAuth flow in your default browser, exchanges the authorization code for access and refresh tokens, and stores them in `~/.config/jam/credentials.json`.
  </Tab>

  <Tab title="Personal access token">
    Use a personal access token for headless environments, CI jobs, or WSL:

    ```bash theme={"theme":"css-variables"}
    echo "jam_pat_abc123..." | jam auth login --token
    ```

    Create PATs in [**Settings → MCP**](https://jam.dev/s/settings/mcp). See [Personal Access Tokens](/docs/personal-access-tokens) for scopes, expiration, and rotation guidance.
  </Tab>
</Tabs>

### Check auth status

```bash theme={"theme":"css-variables"}
jam auth status
```

Prints the authenticated user, workspace, and auth method. Pass `--json` to consume the same data from a script.

### Log out

```bash theme={"theme":"css-variables"}
jam auth logout
```

Revokes tokens server-side where supported and clears the local credential store.

### Where credentials live

The CLI stores credentials at `~/.config/jam/credentials.json` with `0600` permissions, the same model used by `gh`, `aws`, `gcloud`, and other major developer CLIs.

Bypass the credential file entirely by setting `JAM_TOKEN` in your shell. The CLI uses the env-var token for the lifetime of the process and never writes it to disk.

## First steps

After install and auth, run this short loop to confirm the CLI talks to your workspace:

```bash theme={"theme":"css-variables"}
jam auth status
jam list jams --limit 5
jam get jam <id>
```

`auth status` confirms the CLI can read the stored token. `list jams` returns a page of Jams from your workspace. `get jam` walks a single Jam by ID. From there, [set up your coding agent](/docs/cli#quickstart), or scan the [commands table](#commands) for the command you need.

## Set up your coding agent

`jam skills install` writes the bundled `jam-cli` and `jam-proof` skills where your agent reads them. The workflow, and what each skill teaches, is on the [CLI](/docs/cli) page.

```bash theme={"theme":"css-variables"}
jam skills list                    # see the catalog
jam skills install jam-cli         # install one skill
jam skills install --project       # install into this repo instead of your home directory
jam skills path                    # preview the destination without writing
```

The CLI detects the runtime from environment variables, falls back to project marker directories, and defaults to Claude Code. Name one with `--target`.

## Commands

Every command supports `--help`. The machine-readable surface (argument types, flags, output shapes) lives at `jam agent-context`.

| Command                                                                                                                                                                  | Summary                                                                          | Output      |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------- | ----------- |
| `jam auth login [--token]`                                                                                                                                               | Authenticate via browser OAuth or stdin PAT                                      | Side effect |
| `jam auth logout`                                                                                                                                                        | Revoke tokens and clear credentials                                              | Side effect |
| `jam auth status`                                                                                                                                                        | Show current user, workspace, and auth method                                    | Single      |
| `jam get jam <id>`                                                                                                                                                       | Fetch a Jam by ID                                                                | Single      |
| `jam get metadata <id>`                                                                                                                                                  | Structured `jam.metadata()` events                                               | Paginated   |
| `jam get console <id> [--level <levels>]`                                                                                                                                | Console log events                                                               | Paginated   |
| `jam get network <id> [--status <codes>] [--method <verbs>] [--host <hosts>] [--content-type <types>]`                                                                   | Network requests                                                                 | Paginated   |
| `jam get events <id>`                                                                                                                                                    | Full unfiltered event stream                                                     | Paginated   |
| `jam get transcript <id>`                                                                                                                                                | WebVTT transcript for video Jams                                                 | Single      |
| `jam get chapters <id>`                                                                                                                                                  | AI-generated chapter markers for video Jams                                      | Single      |
| `jam get intents <id>`                                                                                                                                                   | Cached intents summary                                                           | Single      |
| `jam get screenshots <id> --out <dir>`                                                                                                                                   | Download image media into a directory                                            | Receipt     |
| `jam get frames <id> [--overview] [--at <ms>] [--from <ms> --to <ms> --count <n>] [--size <s>] [--out <dir>]`                                                            | Save still video frames as jpgs                                                  | Receipt     |
| `jam list jams [...]`                                                                                                                                                    | List Jams in the workspace                                                       | Paginated   |
| `jam list folders [...]`                                                                                                                                                 | List folders                                                                     | Paginated   |
| `jam list members [...]`                                                                                                                                                 | List workspace members                                                           | Paginated   |
| `jam create jam '<json>'`                                                                                                                                                | Create a screenshot or video Jam                                                 | Receipt     |
| `jam create comment <jamId> <body> [--at <ms>]`                                                                                                                          | Add a comment to a Jam                                                           | Receipt     |
| `jam create folder <name>`                                                                                                                                               | Create a folder                                                                  | Receipt     |
| `jam create reaction <commentId> <emoji>`                                                                                                                                | React to a comment                                                               | Receipt     |
| `jam update jam <id> [--title <title>] [--description <text>] [--folder <folder>]`                                                                                       | Rename a Jam, rewrite its description, or move it to a folder                    | Receipt     |
| `jam update folder <folder> --name <name>`                                                                                                                               | Rename a folder                                                                  | Receipt     |
| `jam update comment <commentId> <body>`                                                                                                                                  | Rewrite a comment you authored                                                   | Receipt     |
| `jam delete jam <id> [-y]`                                                                                                                                               | Delete a Jam                                                                     | Receipt     |
| `jam delete comment <commentUid> [-y]`                                                                                                                                   | Delete a comment you wrote                                                       | Receipt     |
| `jam delete folder <id> [-y]`                                                                                                                                            | Delete a folder and the Jams in it                                               | Receipt     |
| `jam delete reaction <commentId> <emoji>`                                                                                                                                | Take back your reaction on a comment                                             | Receipt     |
| `jam record windows`                                                                                                                                                     | List the windows available to record                                             | List        |
| `jam record displays`                                                                                                                                                    | List the displays available to record                                            | List        |
| `jam record run [command...] [--window-id <id>] [--app <name>] [--bundle-id <bundleId>] [--display <id>] [--title <title>] [--description <text>] [--folder <folderId>]` | Record a window or the desktop into a Jam                                        | Receipt     |
| `jam recording-links urls`                                                                                                                                               | List connected recording domains                                                 | Paginated   |
| `jam recording-links list [--limit <n>] [--after <cursor>]`                                                                                                              | List the team's recording links                                                  | Paginated   |
| `jam recording-links get <id>`                                                                                                                                           | Fetch a recording link by public ID                                              | Single      |
| `jam recording-links jams <id> [--limit <n>] [--after <cursor>]`                                                                                                         | List Jams recorded through a link                                                | Paginated   |
| `jam recording-links create --name <name> [--recording-url-id <id>] [--folder <f>] [--jam-title <t>] [--reference <r>] [--expires-at <iso>] [--metadata <json>]`         | Create a reusable recording link                                                 | Receipt     |
| `jam recording-links update <id> [--name <n>] [--folder <f>] [--reference <r>] [--jam-title <t>] [--expires-at <iso>] [--metadata <json>]`                               | Edit a recording link's settings                                                 | Receipt     |
| `jam recording-links delete <id>`                                                                                                                                        | Revoke a recording link                                                          | Receipt     |
| `jam recording-links verify <url> [--wait]`                                                                                                                              | Verify a connected recording domain                                              | Receipt     |
| `jam skills list`                                                                                                                                                        | List bundled agent skills                                                        | List        |
| `jam skills install [name] [--target <agent>] [--project] [--dir <dir>]`                                                                                                 | Install bundled skill into an agent's directory, or into `<dir>/<name>/SKILL.md` | Receipt     |
| `jam skills path [--target <agent>] [--project]`                                                                                                                         | Show where skills would be installed                                             | Single      |
| `jam skills source`                                                                                                                                                      | Print the absolute path to the bundled `SKILL.md`                                | Path        |
| `jam agent-context`                                                                                                                                                      | Print the machine-readable command surface as JSON                               | Single      |
| `jam doctor`                                                                                                                                                             | Show CLI channel, URLs, version, auth status, and recording readiness            | Text        |
| `jam upgrade [--target <version>]`                                                                                                                                       | Install the latest or pinned CLI binary                                          | Side effect |
| `jam uninstall [-y]`                                                                                                                                                     | Remove the CLI and local data                                                    | Side effect |

### Read Jam data

Three commands return different views of the same Jam:

* `jam get jam <id>` returns the top-level record (title, author, URL, dates, folder, and kind-specific data).
* `jam get metadata <id>` returns structured metadata events emitted by the page via the `jam.metadata()` SDK call.
* `jam get intents <id>` returns the structured summary (what the user was trying to do, observed issues, impact). It returns `{ "status": "not_requested", "value": null }` when no summary is available. Treat that as absence, not an error.

Three commands return slices of the captured event stream:

* `jam get console <id> [--level error|warn|info|debug|log]`
* `jam get network <id> [--status 5xx|<code>] [--method GET|POST|...] [--host <substring>] [--content-type <ct>]`
* `jam get events <id>` returns the unfiltered event stream.

Every filter accepts a comma-separated list, for example `--level error,warn` or `--status 401,5xx`.

All three accept `--limit` (default 50, max 500) and `--after <cursor>` for pagination.

Three media reads:

* `jam get transcript <id>` returns `{ status, vtt }`. `vtt` is null while generation is pending.
* `jam get chapters <id>` returns `{ status, chapters, language }`. `chapters` is null unless `status` is `ready`, and `status` is `not_requested` when generation was never queued. Chapters are text only, so to see what one looked like on screen run `jam get frames <id> --at <ms>` at a timestamp inside its span.
* `jam get screenshots <id> --out <dir>` downloads the Jam's images into `<dir>`. For screenshot Jams that's the primary and secondary screenshots, for video Jams it's the poster image, and for Instant Replay Jams it's the captured screenshot.

### Video frames

`jam get frames <id>` saves still frames from a video Jam as jpgs, so you or an agent can see what was on screen instead of only reading the transcript. Frames land in `--out` (default `./jam-frames/<id>/`) and the command prints the saved paths as JSON.

```bash theme={"theme":"css-variables"}
# overview grid: one labeled image spanning the whole video
jam get frames <id> --overview

# a single moment, or several explicit timestamps
jam get frames <id> --at 7000
jam get frames <id> --at 4000,7000,9000

# evenly-spaced frames across a window
jam get frames <id> --from 2000 --to 10000 --count 5
```

The mode depends on the flags:

* **Overview grid.** `--overview`. Saves one grid image with frames evenly spaced across the whole video, each cell labeled with its timestamp. The frame count scales with duration (6 for short clips up to 16 for long ones). Best for orienting before you know which moment you care about.
* **Timestamps.** `--at <ms>`, single or comma-separated. Saves one jpg per timestamp.
* **Window.** `--from <ms> --to <ms> --count <n>`. Saves N evenly-spaced frames across the range.

`--size` accepts `small`, `medium`, or `large` (default `medium`) and sets the frame height. When frames aren't available (a screenshot Jam, or a video not hosted on Cloudflare Stream), the command prints the reason to stderr and exits non-zero.

### List workspace collections

```bash theme={"theme":"css-variables"}
jam list jams --query "checkout" --type video --limit 20
jam list folders --order-by createdAt
jam list members --query "@example.com"
```

`--type` accepts `screenshot`, `video`, `replay`, or `unknown`. `--order-by` accepts `createdAt` or `updatedAt`. `--limit` defaults to 20 (max 500). All three list commands accept `--after <cursor>` for pagination. See `jam list jams --help` for all filters.

### Create and update Jams

Create a screenshot Jam from a JSON payload:

```bash theme={"theme":"css-variables"}
jam create jam '{
  "url": "https://example.com/checkout",
  "title": "Checkout button is broken",
  "screenshotPath": "./checkout.png",
  "screenDimensions": { "width": 1440, "height": 900 }
}'
```

The payload requires `url`, `screenDimensions`, and exactly one screenshot source (`screenshotPath`, `screenshotDataUrl`, or `screenshotMediaId`). To create a video Jam, set `kind` to `"video"` and provide `videoPath`. If you omit `posterImagePath`, the CLI extracts the video's first frame locally with ffmpeg.

A video Jam can also carry the console logs and network requests from a Playwright test run. Point `playwrightTracePath` at the `trace.zip` Playwright wrote, and the CLI parses it and attaches the events to the Jam, synced to the video timeline:

```bash theme={"theme":"css-variables"}
jam create jam '{
  "kind": "video",
  "url": "https://example.com/checkout",
  "videoPath": "./test-results/checkout/video.webm",
  "playwrightTracePath": "./test-results/checkout/trace.zip",
  "screenDimensions": { "width": 1280, "height": 720 }
}'
```

Headers and request bodies are redacted before upload, the same way the browser extension redacts them during a recording. If the trace cannot be read, the CLI reports it and still creates the Jam, without events. The create payload has no HAR field. Attach console and network events from a Playwright `trace.zip` with `playwrightTracePath`.

The trace also records every `fill`, `type`, `pressSequentially` and `insertText` the test ran. The Jam shows each of those as a typing action, with the text it typed. A password field, a one-time-code or credit-card field, and any field whose name, id, autocomplete or placeholder reads as sensitive show `***` instead. So does text the CLI cannot attribute to a field, which includes everything typed through `keyboard.insertText`.

To avoid escaping a large JSON blob on the command line, read the payload from a file with an `@` prefix, or pipe it in on stdin:

```bash theme={"theme":"css-variables"}
jam create jam @jam.json        # read from a file
cat jam.json | jam create jam   # pipe via stdin
```

Run `jam create jam --help` for both payload shapes, or `jam agent-context` for the full machine-readable JSON Schema (under `create.jam`, on the `source` arg).

Comment on a Jam, then keep that comment current as you learn more instead of posting a second one:

```bash theme={"theme":"css-variables"}
jam create comment <jamId> "Looking into the 500 on /checkout." --at 42000
jam update comment <commentId> "The 500 on /checkout was an expired Stripe key. Fixed in #1423."
```

`<body>` is Markdown. `--at` pins the comment to a video timestamp in milliseconds, and only `create` accepts it. An edit replaces the body entirely, keeps the timestamp the comment was created with, and works only on comments you authored. `<commentId>` is the `id` the create call returned, and the share URL it printed works too.

React to a comment, or take the reaction back:

```bash theme={"theme":"css-variables"}
jam create reaction <commentId> "👀"
jam delete reaction <commentId> "👀"
```

Reactions are one of 🐛 💜 ✅ 👀 ❓ 👏 🔥 👍, the same set the share page offers. Both commands are idempotent, and removing only clears your own reaction.

Rename a Jam, rewrite its description, or move it to a folder:

```bash theme={"theme":"css-variables"}
jam update jam <id> --title "Checkout fails on Safari"
jam update jam <id> --description "Repro steps are in the console log."
jam update jam <id> --folder <folder>
jam update jam <id> --folder ""
```

Pass at least one flag. Only the fields you pass change. `--folder` takes a folder name, its short ID, or its UUID. Pass an empty string to remove the Jam from its current folder. `--description` takes Markdown, and an `@mention` of a teammate's email notifies them. Editing the title or description needs an Admin or Creator role; moving folders does not.

### Create and rename folders

```bash theme={"theme":"css-variables"}
jam create folder "Checkout bugs"
jam update folder checkout-bugs --name "Checkout"
```

`create folder` returns `{ id, shortId, name }`, so you can file a Jam into the new folder straight away with `jam update jam <id> --folder <folder>`. Folder names are not unique. Run `jam list folders` first if you mean to reuse an existing folder rather than add another one with the same name.

`update folder` accepts a folder name, its short ID, or its UUID. Renaming leaves the folder's Jams and short ID untouched.

### Delete Jams, comments, and folders

```bash theme={"theme":"css-variables"}
jam delete jam <id>
jam delete comment <commentUid>
jam delete folder <folder-id>
```

Deleting a Jam takes it out of your lists and search, and there is no way to restore it. The dashboard has no trash or archive view. Deleting a folder deletes every Jam inside it and reports how many in `archivedJamCount`. Deleting a comment is permanent and takes its attachments with it, and only the comment's author can do it.

Each command asks you to confirm first. Pass `-y` (or `--yes`) to skip the prompt. Scripts and agents have no terminal to answer on, so they must pass `-y`; without it the command refuses rather than assuming an answer.

### Record a window or the desktop

`jam record` is the CLI capture path. It is not [Recording Links](/docs/recording-links), which are shareable URLs that collect Jams from a browser. `jam record` captures pixels from a window or display. It does not attach console logs or network requests.

The common use is proof of work. Wrap a test run, a script, or the steps an agent drives, and the Jam link becomes the evidence: what was on screen, in order, at the time it happened. Attach it to the pull request instead of describing the result in words. See the [CLI](/docs/cli) page for the agent side of that workflow.

List targets first. Window IDs change when a window is reopened, so re-run `jam record windows` before each recording:

```bash theme={"theme":"css-variables"}
jam record windows
jam record displays
```

Then record. With no selector flag, `jam record run` records the whole primary display. Name a window with exactly one of `--window-id`, `--app`, or `--bundle-id`. Name a display with `--display`. Do not combine those flags.

`--app` and `--bundle-id` match case-insensitively but exactly. If more than one window matches, the command fails and lists candidate IDs. Prefer `--window-id` from a fresh `jam record windows` when an app has several windows open.

```bash theme={"theme":"css-variables"}
jam record run -- sleep 30
jam record run --app "Google Chrome" --title "Checkout 500s" -- bun run e2e/checkout.ts
jam --json record run --window-id 4213 --title "Checkout 500s"
```

Put the wrapped command after `--` so its own flags reach it instead of `jam`. Command output goes to stderr. Stdout carries only the Jam receipt:

```json theme={"theme":"css-variables"}
{
  "id": "<jam-id>",
  "url": "https://jam.dev/c/<jam-id>",
  "kind": "video"
}
```

The wrapped form exits with the command's code when the command fails, and with the upload's code otherwise. A failing test still produces a Jam and still fails the pipeline. If upload fails, the mp4 is kept and its path is printed to stderr.

With no wrapped command, recording runs until you stop it. Press Ctrl-C at a terminal, or send SIGINT (`kill -INT <pid>`) from a script that started the process in the background. Both forms upload and print the same receipt. The no-command form exits 0. A wrapped command killed by SIGINT exits 130 after the upload.

`--title`, `--description`, and `--folder` set those fields at creation. `--folder` takes a folder ID. Leave them off and set the title or description later with `jam update jam <id>`.

### Recording links

A recording link is a shareable URL that collects Jams: anyone who opens it can record and submit a Jam back to your workspace. A link captures console and network logs only when it records from a connected recording domain (a "recording URL"), so list your connected domains first and pass one when you create the link. See [Recording Links](/docs/recording-links) for the dashboard workflow.

```bash theme={"theme":"css-variables"}
jam recording-links urls
jam recording-links create --name "Support intake" --recording-url-id <url-id> --folder "Bug reports"
```

`create` returns the link's public ID and shareable URL. Every other command addresses the link by that public ID.

```bash theme={"theme":"css-variables"}
jam recording-links jams <id> --limit 50
jam recording-links update <id> --name "Q3 support intake"
jam recording-links delete <id>
```

`jams` lists the Jams recorded through a link. `update` edits its settings (name, folder, reference, Jam title, expiration, metadata). `delete` soft-deletes the link so it stops accepting new recordings, while the Jams it already collected stay. To connect a new domain, run `jam recording-links verify <url>` and open the returned link in a browser where Jam is live on that domain.

## Output mode

The CLI pretty-prints when stdout is a TTY and emits compact JSON when output is piped. Force JSON output in any context with the top-level `--json` flag:

```bash theme={"theme":"css-variables"}
jam --json auth status
jam --json get jam <id> | jq '.title'
```

Machine consumers (agents, scripts) should pass `--json` so output stays parseable regardless of where the command runs. Exception: `jam doctor` always prints a human-readable report.

## Pagination

Paginated commands return:

```json theme={"theme":"css-variables"}
{
  "items": [...],
  "next_cursor": "<opaque>" | null,
  "truncated": true | false,
  "hint": "Use --after=<cursor> to fetch the next page."
}
```

Walk every page in a shell loop:

```bash theme={"theme":"css-variables"}
cursor=""
while :; do
  page=$(jam --json get console "$ID" --limit 500 ${cursor:+--after "$cursor"})
  echo "$page" | jq -c '.items[]'
  cursor=$(echo "$page" | jq -r '.next_cursor // empty')
  [ -z "$cursor" ] && break
done
```

`--limit` caps each page at 500. Defaults: 50 for `get` commands, 20 for `list` commands.

## Exit codes

The exit code is authoritative. Branch on it, not on stderr parsing.

| Code | Name       | When                                                   |
| ---- | ---------- | ------------------------------------------------------ |
| 0    | success    | Command completed.                                     |
| 1    | generic    | Unclassified error.                                    |
| 2    | usage      | Invalid flag or argument.                              |
| 3    | auth       | Not authenticated or token rejected (HTTP 401 or 403). |
| 4    | not\_found | Resource missing (HTTP 404).                           |
| 5    | validation | Enum or integer validation failed.                     |
| 6    | server     | Upstream returned 5xx.                                 |

In JSON mode, errors print to stderr as `{"error":{"code":"...","message":"..."}}`. `valid_values` is included on validation errors when applicable.

## Environment variables

| Variable           | Purpose                                                                                                                            |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| `JAM_TOKEN`        | Bearer token used in place of stored credentials. The CLI uses it for the lifetime of the process and never writes it to disk.     |
| `JAM_NO_TELEMETRY` | Set to `1` to disable all CLI telemetry: lifecycle events (install, update, uninstall) plus per-command usage and error reporting. |

## Update and uninstall

Install the latest CLI binary:

```bash theme={"theme":"css-variables"}
jam upgrade
```

Install a specific version:

```bash theme={"theme":"css-variables"}
jam upgrade --target 0.2.0
```

The CLI verifies the new binary's checksum, runs a `--version` smoke test, and replaces the running binary atomically. On Windows the running `.exe` is locked, so each version installs into its own folder and `jam upgrade` re-points a `jam` command at the new one. A `jam` process you already have open keeps running the old version until you restart it.

Remove the CLI and local data:

```bash theme={"theme":"css-variables"}
jam uninstall
```

Skip the confirmation in non-interactive environments:

```bash theme={"theme":"css-variables"}
jam uninstall --yes
```

Uninstall removes `~/.local/bin/jam`, the `~/.local/state/jam/` state directory, your stored credentials in `~/.config/jam/`, and the `PATH` marker the installer added to your shell rc files. On Windows it removes the `%LOCALAPPDATA%\Programs\Jam` install folder and drops its entry from your user `PATH`.

<Warning>
  `jam uninstall` is irreversible. Re-install via the curl one-liner to recover.
</Warning>
