Skip to content

Latest commit

 

History

History

README.md

Kalam CLI

Interactive command-line client for KalamDB - a real-time database with WebSocket subscriptions.

Features

  • 🎯 Interactive SQL Execution - Execute queries with instant results
  • 📊 Multiple Output Formats - Table, JSON, and CSV output modes
  • 🔄 Live Query Subscriptions - Real-time data updates via WebSocket
  • 🎨 Syntax Highlighting - Beautiful colored SQL syntax
  • 📝 Command History - Persistent history with arrow key navigation and interactive menu
  • Auto-completion - TAB completion for SQL keywords, tables, and columns
  • 🔐 Authentication - JWT tokens, user/password login, and stored credentials
  • 📁 Batch Execution - Run SQL scripts from files
  • 🎭 Progress Indicators - Visual feedback for long-running queries

Installation

npm

npm install -g @kalamdb/cli

curl

curl -fsSL https://kalamdb.org/install.sh | sh

From Source

cd cli
cargo build --release

The binary will be available at target/release/kalam.

Using Environment Variables

# Set custom server URL and root password
export KALAMDB_SERVER_URL="http://127.0.0.1:3000"
export KALAMDB_ROOT_PASSWORD="your-password"

# Run all tests
cd cli
cargo test

# Run smoke tests
cargo test --test smoke -- --nocapture

# Or inline for a single run
KALAMDB_SERVER_URL="http://localhost:3000" \
KALAMDB_ROOT_PASSWORD="kalamdb123" \
cargo test --test smoke -- --nocapture

