Metadata-Version: 2.4
Name: lql-cli
Version: 0.2.0
Summary: lql — CLI for the Liquid DataViewer platform
Project-URL: Homepage, https://github.com/Liquid4All/lql
Author: Liquid AI
License: MIT
Requires-Python: >=3.9
Requires-Dist: httpx>=0.27
Requires-Dist: huggingface-hub>=0.24
Requires-Dist: rich>=13.0
Requires-Dist: typer>=0.12
Description-Content-Type: text/markdown

# lql — Liquid Query Language CLI

Scriptable CLI for the [Liquid DataViewer](https://dataviewer.liquid.ai) platform. Designed for both humans and AI agents (Claude Code, Codex, etc.) to automate datasets, eval analysis, spec docs, annotations, and more.

## Quick start

```bash
uv tool install lql-cli               # install the CLI (or: pipx install lql-cli); the command is `lql`
lql login                             # authenticate (opens a browser)
lql skills install                    # teach Claude Code + Codex how to use lql
```

## Install

`lql` is a Python package (requires Python ≥ 3.9), distributed on PyPI as **`lql-cli`** (the
command it installs is `lql`). Install it as a standalone CLI tool with
[uv](https://docs.astral.sh/uv/):

```bash
uv tool install lql-cli
```

Or with pipx / pip:

```bash
pipx install lql-cli
# or
pip install lql-cli
```

Run it without installing:

```bash
uvx --from lql-cli lql instructions
```

Or build from source:

```bash
git clone https://github.com/Liquid4All/lql
cd lql
uv tool install .     # or: pip install -e .
```

Update to the latest version with `uv tool upgrade lql-cli` (or `pipx upgrade lql-cli` / `pip install -U lql-cli`).

## Authentication

### Interactive login (browser)

```bash
lql login
```

Opens a browser window. After authorizing, credentials are saved to `~/.lql/config.json`.

### Non-interactive (API key)

```bash
export LQL_API_KEY=ak_live_...
lql login         # stores key in config
# or skip config entirely — just set the env var
```

### Logout

```bash
lql logout
```

## Environment variables

| Variable | Description |
|---|---|
| `LQL_API_KEY` | API token (bypasses config file) |
| `LQL_API_URL` | Override API base URL |
| `LQL_HF_TOKEN` | HuggingFace token (required for `datasets upload`) |
| `LQL_EVAL_WORKSPACE` | Default workspace for `eval list` |

## Command reference

### Auth

```
lql login                        Authenticate (browser or LQL_API_KEY)
lql logout                       Revoke key and clear profile
lql whoami                       Show current user
```

### Workspaces

```
lql workspaces list                              List all workspaces
lql workspaces create <name>                     Create a workspace
lql workspaces show <id>                         Show workspace details
lql workspaces update <id> --name <n>            Rename a workspace
lql workspaces delete <id>                       Delete a workspace
lql workspaces members list <id>                 List members
lql workspaces members add <id> <email>          Add member by email
lql workspaces members remove <id> <uid>         Remove member by user ID
```

### Datasets

```
lql datasets list [--workspace <id>]             List datasets
lql datasets show <id>                           Show dataset details
lql datasets create --workspace <id> --hf-repo <repo> [--name <n>] [--split <s>]
lql datasets create --workspace <id> --hf-bucket <org/bucket> --key <path-or-glob> [--name <n>]
                                                 From an HF storage bucket (e.g. --key 'data/*.parquet')
lql datasets sync <id>                           Trigger sync (HF repo, S3, or HF bucket)
lql datasets schema <id>                         Show column schema
lql datasets rows <id> [--limit N] [--offset N]  Fetch rows
lql datasets delete <id>                         Delete dataset
lql datasets push <id>                           Push to HuggingFace
lql datasets push-status <id> [--job <id>]       Check push job status
lql datasets upload <file> --workspace <id> --name <repo-name> [--split <s>]
                                                 Upload local file → HF → dataset
```

`datasets upload` requires `LQL_HF_TOKEN`.

### Evals (dataset analysis)

Eval datasets are evaluation-run output — each row a sample with a model
`response` and a `correct` verdict. They're detected automatically. These
commands are the data primitives for error analysis: they slice and summarize
the dataset, and you do the reasoning over what they return.

```
lql eval list [--workspace <id>]                 List eval datasets only
                                                 Defaults to LQL_EVAL_WORKSPACE; without a
                                                 workspace, lists only evals you own.
lql eval correctness <id>                        Fast accuracy + correct/incorrect/missing counts
lql eval stats <id>                              Accuracy + error-type distribution + token stats
lql eval samples <id> [--filter correct|incorrect|missing|all]
                       [--search <text>] [--error-type <value>]
                       [--columns a,b] [--limit N] [--offset N]
                                                 Slice the dataset for error analysis. Filters
                                                 AND together; prints an `index` column per row.
lql eval sample <id> --row <index>               Read one full sample (the conversation) by the
                                                 `index` returned from `eval samples`
```

Notes:

- `--search` matches a substring on the prompt **or** response column (either hit counts). Override the searched columns with `--search-columns a,b`.
- `--error-type` values come from the `error_field` / `error_distribution` reported by `eval stats`.
- Use the `index` from `eval samples` directly as `eval sample --row <index>`.

Typical analysis loop:

```bash
lql eval list --workspace <id>                   # find the eval dataset
lql eval stats <id>                              # accuracy + where the errors cluster
lql eval samples <id> --filter incorrect --limit 20   # pull the misses
lql eval sample <id> --row 42                    # read one failure in full
```

### Edits

```
lql edits list <dataset_id> [--limit N]          List edits
lql edits count <dataset_id>                     Count edits
lql edits add <dataset_id> --row <ext_id> --column <col> --value <json>
lql edits delete <dataset_id> <edit_id>          Delete an edit
```

### Spec docs

```
lql spec show --workspace <id>                   Show current spec doc
lql spec pull --workspace <id> [-o <file>] [--stdout]
                                                 Pull markdown (writes SPEC.md by default)
lql spec push --workspace <id> [--file <f>] --message <m> [--base-version-id <id>]
                                                 Defaults --file to SPEC.md; --message required
lql spec history --workspace <id>                Version history
lql spec diff --workspace <id> --version-id <id> [--compare-to <id>]
lql spec generate --workspace <id>               AI-generate a spec from the workspace's datasets
```

`push` auto-detects create-vs-update: with no existing doc it creates v1, otherwise it commits on
top of the current HEAD (auto-resolved unless `--base-version-id` is given). On conflict (409),
`spec push` exits with code 4 — pull again, re-apply, and push.

### Review (annotations, highlights, issues, reports)

These act directly on a **dataset** — the CLI resolves the dataset's review session for you, so you
never manage sessions by hand. Advanced: pass `--session <id>` to target a specific session for
multi-pass review (a session id is returned in the JSON of any annotation/highlight/report).

#### Annotations

```
lql annotations list <dataset_id> [--session <id>]
lql annotations add <dataset_id> --row <ext_id> [--rating <n>] [--note <str>] [--session <id>]
```

#### Highlights

Highlights mark a text span (`--start`/`--end` are character offsets into the row's `--column` value).

```
lql highlights list <dataset_id> [--session <id>]
lql highlights add <dataset_id> --row <ext_id> --column <col> --start <n> --end <n> --text <str>
                  [--issue <id>] [--color <hex>] [--note <text>] [--session <id>]
```

#### Issues

A per-dataset taxonomy (name/color) used to tag highlights via `highlights add --issue <id>`.

```
lql issues list <dataset_id>
lql issues create <dataset_id> --name <str> [--description <str>] [--color <hex>]
```

#### Reports

```
lql reports list <dataset_id> [--session <id>]
lql reports show <report_id>                     Show a report
lql reports create <dataset_id> --title <title> [--summary <text>] [--session <id>]
                                                 Publish a report (bundles annotations + LLM analysis)
```

### Buckets

S3-compatible:

```
lql buckets list                                 List S3 buckets
lql buckets show <id>                            Show bucket details
lql buckets probe <id>                           Test bucket connectivity + credentials
lql buckets objects <id> [--prefix <str>]        List objects
lql buckets attach <bucket_id> --workspace <id>  Attach bucket to workspace
lql buckets detach <bucket_id> --workspace <id>  Detach bucket from workspace
```

Hugging Face buckets (connect → add datasets; auth is your HF token):

```
lql buckets list-hf                              List HF bucket connections
lql buckets connect-hf <owner/bucket> --workspace <id> [--label <l>] [--hf-key <id>]
                                                 Connect an HF bucket and attach it to a workspace
lql buckets create-dataset <bucket_id> --workspace <id> --key <path-or-glob> [--name <display>]
                                                 Create a dataset from a connected HF bucket
```

### Skills (agent setup)

Install the `lql` agent skill so coding agents (Claude Code, Codex) know how to use lql. The skill
is a thin pointer that tells the agent to run `lql instructions`, so it never goes stale.

```
lql skills install [--tool claude|codex|both] [--project] [--force]
                                                 Install to ~/.claude and ~/.codex (both, by default)
lql skills uninstall [--tool claude|codex|both] [--project]
```

`--project` installs into `./.claude` and `./.codex` in the current directory instead of the home dir.

### Instructions

```
lql instructions                                 Print the full agent reference (all commands,
                                                 flags, examples, and workflows) in one read
```

## Global flags

All commands accept:

| Flag | Description |
|---|---|
| `--json` | Output raw JSON to stdout |
| `--profile <name>` | Use a named config profile |
| `--api-url <url>` | Override the API base URL |

## Exit codes

| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | General error |
| 2 | Unauthenticated / forbidden |
| 3 | Not found |
| 4 | Conflict (e.g. spec push version conflict) |
| 5 | Server error |

## Config file

`~/.lql/config.json` (mode 0600):

```json
{
  "current_profile": "default",
  "profiles": {
    "default": {
      "token": "ak_live_...",
      "key_id": "uuid",
      "api_url": "https://api.dataviewer.liquid.ai"
    }
  }
}
```
