CLI
The CLI (@usebetterdev/console-cli) provides commands for setting up and managing UseBetter Console. Use it via npx — no installation required.
npx @usebetterdev/console-cli <command>Commands
Section titled “Commands”init — generate token and config
Section titled “init — generate token and config”Generates a connection token pair and prints the environment variables needed to run Console.
npx @usebetterdev/console-cli init| Flag | Description |
|---|---|
--email <email> | Admin email address (skips the prompt) |
-n, --non-interactive | Disable all prompts; requires --email |
Output:
Connection token (save this — it won't be shown again):a1b2c3d4...
BETTER_CONSOLE_TOKEN_HASH=sha256:e5f6a7b8...The token hash is the SHA-256 digest stored in your environment. It is used server-side to sign and verify session JWTs. The raw connection token is only shown once during init — only the hash is needed at runtime.
migrate — generate table SQL
Section titled “migrate — generate table SQL”Generates the SQL to create the better_console_sessions and better_console_magic_links tables. Only needed if you use the magic link auth flow — auto-approve is stateless and needs no tables.
npx @usebetterdev/console-cli migrate --dry-run # print to stdoutnpx @usebetterdev/console-cli migrate # write to ./console-migrations/<timestamp>_better_console_tables.sqlnpx @usebetterdev/console-cli migrate -o path/to/file.sql # write to specific filenpx @usebetterdev/console-cli migrate --force # overwrite if file exists| Flag | Description |
|---|---|
--dry-run | Print SQL to stdout instead of writing a file |
-o, --output <path> | File (.sql) or directory path |
--force | Overwrite an existing file without error |
The generated SQL is idempotent (CREATE TABLE IF NOT EXISTS, CREATE INDEX IF NOT EXISTS).
Tables created:
| Table | Purpose |
|---|---|
better_console_sessions | Stores claimed magic-link sessions (email, token hash, permissions, expiry) |
better_console_magic_links | Tracks the init → verify → claim flow (code hash, session correlation ID, failed attempts) |
token generate — new token pair
Section titled “token generate — new token pair”Generates a fresh connection token pair without the full init flow. Useful for scripting or CI.
npx @usebetterdev/console-cli token generatePrints the raw token and the BETTER_CONSOLE_TOKEN_HASH=sha256:... line.
token rotate — rotate and invalidate
Section titled “token rotate — rotate and invalidate”Same as generate but prints a warning that rotating the token invalidates all existing console sessions.
npx @usebetterdev/console-cli token rotateAfter rotating, update BETTER_CONSOLE_TOKEN_HASH in your environment and restart your server.
check — verify setup
Section titled “check — verify setup”Validates that the database tables, indexes, and environment variables are set up correctly.
npx @usebetterdev/console-cli check --database-url postgres://...# or with DATABASE_URL in the environment:npx @usebetterdev/console-cli check| Flag | Description |
|---|---|
--database-url <url> | Postgres connection string (default: DATABASE_URL env) |
Checks performed:
| Category | What it verifies |
|---|---|
| Tables | better_console_sessions and better_console_magic_links exist with all required columns |
| Indexes | token_hash, session_id, and expires_at indexes exist |
| Env vars | BETTER_CONSOLE_TOKEN_HASH is set and has valid format (sha256:<64 hex> or bare <64 hex>) |
| Env vars | BETTER_CONSOLE_ALLOWED_EMAILS is set (warning only — only needed for magic link mode) |
Exits with code 1 if any check fails.
Programmatic API
Section titled “Programmatic API”The CLI modules are also importable for use in scripts or custom tooling:
import { generateTokenPair } from "@usebetterdev/console-cli/token";import { generateConsoleMigrationSql } from "@usebetterdev/console-cli/migrate";import { runConsoleCheck } from "@usebetterdev/console-cli/check";import { runInit } from "@usebetterdev/console-cli/init";
// Generate a token pairconst { token, hash } = await generateTokenPair();
// Get the migration SQL as a stringconst sql = generateConsoleMigrationSql();
// Run checks programmaticallyconst { passed, results, warnings } = await runConsoleCheck(databaseUrl);
// Run init (non-interactive)Next steps
Section titled “Next steps”- Configuration — full config reference, CORS, environment variables
- Troubleshooting — common issues and fixes
- Architecture — how the routing and auth internals work