# CLI overview

> Every Esker command, what it does, and where to learn more.

The CLI is installed by `pip install esker` (or `uv add esker`). Two equivalent entry points point at the same binary:

```sh
esker <cmd>
esk <cmd>      # short alias
```

`esker` (no args) prints help. Every subcommand accepts `--help` for its own usage.

## Commands by job

### Build a dataset

| command                                             | what                                                  |
| --------------------------------------------------- | ----------------------------------------------------- |
| [`esker list`](https://esker.so/docs/cli/authoring.md#esker-list)            | List pipelines registered in this project             |
| [`esker run <domain>`](https://esker.so/docs/cli/authoring.md#esker-run)     | Execute a pipeline, write parquet locally             |
| [`esker test [<domain>]`](https://esker.so/docs/cli/authoring.md#esker-test) | Run fixtures against your `transform`                 |
| [`esker check <domain>`](https://esker.so/docs/cli/authoring.md#esker-check) | Diff your local schema against the last published one |
| [`esker push <domain>`](https://esker.so/docs/cli/authoring.md#esker-push)   | Run, gate, and upload to the hub                      |

Detailed reference: [CLI authoring](https://esker.so/docs/cli/authoring.md).

### Consume a dataset

| command                                              | what                                           |
| ---------------------------------------------------- | ---------------------------------------------- |
| [`esker pull <ref>`](https://esker.so/docs/cli/reading.md#esker-pull)         | Download a parquet, content-hash verify        |
| [`esker view <ref>`](https://esker.so/docs/cli/reading.md#esker-view)         | One-screen summary: header + sample rows       |
| [`esker head <ref>`](https://esker.so/docs/cli/reading.md#esker-head)         | Records, filterable with `--where`             |
| [`esker schema <ref>`](https://esker.so/docs/cli/reading.md#esker-schema)     | The schema as a typed table                    |
| [`esker manifest <ref>`](https://esker.so/docs/cli/reading.md#esker-manifest) | The manifest as `key  value` lines             |
| [`esker search <query>`](https://esker.so/docs/cli/reading.md#esker-search)   | Find publishers of a name, or full-text search |

Detailed reference: [CLI reading](https://esker.so/docs/cli/reading.md).

### Manage bindings

| command                                              | what                                            |
| ---------------------------------------------------- | ----------------------------------------------- |
| [`esker add <owner>/<name>`](https://esker.so/docs/cli/bindings.md#esker-add) | Bind a dataset, pin its version in `esker.lock` |
| [`esker remove <name>`](https://esker.so/docs/cli/bindings.md#esker-remove)   | Drop a binding                                  |
| [`esker sync`](https://esker.so/docs/cli/bindings.md#esker-sync)              | Reconcile the cache against the lockfile        |
| [`esker upgrade <name>`](https://esker.so/docs/cli/bindings.md#esker-upgrade) | Re-resolve to the hub's latest version          |

Detailed reference: [CLI bindings](https://esker.so/docs/cli/bindings.md).

### Sign in and manage your account

| command                                                                               | what                                             |
| ------------------------------------------------------------------------------------- | ------------------------------------------------ |
| [`esker login`](https://esker.so/docs/cli/auth.md#sign-in)                                                     | Browser sign-in                                  |
| [`esker logout`](https://esker.so/docs/cli/auth.md#sign-out)                                                   | Clear local credentials                          |
| [`esker whoami`](https://esker.so/docs/cli/auth.md#check-who-youre-signed-in-as)                               | Show signed-in user and active handle            |
| [`esker config set-owner <handle>`](https://esker.so/docs/cli/auth.md)                                         | Print a `pyproject.toml` snippet                 |
| [`esker config set-handle <handle>`](https://esker.so/docs/cli/auth.md#rename-your-handle)                     | Rename your handle (server-side)                 |
| [`esker transfer <ref> <new_owner>`](https://esker.so/docs/cli/auth.md#transfer-dataset-ownership)             | Hand a dataset to another handle                 |
| [`esker visibility <ref> public\|private`](https://esker.so/docs/cli/auth.md#make-a-dataset-public-or-private) | Toggle dataset visibility (phase 1: public only) |

Detailed reference: [Auth](https://esker.so/docs/cli/auth.md).

## Refs

Most read commands accept a _ref_ — the address of a dataset on the hub. A ref can be:

| form                       | meaning                                                  |
| -------------------------- | -------------------------------------------------------- |
| `<owner>/<name>`           | latest version published by `<owner>`                    |
| `<owner>/<name>@<version>` | a specific version                                       |
| `<owner>/<name>@latest`    | same as no version                                       |
| `<name>` (bare)            | resolved through your project's [bindings](https://esker.so/docs/sdk/bindings.md) |

Bare names are the recommended path in code and CLI alike. They keep the owner choice in one explicit place (`esker add`) and the rest of your usage clean.

## Output conventions

Esker's CLI is calm and dense. A successful command is two or three lines:

```
$ esker push us.treasury.yields
  archie/us.treasury.yields@2.0.0
  4,205 records · 0.7s · output/us.treasury.yields.parquet
  pushed archie/us.treasury.yields@2.0.0
```

Errors are two lines — the type and message in red, then a `→ file:line` pointer in dim:

```
  ValueError: esker_id jurisdiction 'us' does not match DOMAIN_ID jurisdiction 'ca'
  → my_pipelines/sec_companies.py:34
```

Pass `-v` / `--verbose` to add the full traceback.

Every read command supports `--json` for piping into `jq`:

```sh
esker manifest archie/us.treasury.yields --json | jq '.content_hash'
```

The output is pretty-printed and newline-terminated.

## Exit codes

- `0` — success.
- `1` — anything that prevents the command from completing. Specific failure mode is in the error message.

There are no other exit codes. Scripts can branch on `$?` cleanly.

## See also

- [Getting started](https://esker.so/docs/getting-started.md) — full tutorial
- [CLI authoring](https://esker.so/docs/cli/authoring.md) · [CLI reading](https://esker.so/docs/cli/reading.md) · [CLI bindings](https://esker.so/docs/cli/bindings.md) · [Auth](https://esker.so/docs/cli/auth.md)
- [Errors and footguns](https://esker.so/docs/guides/errors.md) — every error path, verbatim
