# CLI Reference

The Quickback CLI is the fastest way to create, compile, and manage your backend projects.

## Installation

```bash
# One-shot via npx — recommended for first run
npx @quickback-dev/cli start

# Or install globally for repeat use
npm install -g @quickback-dev/cli
```

## Commands

### Start a Project (interactive)

```bash
quickback start
```

Interactive onboarding designed for new users. No flags required.

- Prompts for a template (`cloudflare`, `todos`, `blog`, `empty`)
- Prompts for a project name (defaults to the current directory's name if empty)
- Auto-detects whether to scaffold in-place or create a `./<name>/` subdirectory
- Defers login until just before the compile step — cancel at the auth prompt and the scaffold stays on disk, ready for `quickback compile` later

**Example:**
```bash
mkdir my-app && cd my-app
npx @quickback-dev/cli start
```

### Create a Project (scriptable)

```bash
quickback create <template> <name>
```

**Templates:**
- `cloudflare` — Cloudflare Workers + D1 + Better Auth, bare scaffold
- `todos` — Working todos example with masking + actions + a named view
- `blog` — Single-tenant blog, PUBLIC reads, admin writes
- `empty` — Cloudflare scaffold, no example features
- `saas` — Full B2B SaaS: orgs, R2 file storage, webhooks, split databases, realtime

**Example:**
```bash
quickback create todos my-app
```

This scaffolds a complete project with:
- `quickback.config.ts` — Project configuration
- `quickback/features/` — Your table definitions
- Example feature with full security configuration (for `todos` / `blog` / `saas`)

See the [Templates](/start/templates) page for a deeper guide on choosing between them.

### Compile Definitions

```bash
quickback compile
```

Use `quickback compile --verbose` when a remote compile fails and you need the
underlying command, exit code, stderr/stdout tail, and compiler-suggested fixes.

Reads your definitions and generates:
- Database migrations (Drizzle)
- API route handlers (Hono)
- TypeScript client SDK
- OpenAPI specification

Run this after making changes to your definitions.

#### Configuration-aware completion steps

After a successful compile, the CLI derives its next steps from the configured
database connection mode. Neon HTTP projects receive the direct
`DATABASE_URL`, `.dev.vars`, migration, and deploy workflow. Hyperdrive
projects instead receive migration-only `DATABASE_MIGRATION_URL` guidance and
local development instructions for the configured Hyperdrive
`localConnectionString`; the CLI never recommends `DATABASE_URL` as a Worker
secret for that mode.

When `providers.database.environments` defines isolated targets, the footer
lists the configured Neon branches, each target's required Worker secrets, and
explicit `wrangler ... --env <target>` deploy commands. It does not suggest a
bare deploy or the unnamed `.env.neon` / `.dev.vars` workflow for named
Hyperdrive environments.

#### Generated `src/` is hermetic

Every file under `src/` carries a `Generated by quickback.dev` header and is owned by the compiler. Before each compile writes its output, the CLI:

1. Snapshots the existing `src/` tree to `quickback/.archives/src-<ISO-timestamp>/` (a plain recursive copy — `cp -R` semantics, no compression).
2. Wipes `src/` entirely.
3. Writes the fresh manifest from the compiler.

This prevents stale output: removed features stop leaving orphan folders, deleted SPA assets with old content hashes get cleared, and `.DS_Store` files don't keep retired directories alive.

The most recent **3** archives are retained (older ones are pruned automatically). If a compile produces unexpected output, your last-known-good tree is sitting in `quickback/.archives/` ready to grep or copy back:

```bash
ls quickback/.archives/
# src-2026-04-27T16-31-02-014/
# src-2026-04-27T16-29-44-882/
# src-2026-04-27T16-12-19-301/
```

As a safety net, the wipe is **skipped** when the manifest contains zero files for the target directory — that's almost always an upstream compile bug, and we'd rather keep your last working tree than overwrite it with nothing.

### Typecheck the Authored Tree

```bash
quickback check            # one-shot; CI-friendly exit codes
quickback check --watch    # re-check on change (tsc --watch)
```

Runs `tsc` over `quickback/tsconfig.json` — the config the compiler emits on
every compile, which typechecks the tree you actually edit (actions, lib,
table files) against the generated `.quickback/` typed helpers. No compile,
no server: this is your editor's view of the source, on demand.

Exit codes: `0` clean · `1` type errors · `2` setup missing. A fresh clone
(or a project that has never compiled) exits `2` with a pointer at
`quickback compile`, which generates the tsconfig and helpers the check
resolves against. Re-run `quickback compile` after schema changes so the
helpers track your tables.

### Synchronize Managed Columns

```bash
quickback schema check   # report missing managed-column declarations; read-only
quickback schema sync    # write the safe additive declarations into authored files
quickback schema sync --dry-run   # show the sync diff without writing
```

Checks every authored table under `quickback/features/` for the managed
columns the compiler expects (audit timestamps, soft-delete markers) and —
on `sync` — writes the missing declarations into your source. `check` never
writes; anything that needs a human decision is reported as a diagnostic and
blocks the write.

The SQL dialect for written declarations comes from your configured database
provider — the same provider→dialect table the compiler uses. Postgres
providers (`supabase`, `neon`, `vercel-postgres`, `postgres`, `postgresql`)
get Postgres declarations; SQLite providers (`cloudflare-d1`,
`better-sqlite3`, `bun-sqlite`, `libsql`, `turso`) get SQLite. MySQL
providers are refused with an error rather than written in the wrong
dialect; no provider (or an unrecognized one) defaults to SQLite.

### Authored-Source Codemods

```bash
quickback migrate visible-columns [--dry-run]   # declare managed audit columns
quickback migrate helper-imports  [--dry-run]   # single typed helper import
```

`helper-imports` rewrites action files from the legacy pair —

```ts
import { defineAction } from "../.quickback/define-action";
import { applications } from "../applications";   // resolves to the authored file
```

— to the single typed import the helpers are designed for:

```ts
import { defineAction, applications } from "../.quickback/define-action";
```

Only provably-safe merges are made: the table import must resolve to the
helper's own bound table under a name the helper exports. Sibling-table and
cross-feature imports are left untouched, and unusual shapes (aliases,
multi-line imports, `import type`) are reported for manual attention instead
of guessed at.

### View Documentation

```bash
quickback docs              # List available topics
quickback docs <topic>      # Show documentation for a topic
```

**Available topics:**
- `firewall` - Data isolation layer
- `access` - Role-based permissions
- `guards` - Field protection
- `masking` - PII redaction
- `actions` - Custom business logic
- `api` - CRUD endpoints reference
- `config` - Configuration reference
- `features` - Schema definitions

Documentation is bundled with the CLI and works offline.

### Manage Claude Code Skill

```bash
quickback claude install     # Interactive install
quickback claude install --global   # Install to ~/.claude/skills/
quickback claude install --local    # Install to ./.claude/
quickback claude update      # Update to latest version
quickback claude remove      # Remove installed skill
quickback claude status      # Check installation status
```

The Quickback skill for Claude Code provides AI assistance for:
- Creating resource definitions with proper security layers
- Configuring Firewall, Access, Guards, and Masking
- Debugging configuration issues
- Understanding security patterns

## Authentication

### Login

```bash
quickback login
```

Uses the [OAuth 2.0 Device Authorization Grant](https://datatracker.ietf.org/doc/html/rfc8628) (RFC 8628) to authenticate securely without exposing tokens in URLs.

**How it works:**

1. The CLI requests a one-time device code from the Quickback API.
2. A code is displayed in your terminal (e.g., `AUL8-H93S`).
3. Your browser opens to the Quickback account page where you approve the code.
4. The CLI detects approval and exchanges it for a session token.
5. If you belong to one organization, it's auto-selected. If you have multiple, you choose one.
6. Credentials are stored locally.

```
$ quickback login

🔐 Quickback Login

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Your code: AUL8-H93S

  Visit: https://account.quickback.dev/cli/authorize

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✓ Login successful!
Welcome, Paul Stenhouse!

Using organization: Acme
✓ Active organization: Acme
```

This flow works in headless environments (SSH, containers, WSL) since it doesn't require a localhost callback.

### Logout

```bash
quickback logout
```

Clears stored credentials from `~/.quickback/credentials.json`.

### Check Auth Status

```bash
quickback whoami
```

Shows the currently authenticated user, organization, and token expiration.

### Credential Storage

Credentials are stored at `~/.quickback/credentials.json`:

```json
{
  "token": "...",
  "user": {
    "id": "...",
    "email": "paul@example.com",
    "name": "Paul Stenhouse"
  },
  "expiresAt": "2026-02-16T01:42:21.519Z",
  "organization": {
    "id": "...",
    "name": "Acme",
    "slug": "acme"
  }
}
```

Sessions expire after 7 days. Run `quickback login` again to re-authenticate.

### Organizations

After login, the CLI auto-selects your organization:
- **One organization** - automatically set as active.
- **Multiple organizations** - you're prompted to choose one.

The active organization is stored in your credentials and sent with compile requests, so the compiler knows which org context to use.

## Quick Start

```bash
# 1. Start a new project (interactive — picks template, scaffolds,
#    prompts for login only when needed)
mkdir my-app && cd my-app
npx @quickback-dev/cli start

# 2. Run locally
npm run dev
```

Or the scriptable form:

```bash
# 1. Create the project (scaffolds + compiles + installs)
quickback create todos my-app   # prompts for login on first compile
cd my-app

# 2. Run
npm run dev

# 3. Recompile after editing definitions
quickback compile
```

## Options

| Flag | Description |
|------|-------------|
| `-v, --version` | Show version number |
| `-h, --help` | Show help message |

## Environment Variables

| Variable | Description |
|----------|-------------|
| `QUICKBACK_API_KEY` | API key for authentication (alternative to `quickback login`) |
| `QUICKBACK_API_URL` | Override compiler API URL |
| `QUICKBACK_STRICT_PARSE` | Set to `1` to fail instead of falling back to regex feature parsing |

### TypeScript and the parser

The CLI parses your feature files with the TypeScript compiler API, and falls back to a **regex** table detector when it can't. That fallback feeds schema sync, firewall analysis, masking detection, and migration generation — a weaker parser for the input that drives your security pillars.

`typescript` is an optional peer dependency, supported at **`>=5.0.0 <7`**. TypeScript 7 (the native port) resolves its main entry to a module exporting only `version` — parsing moved to the explicitly-unstable `typescript/unstable/*` subpaths — so it cannot drive the AST parser, and the CLI says so by name rather than degrading quietly.

Set `QUICKBACK_STRICT_PARSE=1` in CI so a regex-parsed build fails the pipeline instead of shipping:

```bash
QUICKBACK_STRICT_PARSE=1 quickback compile
```

Having no `typescript` installed at all is a supported setup and stays silent — the fallback is the intended path there.

### API Key Authentication

Use an API key instead of interactive login. Useful for CI/CD pipelines and automated workflows:

```bash
# Pass API key for a single command
QUICKBACK_API_KEY=your_api_key quickback compile

# Or export for the session
export QUICKBACK_API_KEY=your_api_key
quickback compile
```

The API key takes precedence over stored credentials from `quickback login`.

You can create API keys from your [Quickback account](https://account.quickback.dev/api-keys). Each key is scoped to your organization.

### Custom Compiler URL

Point the CLI to a different compiler (local or custom):

```bash
# Use a local compiler
QUICKBACK_API_URL=http://localhost:3000 quickback compile

# Or export for the session
export QUICKBACK_API_URL=http://localhost:3000
quickback compile
```

See [Local Compiler](/tooling/cloud-compiler/local-compiler) for running the compiler locally with Docker.

## Troubleshooting

### "Command not found: quickback"

Make sure the CLI is installed globally:
```bash
npm install -g @quickback-dev/cli
```

Or use npx (no global install needed):
```bash
npx @quickback-dev/cli start
```

### Compile errors

1. Check your `quickback.config.ts` exists and is valid
2. Ensure all tables in `quickback/features/` have valid exports
3. Run `quickback compile` with `--verbose` for detailed output
4. For rename-related Drizzle failures in CI/headless runs, configure `compiler.migrations.renames` in `quickback.config.ts`

### Authentication issues

Clear credentials and re-authenticate:
```bash
quickback logout
quickback login
```

### "Could not load organizations"

This can happen if your session token expired or if the API is temporarily unavailable. Re-login:
```bash
quickback logout
quickback login
```
