Skip to content
Closed
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
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
---
title: Troubleshooting
title: CLI troubleshooting
description: Fix common CipherStash CLI errors covering config files, database permissions, EQL installs, Supabase resets, and Drizzle migration issues.
type: guide
components: [cli, eql]
---

## Common errors

| Error | Cause | Fix |
|---|---|---|
| `Could not find stash.config.ts` | No config file in cwd or parent dirs | Run `npx stash init` (which runs `db install` automatically), or run `npx stash db install` directly, or create `stash.config.ts` manually |
| `Could not find stash.config.ts` | No config file in cwd or parent dirs | Run `npx stash init` (which runs `eql install` automatically), or run `npx stash eql install` directly, or create `stash.config.ts` manually |
| `databaseUrl is required` | Config missing `databaseUrl` | Add `databaseUrl` to config and check `.env` is loaded |
| `must be superuser to create an operator family` | Standard SQL requires superuser | The CLI falls back to OPE mode automatically on managed databases. Pass `--exclude-operator-family` if you see this on self-hosted Postgres. |
| `Insufficient database permissions` | Role lacks `CREATE` privileges | Connect as superuser or grant permissions |
| `EQL is already installed` | `eql_v2` schema exists | Use `--force` to reinstall |
| `Encrypt client file not found` | `push`/`validate` can't find the file at `config.client` | Set `client` in `stash.config.ts` to the correct path |
| `drizzle-kit generate failed` | drizzle-kit not installed or wrong output dir | Install `drizzle-kit` and set `--out` to match your Drizzle config |
| EQL missing after `supabase db reset` | EQL was installed via direct push, not as a migration | Re-run `db install --supabase --migration` to add EQL to `supabase/migrations/`. See [below](#supabase-db-reset). |
| EQL missing after `supabase db reset` | EQL was installed via direct push, not as a migration | Re-run `eql install --supabase --migration` to add EQL to `supabase/migrations/`. See [below](#supabase-db-reset). |

## Permission issues

Expand All @@ -23,7 +25,7 @@ The `install` command checks database permissions before running. On managed dat
If you still see permission errors:

1. Run `npx stash db test-connection` to verify your database URL is correct.
2. Run `npx stash db status` to check the current EQL state.
2. Run `npx stash eql status` to check the current EQL state.
3. Ensure the connected role has `CREATE` privileges on the database and `public` schema.
4. For the `pgcrypto` extension, the role needs `SUPERUSER` or extension owner privileges.

Expand Down Expand Up @@ -54,10 +56,10 @@ When adding `encryptedType` to a column that already has data, the CLI rewrites

### Fix for new installs

Re-run `db install` and choose the migration-file path:
Re-run `eql install` and choose the migration-file path:

```bash
npx stash db install --supabase --migration
npx stash eql install --supabase --migration
```

The CLI writes EQL SQL to `supabase/migrations/00000000000000_cipherstash_eql.sql`. The all-zero timestamp prefix ensures it runs before any user migrations that reference `eql_v2_encrypted`. After the file is created, `supabase db reset` will reinstall EQL automatically on every reset.
Expand All @@ -67,7 +69,7 @@ The CLI writes EQL SQL to `supabase/migrations/00000000000000_cipherstash_eql.sq
If you already ran a direct-push install and your live database is working, your existing install is not broken. To get a migration file going forward without disrupting the live database, run:

```bash
npx stash db install --supabase --migration --force
npx stash eql install --supabase --migration --force
```

The EQL SQL is idempotent. The `--force` flag regenerates the install even though EQL is already present. Your live install is unaffected. After this, `supabase db reset` reinstalls EQL from the migration file.
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
---
title: Programmatic API
description: Import the stash package programmatically to install EQL, load and validate stash.config.ts, and build custom CipherStash tooling or CI scripts.
type: reference
components: [cli]
---

Import `stash` directly for custom tooling or CI scripts.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
title: Execute an encryption plan
description: Run stash impl to execute your CipherStash encryption plan by handing off to a coding agent such as Claude Code, Codex, or AGENTS.md.
type: reference
components: [cli]
---

# Execute an encryption plan

`stash impl` is the third step in the setup lifecycle. It reads your plan, confirms the scope, and hands off to a coding agent to make the changes. Run `stash plan` first to produce `.cipherstash/plan.md`.

```bash
Expand Down Expand Up @@ -121,15 +121,15 @@ No plan at `.cipherstash/plan.md`. Run `stash plan` first, or pass --continue-wi
When the agent handoff completes, `stash impl` prints:

```
Implementation handoff complete. Run `stash db status` to verify state.
Implementation handoff complete. Run `stash eql status` to verify state.
```

Run `stash db status` to check EQL installation and `stash encrypt status` for per-column migration state.
Run `stash eql status` to check EQL installation and `stash encrypt status` for per-column migration state.

## Next steps

<Cards>
<Card title="Check project status" href="/stack/cipherstash/cli/status" description="Use stash status to see where you are in the lifecycle." />
<Card title="Push and status" href="/stack/cipherstash/cli/push" description="Push your encryption schema and check EQL installation state." />
<Card title="Draft an encryption plan" href="/stack/cipherstash/cli/plan" description="Use stash plan to draft a reviewable plan before implementation." />
<Card title="Check project status" href="/reference/cli/status" description="Use stash status to see where you are in the lifecycle." />
<Card title="Push and status" href="/reference/cli/push" description="Push your encryption schema and check EQL installation state." />
<Card title="Draft an encryption plan" href="/reference/cli/plan" description="Use stash plan to draft a reviewable plan before implementation." />
</Cards>
196 changes: 192 additions & 4 deletions content/docs/reference/cli/index.mdx
Original file line number Diff line number Diff line change
@@ -1,8 +1,196 @@
---
title: CLI
description: "CLI documentation — being built as part of the docs V2 overhaul."
title: CipherStash CLI
description: The stash dev-time CLI installs EQL in PostgreSQL, scaffolds an encryption client, and manages schemas with init, plan, and impl commands.
type: reference
components: [cli]
---

This section is being built as part of the docs V2 overhaul ([CIP-3307](https://linear.app/cipherstash/issue/CIP-3307)). Track progress in [IA.md](https://github.com/cipherstash/docs/blob/v2/IA.md).
`stash` is a dev-time CLI and library for managing CipherStash EQL (Encrypted Query Language) in PostgreSQL.

Until it lands, current documentation lives in the [existing docs](/stack).
`@cipherstash/stack` is the runtime encryption SDK. It stays lean with no heavy dependencies like `pg`. `stash` is a devDependency that handles database tooling: installing EQL extensions, checking permissions, validating schemas, and managing the schema lifecycle.

Think of it like Prisma CLI or Drizzle Kit. It sets up the database while the main SDK handles runtime operations.

| Package | Role | Install as |
|---|---|---|
| `@cipherstash/stack` | Runtime encryption and decryption | dependency |
| `stash` | Database setup and schema management | devDependency |

## Quick start

### Interactive (recommended)

The setup lifecycle has three explicit save-points. Each command can be run standalone; the chain prompts after `init` and `plan` are convenience for first-time users.

<Steps>
<Step>
### Run init

`stash init` authenticates you, resolves your database, scaffolds an encryption client, installs dependencies, installs EQL, and writes `.cipherstash/context.json`.

```bash
npx stash init
```

When init finishes, it asks (default-yes) whether to continue to `stash plan`.
</Step>

<Step>
### Draft an encryption plan

`stash plan` hands off to a coding agent (Claude Code or Codex), which reads your project and writes `.cipherstash/plan.md`. The plan lists the tables and columns to encrypt. Review it before proceeding.

```bash
npx stash plan
```

When plan finishes, it asks (default-yes) whether to continue to `stash impl`.
</Step>

<Step>
### Execute the plan

`stash impl` reads the plan, shows a summary panel, asks you to confirm, and dispatches to the agent to make the changes.

```bash
npx stash impl
```
</Step>
</Steps>

### Manual setup

If you prefer to configure things yourself rather than running `stash init`, you can scaffold the config file manually and run `stash eql install` directly.

<Steps>
<Step>
### Install the CLI

```bash
npm install -D stash
```
</Step>

<Step>
### Create stash.config.ts

Create `stash.config.ts` in your project root:

```typescript filename="stash.config.ts"
import { defineConfig } from 'stash'

export default defineConfig({
databaseUrl: process.env.DATABASE_URL!,
})
```
</Step>

<Step>
### Add your database URL

```bash filename=".env"
DATABASE_URL=postgresql://user:password@localhost:5432/mydb
```
</Step>

<Step>
### Install EQL

```bash
npx stash eql install
```
</Step>
</Steps>

> **Good to know**: Using Drizzle? The CLI auto-detects a `drizzle.config.*` file or `drizzle-orm`/`drizzle-kit` in `package.json` and generates a migration automatically. You can also pass `--drizzle` explicitly. Run `npx drizzle-kit migrate` after to apply it.

## Configuration

The `stash.config.ts` file is the single source of truth for the CLI. Use `defineConfig` for type safety.

```typescript filename="stash.config.ts"
import { defineConfig } from 'stash'

export default defineConfig({
databaseUrl: process.env.DATABASE_URL!,
client: './src/encryption/index.ts',
})
```

| Option | Required | Default | Description |
|---|---|---|---|
| `databaseUrl` | Yes | | PostgreSQL connection string |
| `client` | No | `./src/encryption/index.ts` | Path to your encryption client file. Used by `push` and `validate`. |

The CLI loads `.env.local`, `.env.development.local`, `.env.development`, then `.env` (first-win, Next.js precedence) before evaluating the config, so `process.env` references work without any extra setup. The config file is resolved by walking up from the current working directory, similar to how `tsconfig.json` resolution works.

## Wizard

`stash wizard` (also available as `@cipherstash/wizard`) is the CipherStash-hosted AI setup tool. It reads your codebase, asks which columns to encrypt, and wires up `@cipherstash/stack` for you.

The primary setup path is `stash init` → `stash plan` → `stash impl`, which can hand off to Claude Code, Codex, AGENTS.md (Cursor, Windsurf, Cline), or the wizard. The wizard is one handoff target among these options.

Run it directly with:

```bash
npx stash wizard
```

Or via the package runner:

```bash
npx @cipherstash/wizard # npm / Node
pnpm dlx @cipherstash/wizard # pnpm
bunx @cipherstash/wizard # bun
yarn dlx @cipherstash/wizard # yarn
```

### Prerequisites

Before running the wizard, your project should have:

- An authenticated CipherStash session (`npx stash auth login`)
- A `stash.config.ts` (run `npx stash init` or `npx stash eql install` to scaffold one)
- A reachable database via `DATABASE_URL`

### What the wizard does

1. Detects your framework (Drizzle, Supabase, Prisma, generic) and TypeScript usage.
2. Runs health checks against the CipherStash gateway and your database.
3. Prompts you to pick the tables and columns to encrypt.
4. Sends a prompt to the Claude Agent SDK, which edits your schema and call sites to use `@cipherstash/stack`'s encryption APIs. The agent runs against a CipherStash-hosted LLM gateway. No Anthropic API key is required.
5. Runs post-agent steps: package install, `eql install`, `db push`, and framework-specific migrations.
6. Scans for remaining call sites that need `encryptModel`/`decryptModel` wiring and prints a summary. These locations are not edited automatically.
7. Offers to install integration-appropriate [agent skills](/stack/reference/agent-skills) into `./.claude/skills/`.

### Wizard log

Each run writes a timestamped log to `.cipherstash/wizard-log.md` in your project root. The log records phases, decisions, and touched files.

### Backfilling existing data

When the wizard adds `encryptedType` to columns that already have data, you must backfill the existing rows with `encryptModel` before dropping the old column. The wizard prints a reminder with the recommended pattern. You are responsible for writing and running this backfill.

## Experimental commands

### env

The `env` command prints a `.env.production.local` block with your CipherStash credentials. Pass `--write` to write it to disk.

```bash
STASH_EXPERIMENTAL_ENV_CMD=1 npx stash env
STASH_EXPERIMENTAL_ENV_CMD=1 npx stash env --write
```

This command is experimental and gated behind the `STASH_EXPERIMENTAL_ENV_CMD=1` environment variable. It is not ready for production use.

## Next steps

<Cards>
<Card title="Init" href="/reference/cli/init" description="Use the interactive init command to scaffold your project and generate context.json." />
<Card title="Plan" href="/reference/cli/plan" description="Draft a reviewable encryption plan before any code changes are made." />
<Card title="Impl" href="/reference/cli/impl" description="Execute the plan with a local coding agent." />
<Card title="Status" href="/reference/cli/status" description="Check where you are in the setup lifecycle at a glance." />
<Card title="Install and upgrade" href="/reference/cli/install" description="Install or upgrade EQL in your database." />
<Card title="Programmatic API" href="/reference/cli/api" description="Use the CLI as a library in your own scripts and tooling." />
</Cards>
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
---
title: Interactive setup
description: Run stash init to authenticate, resolve your database, scaffold an encryption client, install dependencies, and add the EQL extension to CipherStash.
type: reference
components: [cli]
---

`npx stash init` is the first step in the CipherStash setup lifecycle. It authenticates you, resolves your database, scaffolds an encryption client, installs dependencies, installs the EQL extension, and writes a context file. When it finishes, it prompts you to continue to `stash plan`.
Expand All @@ -17,7 +19,7 @@ Init runs six steps with minimal prompts:
2. **Resolves the database**: Reads your `DATABASE_URL` and verifies a connection can be made. Detects your Postgres provider (Supabase from the URL host, or generic Postgres).
3. **Generates the encryption client file**: Auto-detects your integration (Drizzle from `drizzle.config.*` or `drizzle-orm`/`drizzle-kit` in `package.json`, Supabase from the `DATABASE_URL` host, or generic Postgres). Writes a placeholder client to `./src/encryption/index.ts` silently. If that file already exists, it prompts you to keep it or overwrite it.
4. **Installs dependencies**: Checks whether `@cipherstash/stack` and `stash` are already in `node_modules`. If both are present, skips silently. If either is missing, shows a single combined install prompt. Detects your package manager (npm, pnpm, yarn, bun) automatically.
5. **Installs EQL**: Runs the same logic as `stash db install`. Scaffolds `stash.config.ts` if missing, detects your provider, and installs the EQL extension into your database. You do not need to run `stash db install` separately after init.
5. **Installs EQL**: Runs the same logic as `stash eql install`. Scaffolds `stash.config.ts` if missing, detects your provider, and installs the EQL extension into your database. You do not need to run `stash eql install` separately after init.
6. **Gathers context**: Writes `.cipherstash/context.json` with the detected integration, package manager, schemas, environment keys, and available agents. This file is required by `stash plan` and `stash impl`.

Best case: 0 prompts (already authenticated, both packages installed, no existing client file, database reachable). Worst case: 2 prompts (region selection for first-time login, install confirmation for missing packages).
Expand Down Expand Up @@ -73,24 +75,24 @@ Answering yes launches `stash plan` immediately. Answering no (or running non-in
Next: run `stash plan` to draft your encryption plan.
```

## db install flags
## eql install flags

If you need to run EQL installation with specific flags (for example, writing a Supabase migration file), use `stash db install` directly after init:
If you need to run EQL installation with specific flags (for example, writing a Supabase migration file), use `stash eql install` directly after init:

```bash
npx stash db install --supabase --migration
npx stash db install --drizzle
npx stash db install --drizzle --supabase
npx stash eql install --supabase --migration
npx stash eql install --drizzle
npx stash eql install --drizzle --supabase
```

> **Good to know**: You can pass `--drizzle` and `--supabase` together. The CLI combines both behaviors: Supabase-compatible SQL output as a Drizzle migration.

See [Install and upgrade EQL](/stack/cipherstash/cli/install) for the full flag reference.
See [Install and upgrade EQL](/reference/cli/install) for the full flag reference.

## Next steps

<Cards>
<Card title="Draft an encryption plan" href="/stack/cipherstash/cli/plan" description="Run stash plan to hand off to a coding agent and produce a reviewable plan." />
<Card title="Execute an encryption plan" href="/stack/cipherstash/cli/impl" description="Run stash impl to execute the plan with a local agent." />
<Card title="Draft an encryption plan" href="/reference/cli/plan" description="Run stash plan to hand off to a coding agent and produce a reviewable plan." />
<Card title="Execute an encryption plan" href="/reference/cli/impl" description="Run stash impl to execute the plan with a local agent." />
<Card title="Going to production" href="/stack/deploy/going-to-production" description="Transition from device-based auth to environment variables for deployment." />
</Cards>
Loading