Skip to main content

ldv — CLI for the Liquid DataViewer platform (formerly lql)

Project description

ldv — Liquid DataViewer CLI

Scriptable CLI for the Liquid DataViewer platform. Designed for both humans and AI agents (Claude Code, Codex, etc.) to automate datasets, eval analysis, spec docs, annotations, and more.

A Python package (Python ≥ 3.12), published on PyPI as ldv-cli — the installed command is ldv.

Renamed from lql. This CLI was formerly published as lql-cli with an lql command. The lql command still works as an alias, and the legacy LQL_* environment variables and ~/.lql/config.json are still honored, so existing setups keep working. New users should install ldv-cli and use ldv.

Quick start

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

Install

ldv is a Python package (requires Python ≥ 3.12), distributed on PyPI as ldv-cli (the command it installs is ldv). Install it as a standalone CLI tool with uv:

uv tool install ldv-cli

Or with pipx / pip:

pipx install ldv-cli
# or
pip install ldv-cli

Run it without installing:

uvx --from ldv-cli ldv instructions

Or build from source:

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

Update to the latest version with ldv update --run, which detects how ldv was installed (uv tool / pipx / pip) and runs the matching upgrade. Run ldv update (no flag) to just print the command without executing it.

Authentication

Interactive login (browser)

ldv login

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

Non-interactive (API key)

export LDV_API_KEY=ak_live_...
ldv login         # stores key in config
# or skip config entirely — just set the env var

Logout

ldv logout

Environment variables

Variable Description
LDV_API_KEY API token (bypasses config file)
LDV_API_URL Override API base URL
LDV_HF_TOKEN HuggingFace token (required for datasets upload)
LDV_EVAL_WORKSPACE Default workspace for eval list
LDV_ALLOW_INSECURE_API_URL Set to 1 to allow a plaintext http:// API URL to a non-loopback host (off by default — the token is only sent over HTTPS or to localhost)

Command reference

Running a group with no subcommand (e.g. ldv datasets) lists its subcommands. For faster typing, aliases and unique prefixes resolve everywhere: group aliases (ds, ws, ev, ann, hl, rep, bkt, iss), verb aliases (ls=list, rm/del=delete, new/mk=create, info=show), and prefixes (ldv datasets llist). So ldv ds ls --workspace <id>ldv datasets list --workspace <id>. The canonical names below always work (use those in scripts).

Auth

ldv login                        Authenticate (browser or LDV_API_KEY)
ldv logout                       Revoke key and clear profile
ldv whoami                       Show current user

Workspaces

ldv workspaces list [--search <text>]            List workspaces (--search filters by name/slug)
ldv workspaces create <name>                     Create a workspace
ldv workspaces show <id>                         Show workspace details
ldv workspaces update <id> --name <n>            Rename a workspace
ldv workspaces delete <id>                       Delete a workspace
ldv workspaces members list <id>                 List members
ldv workspaces members add <id> <email>          Add member by email
ldv workspaces members remove <id> <uid>         Remove member by user ID

Datasets

ldv datasets list [--workspace <id>] [--search <text>]   List datasets (--search filters by name/HF repo)
ldv datasets show <id>                           Show dataset details
ldv datasets create --workspace <id> --hf-repo <repo> [--name <n>] [--split <s>]
ldv datasets create --workspace <id> --hf-bucket <org/bucket> --key <path-or-glob> [--name <n>]
                                                 From an HF storage bucket (e.g. --key 'data/*.parquet')
ldv datasets sync <id>                           Trigger sync (HF repo, S3, or HF bucket)
ldv datasets schema <id>                         Show column schema
ldv datasets rows <id> [-f "col<op>value"] [--columns a,b] [--limit N] [--offset N]
                                                 Fetch rows (-f/--filter: same syntax everywhere)
ldv datasets delete <id>                         Delete dataset
ldv datasets push <id>                           Push to HuggingFace
ldv datasets push-status <id> [--job <id>]       Check push job status
ldv datasets upload <file> --workspace <id> --name <repo-name> [--split <s>]
                                                 Upload local file → HF → dataset

