# Command-Line Interface (CLI)

The `ml-dash` CLI authenticates, queries, and manages projects and experiments on a remote server. Installed with the Python package:

```bash
pip install ml-dash
ml-dash --help
```

| Command | Description |
|---|---|
| `version` | Show ml-dash version |
| `login` | Authenticate via OAuth2 device flow |
| `logout` | Clear stored token |
| `profile` | Show current user |
| `api` | Send raw GraphQL queries/mutations |
| `list` | List projects, experiments, or tracks |
| `create` | Create a project |

All commands accept `--dash-url` / `--api-url` (defaults to stored config or `https://api.dash.ml`) and `--help`.

---

## `ml-dash version`

Print the installed version.

```bash
ml-dash version
```

---

## `ml-dash login`

Authenticate using the OAuth2 device authorization flow. Displays a URL, user code, and QR code; opens a browser; polls for authorization (10-minute timeout); stores the token in the system keychain.

```bash
ml-dash login [--dash-url URL] [--auth-url URL] [--no-browser]
```

| Flag | Description |
|---|---|
| `--dash-url`, `--api-url` | ML-Dash server URL |
| `--auth-url` | OAuth authorization server URL |
| `--no-browser` | Don't open the browser automatically |

```bash
ml-dash login --dash-url https://your-server.com
```

After login, all commands pick up the stored token; no `--api-key` flag needed.

---

## `ml-dash logout`

Clear the stored token from the system keychain.

```bash
ml-dash logout
```

---

## `ml-dash profile`

Show the current authenticated user. By default fetches live data from the server; `--cached` reads only the stored token payload.

```bash
ml-dash profile [--dash-url URL] [--json] [--cached]
```

| Flag | Description |
|---|---|
| `--json` | Output as JSON |
| `--cached` | Use cached token data instead of fetching |

Displays username, user ID, name, email, remote URL, and token expiration status.

```bash
ml-dash profile --json
```

---

## `ml-dash api`

Send raw GraphQL queries or mutations.

```bash
ml-dash api (--query QUERY | --mutation MUTATION) [--jq PATH] [--dash-url URL]
```

| Flag | Description |
|---|---|
| `--query`, `-q` | GraphQL query string |
| `--mutation`, `-m` | GraphQL mutation string |
| `--jq PATH` | Extract a value by dot-path (e.g. `.me.username`) |

Notes:
- Single quotes are auto-converted to double quotes.
- `--jq` paths skip the top-level `data` key — use `.me.username`, not `.data.me.username`.
- Bare bodies are auto-wrapped: `me { username }` becomes `{ me { username } }`.

```bash
ml-dash api --query "me { username }" --jq ".me.username"
```

---

## `ml-dash create`

Create a new project. If the project already exists, the command exits successfully with a warning.

```bash
ml-dash create -p PROJECT [-d DESCRIPTION] [--dash-url URL]
```

| Flag | Description |
|---|---|
| `-p`, `--project` | `project` or `namespace/project` (required). Namespace auto-resolves from the authenticated user if omitted. |
| `-d`, `--description` | Project description |

```bash
ml-dash create -p tom/my-project -d "Baseline experiments"
```

---

## `ml-dash list`

List projects, experiments, or tracks with server-side pagination (50 per page; navigate with `n`/`→`/`Space` for next, `p`/`←` for previous, any other key to quit).

```bash
ml-dash list [-p PROJECT] [-n NAMESPACE] [--status STATUS] [--tags TAGS]
             [--detailed] [--tracks] [--topic-filter TOPIC]
             [--dash-url URL] [-v]
```

| Flag | Description |
|---|---|
| `-p`, `--project` | Project filter. Supports glob patterns — **always quote them** to prevent shell expansion |
| `-n`, `--namespace` | Namespace (defaults to authenticated user) |
| `--status` | Filter by `COMPLETED`, `RUNNING`, `FAILED`, or `ARCHIVED` |
| `--tags` | Comma-separated tag filter |
| `--detailed` | Show tags and created time |
| `--tracks` | List tracks inside an experiment (requires full `namespace/project/experiment` path) |
| `--topic-filter` | Filter tracks by topic pattern (e.g. `robot/*`) |
| `-v`, `--verbose` | Show full error tracebacks |

Glob patterns expand against the current namespace: `tes*` becomes `{namespace}/tes*/*`; `tom/tes*` becomes `tom/tes*/*`; fully-qualified patterns are left unchanged.

```bash
# List your projects
ml-dash list

# Wildcard search (quote the pattern)
ml-dash list -p 'tom/tes*'

# Tracks inside an experiment, filtered by topic
ml-dash list --tracks -p tom/test/my-experiment --topic-filter "robot/*"
```

See [Experiments](/experiments.md) and [Metrics](/metrics.md) for working with the data these commands surface.

---

## CI / scripting

Store the token in `~/.dash/config.json` to skip `login`:

```json
{
  "remote_url": "https://api.dash.ml",
  "api_key": "your-jwt-token"
}
```

If `ml-dash` isn't on PATH, run `python -m ml_dash.cli` or `uv run ml-dash`.