Environment Variables:

  • KALAMDB_SERVER_URL - Server URL (default: http://127.0.0.1:2900)
  • KALAMDB_ROOT_PASSWORD - Root password (default: kalamdb123 for local dev servers)

Cluster Test Shortcuts

# Run only the dedicated cluster integration target
cd cli
./run-cluster-tests.sh

# Run the follower/replication-focused cluster bundle
./run-cluster-tests.sh --followers --nocapture

# Run a single cluster test function
./run-cluster-tests.sh --test cluster_test_ws_follower_receives_leader_changes --nocapture

run-cluster-tests.sh delegates to run-tests.sh, pins the test target to cluster, and keeps the same environment loading and cluster autodetection behavior.

Quick Start

Connect to Server

# Connect to default localhost:3000
kalam

# Connect to specific host
kalam --host myserver.com

# Connect with authentication
kalam --token YOUR_JWT_TOKEN

Execute SQL

-- Create namespace
CREATE NAMESPACE app;

-- Create table
CREATE TABLE app.users (
    id BIGINT PRIMARY KEY DEFAULT SNOWFLAKE_ID(),
    username TEXT NOT NULL,
    email TEXT,
    created_at TIMESTAMP DEFAULT NOW()
) WITH (TYPE = 'USER');

-- Insert data
INSERT INTO app.users (username, email) 
VALUES ('alice', 'alice@example.com');

-- Query data
SELECT * FROM app.users;

Live Subscriptions

-- Subscribe to changes
SUBSCRIBE TO app.messages WHERE user_id = 'user123';

-- Or use the interactive CLI aliases
\subscribe SELECT * FROM app.messages WHERE user_id = 'user123';
\live SELECT * FROM app.messages WHERE user_id = 'user123';

-- Stop subscription (Ctrl+C)

Usage

Command-Line Options

kalam [OPTIONS] [COMMAND]

COMMANDS:
    update                         Update this kalam binary from release assets
    version                        Print version information
    doctor                         Run local, server, and authentication diagnostics
    login                          Login and save credentials for an instance
    logout                         Delete saved credentials for an instance
    whoami                         Show the authenticated user
    token create --name <NAME>     Create a service account and print tokens

CONNECTION:
    -u, --url <URL>                 Server URL (e.g., http://localhost:3000)
    -H, --host <HOST>               Host address (alternative to URL)
    -p, --port <PORT>               Port number (default: 3000)

AUTHENTICATION:
    --token <TOKEN>                 JWT authentication token
    --user <USER>                   User/password login identifier
    --password [PASSWORD]           User/password login secret (prompts if flag is present without value)
    --instance <INSTANCE>           Credential instance name (default: local)
    --save-credentials              Save credentials after successful login

EXECUTION:
    -f, --file <FILE>               Execute SQL from file and exit
    -c, --command <SQL>             Execute SQL command and exit
    --subscribe <SQL>               Subscribe to a table or live query
    --list-subscriptions            List active subscriptions (non-interactive)

OUTPUT:
    --format <FORMAT>               Output format: table|json|csv (default: table)
    --json                          Shorthand for --format=json
    --csv                           Shorthand for --format=csv
    --no-color                      Disable colored output
    --no-spinner                    Disable spinners/animations
    --loading-threshold-ms <MS>     Loading indicator threshold (0 to always show)

TIMEOUTS:
    --timeout <SECONDS>             HTTP request timeout (default: 30)
    --connection-timeout <SECONDS>  Connection timeout (default: 10)
    --receive-timeout <SECONDS>     Receive timeout (default: 30)
    --auth-timeout <SECONDS>        WebSocket auth timeout (default: 5)
    --subscription-timeout <SECONDS>Subscription timeout (0 = no timeout, default: 0)
    --initial-data-timeout <SECONDS>Initial data timeout (default: 30)
    --fast-timeouts                 Fast timeout preset (local dev)
    --relaxed-timeouts              Relaxed timeout preset (high latency)

CONFIG:
    --config <PATH>                 Configuration file path (default: ~/.kalam/config.toml)
    -v, --verbose                   Enable verbose logging

CREDENTIALS:
    --show-credentials              Show stored credentials for instance
    --update-credentials            Login and update stored credentials
    --delete-credentials            Delete stored credentials
    --list-instances                List all stored credential instances

INFO:
    --help                          Print help information
    --version                       Print version information

Non-Interactive Examples

# Run a single SQL command and exit
kalam --command "SELECT * FROM system.tables LIMIT 5"

# Run SQL from a file and exit
kalam --file setup.sql

# Subscribe to a live query (non-interactive)
kalam --subscribe "SUBSCRIBE TO app.messages WHERE user_id = 'alice'"

# Manage stored credentials
kalam login --instance local --user root --password ""
kalam whoami --instance local
kalam logout --instance local
kalam --show-credentials --instance local
kalam --list-instances

# Create a CI service token
kalam token create --name ci-prod

# Check the local install and configured server
kalam doctor

# Update the installed binary
kalam update

When kalam login is run from an interactive terminal, a successful local or OIDC login now drops straight into the normal SQL shell. Piped or otherwise non-interactive invocations keep the one-shot behavior and exit after saving credentials so automation does not hang.

Interactive Commands

Special commands starting with backslash (\):

Command Description
\help / \? Show available commands
\quit / \q Exit the CLI
\info / \session Show session info
\sessions Show active pg-extension gRPC sessions
\format <table|json|csv> Set output format
\dt / \tables List tables
\d <table> / \describe <table> Describe a table (<table> or <namespace.table>)
\as <user_id> <SQL> Wrap one statement as EXECUTE AS '<user_id>'
\stats / \metrics Show system stats
\health Check server health
\flush Execute STORAGE FLUSH ALL
\refresh-tables / \refresh Refresh autocomplete cache
\live <SQL> / \subscribe <SQL> Start live query (\subscribe is an alias)
\show-credentials / \credentials Show stored credentials
\update-credentials <u> <p> Update stored credentials
\delete-credentials Delete stored credentials
\cluster ... Cluster inspection and admin commands. See docs/getting-started/cli.md.

Using the CLI (Interactive Mode)

Once the CLI starts, type SQL directly and press Enter (or end with ;) to run it. Use backslash commands (like \help) for CLI-specific actions.

Tips:

  • Use Tab for auto-completion of SQL keywords, namespaces, tables, and columns.
  • Use ↑/↓ to navigate command history.
  • Use \format json or \format csv to switch output formats.
  • Use \live <SQL> for live updates.
  • Run BACKUP DATABASE TO '/tmp/kalamdb-backup.tar.gz'; as SQL for server-side backups.
  • Run EXPORT USER DATA; followed by SHOW EXPORT; to fetch your export download URL.

Output Formats

Table Format (Default)

┌─────────┬──────────┬─────────────────────┬────────────────────────┐
│ id      │ username │ email               │ created_at             │
├─────────┼──────────┼─────────────────────┼────────────────────────┤
│ 1234567 │ alice    │ alice@example.com   │ 2025-10-24 10:30:00    │
│ 1234568 │ bob      │ bob@example.com     │ 2025-10-24 10:31:00    │
└─────────┴──────────┴─────────────────────┴────────────────────────┘
(2 rows)
Took: 5.234 ms

JSON Format

kalam --json
{
  "status": "success",
  "results": [
    {
      "id": 1234567,
      "username": "alice",
      "email": "alice@example.com",
      "created_at": "2025-10-24T10:30:00Z"
    }
  ],
  "took_ms": 5.234
}

CSV Format

kalam --csv
id,username,email,created_at
1234567,alice,alice@example.com,2025-10-24T10:30:00Z
1234568,bob,bob@example.com,2025-10-24T10:31:00Z

Batch Execution

Execute SQL from a file:

kalam --file setup.sql

Example setup.sql:

CREATE NAMESPACE prod;
CREATE TABLE prod.events (
    id BIGINT PRIMARY KEY DEFAULT SNOWFLAKE_ID(),
    event_type TEXT NOT NULL,
    data TEXT,
    created_at TIMESTAMP DEFAULT NOW()
) WITH (TYPE = 'USER');
INSERT INTO prod.events (event_type, data) VALUES ('login', '{"user":"alice"}');

Configuration File

The CLI automatically creates and reads configuration from ~/.kalam/config.toml on first run:

[server]
timeout = 30
max_retries = 0
http_version = "http2"         # http1, http2, auto

[connection]
auto_reconnect = true
reconnect_delay_ms = 100
max_reconnect_delay_ms = 30000
max_reconnect_attempts = 10

[ui]
format = "table"             # table, json, csv
color = true
history_size = 1000
timestamp_format = "iso8601" # iso8601, iso8601-date, iso8601-datetime, unix-ms, unix-sec, relative, rfc2822, rfc3339

The configuration file is created with default values when you first run the CLI. You can edit it to customize the behavior or override settings with command-line flags.

Authentication

Localhost Bypass

When connecting from localhost without credentials, the CLI automatically uses a default user:

kalam  # Uses default user on localhost

JWT Token

kalam --token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

User/Password Login + Stored Credentials

# Login and store credentials
kalam login --instance local --user root --password ""

# Login to a named production instance
kalam login --instance prod --url https://db.example.com --user root --password

# Show current identity
kalam whoami --instance prod

# Remove saved credentials
kalam logout --instance prod

# Legacy credential flags still work for scripts that already use them
kalam --update-credentials --instance local --user root --password ""

Service Tokens

kalam token create --name ci-prod creates a service account with a generated password, logs in once, and prints an access/refresh token pair. The generated password is not stored or shown. Use --json for automation and --save if you also want the token stored locally as a credential instance named after the token.

Advanced Features

Syntax Highlighting

The CLI provides beautiful SQL syntax highlighting with:

  • Blue bold keywords (SELECT, INSERT, CREATE, etc.)
  • Magenta data types (INT, TEXT, TIMESTAMP, etc.)
  • Green string literals
  • Yellow numeric literals

Auto-completion

Press TAB to auto-complete:

  • SQL keywords (SELECT, INSERT, UPDATE, etc.)
  • Table names (loaded from system.tables)
  • Column names (context-aware after table name)
  • SQL types (INT, TEXT, TIMESTAMP, etc.)
  • CLI commands (\help, \quit, etc.)

Refresh table/column cache:

\refresh-tables

Command History

  • arrow (on empty line): Opens interactive history dropdown menu
    • Oldest commands at top, newest at bottom
    • Selection starts at bottom (newest command)
    • to navigate to older commands (up), to newer commands (down)
    • Enter to select, Esc to cancel
    • Type to filter history entries in real-time
    • Selected command appears in your prompt ready to edit
    • Multi-line commands show first 2 lines for easy identification
  • \history or \h: Alternative way to open the history menu
  • History stored in ~/.kalam/history
  • Persistent across sessions
  • \history, \h, \quit, and \q commands are not saved to history

Progress Indicators

For queries taking longer than 200ms, the CLI shows a spinner with elapsed time:

⠋ Executing query... 1.2s

Live Query Notifications

When subscribed, the CLI displays real-time notifications:

[2025-10-24 10:30:15] INSERT: {"id": 1234567, "content": "New message"}
[2025-10-24 10:30:20] UPDATE: {"id": 1234567, "content": "Updated message"}
[2025-10-24 10:30:25] DELETE: {"id": 1234567}

Troubleshooting

Connection Refused

Error: Failed to connect to localhost:3000

Solution: Ensure the KalamDB server is running:

cd backend
cargo run --bin kalamdb-server

Authentication Failed

Error: Authentication failed (401 Unauthorized)

Solution: Provide valid credentials:

kalam --token YOUR_JWT_TOKEN

Table Not Found

Error: table 'app.users' not found

Solution: Create the namespace and table first:

CREATE NAMESPACE app;
CREATE TABLE app.users (...) WITH (TYPE = 'USER');

Examples

Create and Query Table

-- Create namespace
CREATE NAMESPACE myapp;

-- Create table with auto-incrementing ID
CREATE TABLE myapp.users (
    id BIGINT PRIMARY KEY DEFAULT SNOWFLAKE_ID(),
    username TEXT NOT NULL,
    email TEXT,
    created_at TIMESTAMP DEFAULT NOW()
) WITH (TYPE = 'USER');

-- Insert data
INSERT INTO myapp.users (username, email) VALUES 
    ('alice', 'alice@example.com'),
    ('bob', 'bob@example.com');

-- Query all users
SELECT * FROM myapp.users;

-- Query with filter
SELECT username, email FROM myapp.users WHERE username = 'alice';

Live Subscription

-- Create messages table
CREATE TABLE chat.messages (
    id BIGINT PRIMARY KEY DEFAULT SNOWFLAKE_ID(),
    user_id TEXT NOT NULL,
    content TEXT NOT NULL,
    created_at TIMESTAMP DEFAULT NOW()
) WITH (TYPE = 'USER');

-- Subscribe to new messages
SUBSCRIBE TO chat.messages WHERE user_id = 'alice';

-- In another terminal, insert messages:
-- INSERT INTO chat.messages (user_id, content) VALUES ('alice', 'Hello!');
-- The first terminal will show real-time notifications

Batch Processing

Create import.sql:

CREATE NAMESPACE analytics;
CREATE TABLE analytics.events (
    id BIGINT PRIMARY KEY DEFAULT SNOWFLAKE_ID(),
    event_type TEXT NOT NULL,
    user_id TEXT,
    data TEXT,
    created_at TIMESTAMP DEFAULT NOW()
) WITH (TYPE = 'USER');

INSERT INTO analytics.events (event_type, user_id, data) VALUES
    ('page_view', 'user1', '{"page":"/home"}'),
    ('click', 'user1', '{"button":"signup"}'),
    ('conversion', 'user1', '{"amount":99.99}');

Execute:

kalam --file import.sql

Development

Running Tests

cd cli
cargo test

Building from Source

cd cli
cargo build --release

Project Workflow

Project-oriented workflow commands such as kalam init, kalam dev, kalam link, kalam schema gen, kalam migration create, kalam status, and kalam deploy are documented in DEV.md.

When kalam dev starts a local server, the generated kalam/server/server.toml uses root / kalamdb123 by default. Scaffolded .env files include the same password for local development.

Access the running server at http://localhost:2900 (UI at http://localhost:2900/ui) with root / kalamdb123, or run kalam --url http://127.0.0.1:2900 --user root --password kalamdb123 in another terminal.

Use kalam db reset to clear local project state (kalam/server/, schema baseline) and drop the linked namespace when appropriate. Use --yes when reusing a non-project server or in non-interactive shells. Run kalam dev afterward for a fresh database.

Use that guide for:

  • interactive and non-interactive project initialization
  • local vs remote server mode
  • kalam.toml structure and environment resolution
  • the day-to-day development loop
  • production-like environment linking and deploy guardrails

License

Licensed under the Apache License, Version 2.0 (Apache-2.0). See ../LICENSE.txt and ../NOTICE.

Contributing

Contributions welcome! Please see the main KalamDB repository for contribution guidelines.

Related Documentation