datasets upload requires LDV_HF_TOKEN.

Preview

View dataset samples in the terminal — a Textual TUI with a chat-style layout (user turns on the right, system/assistant/tool on the left). It renders the same formats as the DataViewer web UI: OpenAI {role, content}, structured/ multimodal content (text/image/audio), ShareGPT {from, value}, native OpenAI tool_calls, plus <think> reasoning blocks, <|tool_call_start|>…<|tool_call_end|> / Python / XML / JSON tool calls, tool results, tool-definition tables, and code.

Works on a local .jsonl/.json file, a platform dataset ID, or — with --hf — a HuggingFace repo. No browser, and nothing to forward over SSH — it's just the terminal.

ldv preview <file.jsonl|file.json>     Local file: each line/object is a row
ldv preview <dataset-id>               Platform dataset (fetched & paged lazily)
ldv preview <org/name> --hf            HuggingFace repo: sync to DataViewer, then view
ldv preview <src> -c <field>           Force field(s) as conversations (repeatable)
ldv preview <src> -f "col=value"       Filter rows (repeatable, AND); local & platform
ldv preview <src> -n <N>               Page size when paging a platform dataset
ldv preview <src> --offset N           Start at row index N
ldv preview <src> --title "<title>"    Title shown in the viewer header

Filtering (--filter/-f) — one syntax everywhere. The same flag and syntax work on preview, datasets rows, and eval samples. Show only matching rows — preview also filters local files (client-side); platform datasets filter server-side. Repeatable; filters AND together; string match is case-insensitive. Operators: =, !=, ~ (contains), >, <, >=, <=.

ldv preview <dataset-id> -f "domain=telecom"
ldv preview data.jsonl -f "reward>=0.8" -f "split=test"     # both must hold
ldv preview <dataset-id> -f "model~lfm"                      # contains

HuggingFace datasets (--hf). ldv preview org/name --hf syncs the repo into a DataViewer workspace, then opens it. You pick the target workspace from an interactive list (or pass --workspace <id>; --split defaults to train). Already-synced repos are reused — no duplicate, instant re-open.

ldv preview tatsu-lab/alpaca --hf
ldv preview org/name --hf --split validation --workspace <id>

Media. Images render inline in terminals that support an image protocol (Kitty/Ghostty, iTerm2, Sixel; falls back to a compact 🖼 … placeholder elsewhere) — both multimodal image_url/data-URI segments and image-mode columns. Audio can't play inline in a terminal, so each clip shows a line and p plays the current sample's audio via the system player (afplay/ open). Images render inline in pager mode (one sample at a time); scroll mode shows placeholders to avoid decoding the whole buffer.

Navigation — two modes, toggle with m:

  • pager (default): one sample at a time · ←/→ or n/b switch samples · ↑/↓/j/k/PgUp-Dn scroll
  • scroll: all samples in one buffer · n/b jump between samples · arrows scroll
  • copy: Tab/Shift+Tab move a highlight between blocks · c copies the focused message/field · Y copies the whole sample as JSON (via OSC 52 — reaches your local clipboard over SSH where the terminal supports it, e.g. Ghostty/iTerm2; not macOS Terminal)
  • p play audio · q quits
ldv preview examples/agent-traces.jsonl     # 20-sample file of agent-trace/tool-use formats
ldv preview <dataset-id>                     # browse a platform dataset, paged on demand

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.

ldv eval list [--workspace <id>] [--runid <id>] [--taskid <id>]
                                                 List eval datasets only. --runid/--taskid filter by
                                                 run<id>/task<id> in the name or parquet storage path
                                                 (e.g. run11213_task72284.parquet); they AND together.
                                                 Defaults to LDV_EVAL_WORKSPACE; without a
                                                 workspace, lists only evals you own.
