> ## 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.

# CLI

> Authenticate, read Jam data, and create Jams from your terminal. Built for shell scripts, CI jobs, and AI coding agents.

The Jam CLI runs every Jam read and write from your terminal. Authenticate once, then pipe Jam data into shell scripts, CI jobs, or AI coding agents.

<Info>
  The CLI runs on macOS and Linux (x64 and arm64). Windows users can run it under WSL.
</Info>

## Install

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
```

## Authenticate

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

<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 or CI jobs:

    ```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](/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, scan the [command reference](#command-reference) for the command you need.

## Command reference

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 <lvl>]`                                                        | Console log events                                 | Paginated   |
| `jam get network <id> [--status <code>] [--method <verb>] [--host <h>] [--content-type <ct>]` | Network requests                                   | Paginated   |
| `jam get events <id>`                                                                         | Full unfiltered event stream                       | Paginated   |
| `jam get transcript <id>`                                                                     | WebVTT transcript 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 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 update jam <id> --folder <id>`                                                           | Move a Jam to a folder                             | Receipt     |
| `jam skills list`                                                                             | List bundled agent skills                          | List        |
| `jam skills install [name] [--target <agent>] [--project]`                                    | Install bundled skill into an agent's directory    | 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, and auth status   | Single      |
| `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.

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

Two media reads:

* `jam get transcript <id>` returns `{ status, vtt }`. `vtt` is null while generation is pending.
* `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 and replay Jams it's the poster image.

### 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`. The poster image is generated downstream if you omit `posterImagePath`.

Add a comment to a Jam:

```bash theme={"theme":"css-variables"}
jam create comment <jamId> "Logs at 00:42 show a 500 on /checkout." --at 42000
```

`<body>` is Markdown. `--at` pins the comment to a video timestamp in milliseconds.

Move a Jam to a folder:

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

Pass an empty string to remove the Jam from its current folder.

## 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.

## 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.

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.

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

## Use the CLI with AI coding agents

The CLI ships two surfaces for AI coding agents: a bundled skill and a JSON command catalog.

### Bundled skills

`jam skills install` writes the bundled `SKILL.md` into the location your agent runtime expects (Claude Code, Cursor, Codex, OpenCode). The CLI auto-detects the runtime via environment variables, then falls back to project-level marker directories before defaulting to Claude.

```bash theme={"theme":"css-variables"}
jam skills install                  # auto-detect target, user-global install
jam skills install --project        # install into the current repo
jam skills install --target cursor  # explicit target
jam skills path                     # preview destination without writing
jam skills list                     # list bundled skills
```

The skill teaches your agent which command to reach for at each step (read Jam, filter errors, leave a comment) and how to interpret the structured output.

### Machine-readable command surface

`jam agent-context` prints the command surface as JSON: argument types, flag enums, default limits, and output shapes. Pair it with `--json` on every read or write call to keep tool wrappers thin.

```bash theme={"theme":"css-variables"}
jam agent-context | jq '.commands["get.jam"]'
```

The shape is locked by a snapshot test, so the JSON stays stable across releases inside the same `schema_version`.
