Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 125 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,92 +2,177 @@

Command line interface for [Hotdata](https://www.hotdata.dev).

## Installation
## Install

Build from source (requires Rust):
**Homebrew**

```sh
brew install hotdata-dev/tap/hotdata-cli
```

**Binary (macOS, Linux)**

Download a binary from [Releases](https://github.com/hotdata-dev/hotdata-cli/releases).

**Build from source** (requires Rust)

```sh
cargo build --release
cp target/release/hotdata /usr/local/bin/hotdata
```

## Getting Started
## Connect

Run the following command to authenticate:

```sh
# Initialize config
hotdata init
hotdata auth
```

This launches a browser window where you can authorize the CLI to access your Hotdata account.

# Log in via browser
hotdata auth login
Alternatively, authenticate with an API key using the `--api-key` flag:

# Check auth status
hotdata auth status
```sh
hotdata <command> --api-key <api_key>
```

Or set the `HOTDATA_API_KEY` environment variable (also loaded from `.env` files):

```sh
export HOTDATA_API_KEY=<api_key>
hotdata <command>
```

API key priority (lowest to highest): config file → `HOTDATA_API_KEY` env var → `--api-key` flag.

## Commands

### Workspaces
| Command | Subcommands | Description |
| :-- | :-- | :-- |
| `auth` | `status`, `logout` | Authenticate (run without subcommand to log in) |
| `workspaces` | `list`, `set`, `get`, `create`, `update` | Manage workspaces |
| `connections` | `list`, `get`, `create`, `refresh`, `update`, `delete`, `new` | Manage connections |
| `tables` | `list` | List tables and columns |
| `datasets` | `list`, `create` | Manage uploaded datasets |
| `query` | | Execute a SQL query |
| `results` | `list` | Retrieve stored query results |
| `skills` | `install`, `status` | Manage the hotdata-cli agent skill |

## Global options

| Option | Description | Type | Default |
| :-- | :-- | :-- | :-- |
| `--api-key` | API key (overrides env var and config) | string | |
| `-v, --version` | Print version | boolean | |
| `-h, --help` | Print help | boolean | |

## Workspaces

```sh
hotdata workspace list [--format table|json|yaml]
hotdata workspaces list [--format table|json|yaml]
hotdata workspaces set [<workspace_id>]
```

### Connections
- `list` shows all workspaces with a `*` marker on the active one.
- `set` switches the active workspace. Omit the ID for interactive selection.
- The active workspace is used as the default for all commands that accept `--workspace-id`.

## Connections

```sh
hotdata connections list <workspace_id> [--format table|json|yaml]
hotdata connections list [--workspace-id <id>] [--format table|json|yaml]
hotdata connections get <connection_id> [--workspace-id <id>] [--format yaml|json|table]
hotdata connections refresh <connection_id> [--workspace-id <id>]
hotdata connections new [--workspace-id <id>]
```

### Tables
- `list` returns `id`, `name`, `source_type` for each connection.
- `refresh` triggers a schema refresh for a connection.
- `new` launches an interactive connection creation wizard.

### Create a connection

```sh
# List all tables in a workspace
hotdata tables list <workspace_id> [--format table|json|yaml]
# List available connection types
hotdata connections create list [--format table|json|yaml]

# Inspect schema for a connection type
hotdata connections create list <type_name> --format json

# List columns for a specific connection
hotdata tables list <workspace_id> --connection-id <connection_id> [--format table|json|yaml]
# Create a connection
hotdata connections create --name "my-conn" --type postgres --config '{"host":"...","port":5432,...}'
```

### Query
## Tables

```sh
hotdata query "<sql>" --workspace-id <workspace_id> [--connection <connection_id>] [--format table|json|csv]
hotdata tables list [--workspace-id <id>] [--connection-id <id>] [--schema <pattern>] [--table <pattern>] [--limit <n>] [--cursor <token>] [--format table|json|yaml]
```

## Releasing

Releases use a two-phase workflow wrapping [`cargo-release`](https://github.com/crate-ci/cargo-release).
- Without `--connection-id`: lists all tables with `table`, `synced`, `last_sync`.
- With `--connection-id`: includes column details (`column`, `data_type`, `nullable`).
- `--schema` and `--table` support SQL `%` wildcard patterns.
- Tables are displayed as `<connection>.<schema>.<table>` — use this format in SQL queries.

**Phase 1 — prepare**
## Datasets

```sh
scripts/release.sh prepare <version>
# e.g. scripts/release.sh prepare 0.2.0
hotdata datasets list [--workspace-id <id>] [--limit <n>] [--offset <n>] [--format table|json|yaml]
hotdata datasets <dataset_id> [--workspace-id <id>] [--format table|json|yaml]
hotdata datasets create --file data.csv [--label "My Dataset"] [--table-name my_dataset]
hotdata datasets create --sql "SELECT ..." --label "My Dataset"
```

This will:
1. Create a `release/<version>` branch
2. Bump the version in `Cargo.toml`, update `CHANGELOG.md`, and push the branch
3. Open a GitHub pull request and launch it in the browser
- Datasets are queryable as `datasets.main.<table_name>`.
- `--file`, `--sql`, and `--query-id` are mutually exclusive.
- Format is auto-detected from file extension or content.
- Piped stdin is supported: `cat data.csv | hotdata datasets create --label "My Dataset"`

Squash and merge the PR into `main` when ready.
## Query

**Phase 2 — finish**
```sh
hotdata query "<sql>" [--workspace-id <id>] [--connection <connection_id>] [--format table|json|csv]
```

- Default format is `table`, which prints results with row count and execution time.
- Use `--connection` to scope the query to a specific connection.

## Results

```sh
scripts/release.sh finish
hotdata results <result_id> [--workspace-id <id>] [--format table|json|csv]
hotdata results list [--workspace-id <id>] [--limit <n>] [--offset <n>] [--format table|json|yaml]
```

Run this from any branch after the PR is merged. It will switch to `main`, pull the latest, tag the release, and trigger the dist workflow.
- Query results include a `result-id` in the table footer — use it to retrieve past results without re-running queries.

## Configuration

Config is stored at `~/.hotdata/config.yml` keyed by profile (default: `default`).

Environment variable overrides:
| Variable | Description | Default |
| :-- | :-- | :-- |
| `HOTDATA_API_KEY` | API key (overrides config file) | |
| `HOTDATA_API_URL` | API base URL | `https://api.hotdata.dev/v1` |
| `HOTDATA_APP_URL` | App URL for browser login | `https://app.hotdata.dev` |

## Releasing

Releases use a two-phase workflow wrapping [`cargo-release`](https://github.com/crate-ci/cargo-release).

**Phase 1 — prepare**

```sh
scripts/release.sh prepare <version>
```

Creates a `release/<version>` branch, bumps the version, updates `CHANGELOG.md`, pushes the branch, and opens a pull request.

**Phase 2 — finish**

```sh
scripts/release.sh finish
```

| Variable | Description |
|--------------------|------------------------------------------|
| `HOTDATA_API_KEY` | API key (overrides config) |
| `HOTDATA_API_URL` | API base URL (default: `https://api.hotdata.dev/v1`) |
| `HOTDATA_APP_URL` | App URL for browser login (default: `https://app.hotdata.dev`) |
Switches to `main`, pulls latest, tags the release, and triggers the dist workflow.
26 changes: 13 additions & 13 deletions skills/hotdata-cli/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
---
name: hotdata-cli
description: Use this skill when the user wants to run hotdata CLI commands, query the HotData API, list workspaces, list connections, create connections, list tables, manage datasets, execute SQL queries, or interact with the hotdata service. Activate when the user says "run hotdata", "query hotdata", "list workspaces", "list connections", "create a connection", "list tables", "list datasets", "create a dataset", "upload a dataset", "execute a query", or asks you to use the hotdata CLI.
description: Use this skill when the user wants to run hotdata CLI commands, query the Hotdata API, list workspaces, list connections, create connections, list tables, manage datasets, execute SQL queries, or interact with the hotdata service. Activate when the user says "run hotdata", "query hotdata", "list workspaces", "list connections", "create a connection", "list tables", "list datasets", "create a dataset", "upload a dataset", "execute a query", or asks you to use the hotdata CLI.
version: 0.1.4
---

# HotData CLI Skill
# Hotdata CLI Skill

Use the `hotdata` CLI to interact with the HotData service. In this project, run it as:
Use the `hotdata` CLI to interact with the Hotdata service. In this project, run it as:

```
hotdata <command> [args]
Expand All @@ -16,13 +16,18 @@ Or if installed on PATH: `hotdata <command> [args]`

## Authentication

Config is stored in `~/.hotdata/config.yml` keyed by profile (default: `default`).
API key can also be set via `HOTDATA_API_KEY` env var.
Run `hotdata auth` to authenticate via browser login. Config is stored in `~/.hotdata/config.yml`.

API key resolution (lowest to highest priority):
1. Config file (saved by `hotdata auth`)
2. `HOTDATA_API_KEY` environment variable (or `.env` file)
3. `--api-key <key>` flag (works on any command)

API URL defaults to `https://api.hotdata.dev/v1` or overridden via `HOTDATA_API_URL`.

## Workspace ID

All commands that accept `--workspace-id` are optional. If omitted, the first workspace saved during `hotdata auth login` is used as the default. **Omit `--workspace-id` unless you need to target a specific workspace.**
All commands that accept `--workspace-id` are optional. If omitted, the active workspace is used. Use `hotdata workspaces set` to switch the active workspace interactively, or pass a workspace ID directly: `hotdata workspaces set <workspace_id>`. The active workspace is shown with a `*` marker in `hotdata workspaces list`. **Omit `--workspace-id` unless you need to target a specific workspace.**

## Available Commands

Expand Down Expand Up @@ -111,7 +116,7 @@ hotdata tables list [--workspace-id <workspace_id>] [--connection-id <connection

### Datasets

Datasets are managed files uploaded to HotData and queryable as tables.
Datasets are managed files uploaded to Hotdata and queryable as tables.

#### List datasets
```
Expand Down Expand Up @@ -173,15 +178,10 @@ hotdata results <result_id> [--workspace-id <workspace_id>] [--format table|json

### Auth
```
hotdata auth login # Browser-based login
hotdata auth # Browser-based login
hotdata auth status # Check current auth status
```

### Init
```
hotdata init # Create ~/.hotdata/config.yml
```

## Workflow: Running a Query

1. List connections:
Expand Down
12 changes: 10 additions & 2 deletions src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ use sha2::{Digest, Sha256};
use std::collections::HashMap;
use std::io::stdout;

pub fn logout(profile: &str) {
if let Err(e) = config::remove_api_key(profile) {
eprintln!("error: {e}");
std::process::exit(1);
}
println!("{}", "Logged out.".green());
}

pub fn status(profile: &str) {
let profile_config = match config::load(profile) {
Ok(c) => c,
Expand Down Expand Up @@ -133,7 +141,7 @@ pub fn login() {
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>HotData — Login Successful</title>
<title>Hotdata — Login Successful</title>
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body {
Expand Down Expand Up @@ -177,7 +185,7 @@ pub fn login() {
</svg>
</div>
<h1>Login successful</h1>
<p>You're now authenticated with HotData.<br/>You can close this tab and return to the terminal.</p>
<p>You're now authenticated with Hotdata.<br/>You can close this tab and return to the terminal.</p>
</div>
</body>
</html>"#;
Expand Down
Loading
Loading