ldv eval correctness <id>                        Fast accuracy + correct/incorrect/missing counts
ldv eval stats <id>                              Accuracy + error-type distribution + token stats
ldv eval samples <id> [-f "col<op>value" ...] [--correct|--incorrect|--missing]
                       [--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.
ldv eval sample <id> --row <index>               Read one full sample (the conversation) by the
                                                 `index` returned from `eval samples`

Notes:

  • -f/--filter is the unified column filter — same syntax as preview and datasets rows (see Filtering above).
  • --correct / --incorrect / --missing are convenience flags for the canonical correctness filter (mutually exclusive). They AND with any -f filters, --search, and --error-type.
  • --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:

ldv eval list --workspace <id>                   # find the eval dataset
ldv eval stats <id>                              # accuracy + where the errors cluster
ldv eval samples <id> --incorrect --limit 20     # pull the misses
ldv eval samples <id> --incorrect -f "reasoning_tokens>30000"  # misses that ran long
ldv eval sample <id> --row 42                    # read one failure in full

Edits

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

Spec docs

ldv spec show --workspace <id>                   Show current spec doc
ldv spec pull --workspace <id> [-o <file>] [--stdout]
                                                 Pull markdown (writes SPEC.md by default)
ldv spec push --workspace <id> [--file <f>] --message <m> [--base-version-id <id>]
                                                 Defaults --file to SPEC.md; --message required
ldv spec history --workspace <id>                Version history
ldv spec diff --workspace <id> --version-id <id> [--compare-to <id>]
ldv 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

ldv annotations list <dataset_id> [--session <id>]
ldv 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).

ldv highlights list <dataset_id> [--session <id>]
ldv 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>.

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

Reports

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

Buckets

S3-compatible:

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

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

ldv buckets list-hf                              List HF bucket connections
ldv buckets connect-hf <owner/bucket> --workspace <id> [--label <l>] [--hf-key <id>]
                                                 Connect an HF bucket and attach it to a workspace
ldv 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 ldv agent skill so coding agents (Claude Code, Codex) know how to use ldv. The skill is a thin pointer that tells the agent to run ldv instructions, so it never goes stale.

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

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

Instructions

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

Update

ldv update                                       Detect install method (uv/pipx/pip), print upgrade cmd
ldv update --run                                 Detect and run the upgrade in place

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

~/.ldv/config.json (mode 0600):

{
  "current_profile": "default",
  "profiles": {
    "default": {
      "token": "ak_live_...",
      "key_id": "uuid",
      "api_url": "https://liquid-anchor-api.fly.dev"
    }
  }
}

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ldv_cli-0.12.0.tar.gz (77.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ldv_cli-0.12.0-py3-none-any.whl (67.8 kB view details)

Uploaded Python 3

File details

Details for the file ldv_cli-0.12.0.tar.gz.

File metadata

  • Download URL: ldv_cli-0.12.0.tar.gz
  • Upload date:
  • Size: 77.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.10 {"installer":{"name":"uv","version":"0.10.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for ldv_cli-0.12.0.tar.gz
Algorithm Hash digest
SHA256 e9a7c84ccee6047d67de7a845c40dadd3b2191860db857351a4aeeef8c1a5919
MD5 30efd26ab3abc8864dda0a489e3c89b5
BLAKE2b-256 3cad79adfb6ad51094b98f649fe926b375f3aa62ceb712aaa951e59550af0573

See more details on using hashes here.

File details

Details for the file ldv_cli-0.12.0-py3-none-any.whl.

File metadata

  • Download URL: ldv_cli-0.12.0-py3-none-any.whl
  • Upload date:
  • Size: 67.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.10 {"installer":{"name":"uv","version":"0.10.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for ldv_cli-0.12.0-py3-none-any.whl
Algorithm Hash digest
SHA256 90d8789e7efcb0036060a3242c99e6a13aa039d5798b1a00c7cc121585c408ae
MD5 8e7d6b41b75a1dddb5a3741b91fb343b
BLAKE2b-256 875e51df6ac5898603c1f2ed4fcc327c6f62e12353d8de1360ed79a0a9ab6929

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page