Skip to content
Open
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
12 changes: 12 additions & 0 deletions .changeset/rename-db-install-to-eql-install.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
"stash": minor
"@cipherstash/wizard": minor
---

Rename `stash db install`, `stash db upgrade`, and `stash db status` to
`stash eql install`, `stash eql upgrade`, and `stash eql status`. These
commands manage the EQL extension itself, so they now live under a dedicated
`eql` command group. The old `db` spellings keep working as deprecated
aliases that print a warning pointing at the new names. All help text,
hints, generated migration headers, and wizard steps now reference the
`eql` commands.
16 changes: 8 additions & 8 deletions e2e/tests/package-managers.e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,18 @@ describe('CLI init providers — package-manager-aware Next Steps', () => {
{
label: 'base',
create: createBaseProvider,
firstStep: (r) => `Set up your database: ${r} stash db install`,
firstStep: (r) => `Set up your database: ${r} stash eql install`,
},
{
label: 'drizzle',
create: createDrizzleProvider,
firstStep: (r) => `Set up your database: ${r} stash db install --drizzle`,
firstStep: (r) => `Set up your database: ${r} stash eql install --drizzle`,
},
{
label: 'supabase',
create: createSupabaseProvider,
firstStep: (r) =>
`Install EQL: ${r} stash db install --supabase (prompts for migration vs direct)`,
`Install EQL: ${r} stash eql install --supabase (prompts for migration vs direct)`,
},
]

Expand Down Expand Up @@ -158,12 +158,12 @@ describe.skipIf(!authConfigured)(
{ pm: 'yarn' as const, lockfile: 'yarn.lock' },
])('uses $pm runner when $lockfile is present', ({ pm, lockfile }) => {
const out = runWizard({ lockfile })
expect(out).toContain(`Run: ${RUNNER[pm]} stash db install`)
expect(out).toContain(`Run: ${RUNNER[pm]} stash eql install`)
})

it('falls back to npx when no lockfile and no user agent', () => {
const out = runWizard({})
expect(out).toContain('Run: npx stash db install')
expect(out).toContain('Run: npx stash eql install')
})
})

Expand All @@ -174,7 +174,7 @@ describe.skipIf(!authConfigured)(
{ pm: 'yarn' as const, userAgent: 'yarn/4.0.0 npm/? node/v20.0.0' },
])('uses $pm runner when UA is $userAgent', ({ pm, userAgent }) => {
const out = runWizard({ userAgent })
expect(out).toContain(`Run: ${RUNNER[pm]} stash db install`)
expect(out).toContain(`Run: ${RUNNER[pm]} stash eql install`)
})
})

Expand All @@ -184,15 +184,15 @@ describe.skipIf(!authConfigured)(
lockfile: 'pnpm-lock.yaml',
userAgent: 'bun/1.1.40 npm/? node/v22.3.0',
})
expect(out).toContain('Run: bunx stash db install')
expect(out).toContain('Run: bunx stash eql install')
})

it('npm user agent is ignored in favour of a lockfile', () => {
const out = runWizard({
lockfile: 'bun.lock',
userAgent: 'npm/10.2.4 node/v20.0.0',
})
expect(out).toContain('Run: bunx stash db install')
expect(out).toContain('Run: bunx stash eql install')
})
})
},
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ exercise the same code paths.
tweak only needs to land in one place. Add to `messages.ts` only when a
test actually asserts on the string — premature extraction is worse
than copy-paste here. For literals tests don't touch (e.g. command
names like `init`, `db install`), keep them inline.
names like `init`, `eql install`), keep them inline.
- **Telemetry.** The CLI source no longer imports `posthog-node` (analytics
moved to `packages/wizard`). The dep is still listed in `package.json`
and should be removed in a follow-up. If you re-introduce telemetry to
Expand Down
28 changes: 14 additions & 14 deletions packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export default defineConfig({

The CLI loads `.env` files automatically before reading the config, so `process.env` references work without extra setup. The config file is resolved by walking up from the current working directory.

Commands that consume `stash.config.ts`: `db install`, `db upgrade`, `db push`, `db validate`, `db status`, `db test-connection`, `schema build`. `db install` will scaffold `stash.config.ts` for you if it's missing.
Commands that consume `stash.config.ts`: `eql install`, `eql upgrade`, `db push`, `db validate`, `eql status`, `db test-connection`, `schema build`. `eql install` will scaffold `stash.config.ts` for you if it's missing.

---

Expand All @@ -83,10 +83,10 @@ npx stash init [--supabase] [--drizzle]
What `init` does, in order:

1. **Authenticate** — re-uses an existing token if found, otherwise opens the browser device-code flow.
2. **Resolve `DATABASE_URL`** — flag → env → `supabase status` → interactive prompt → hard-fail. The same resolver `db install` uses.
2. **Resolve `DATABASE_URL`** — flag → env → `supabase status` → interactive prompt → hard-fail. The same resolver `eql install` uses.
3. **Generate the encryption client** — connects to your database, lists tables, and prompts you to multi-select which columns to encrypt. Writes `./src/encryption/index.ts` with the right shape for the detected ORM (Drizzle / Supabase / plain Postgres). Falls back to a placeholder if the database has no tables yet.
4. **Install dependencies** — `@cipherstash/stack` (runtime) and `stash` (dev), with a confirmation prompt.
5. **Install EQL** — runs `stash db install` against the resolved URL after a y/N confirm.
5. **Install EQL** — runs `stash eql install` against the resolved URL after a y/N confirm.
6. **Hand off** — four-option menu (Claude Code / Codex / CipherStash Agent / write `AGENTS.md`). See the Quickstart section above for what each option writes and spawns.

The full pipeline state — integration, columns, env-key names, paths, versions — is captured in `.cipherstash/context.json`. The action plan at `.cipherstash/setup-prompt.md` tells whichever agent picks up next what's already done and what's left.
Expand Down Expand Up @@ -156,14 +156,14 @@ npx stash secrets delete -n DATABASE_URL -e production -y

---

### `npx stash db install`
### `npx stash eql install`

Configure your database and install CipherStash EQL extensions in a single command. Run this after `npx stash init`.
Configure your database and install CipherStash EQL extensions in a single command. Run this after `npx stash init`. (`npx stash db install` is a deprecated alias — it still works but prints a warning.)

When `stash.config.ts` is missing, the command auto-detects your encryption client file (or asks for the path) and writes the config before installing. Supabase and Drizzle are detected from your `DATABASE_URL` and project files, so the matching flags default on. Install uses bundled SQL for offline, deterministic runs.

```bash
npx stash db install [options]
npx stash eql install [options]
```

| Flag | Description |
Expand All @@ -183,12 +183,12 @@ The `--supabase` flag uses a Supabase-specific SQL variant and grants `USAGE`, t

---

### `npx stash db upgrade`
### `npx stash eql upgrade`

Upgrade an existing EQL installation to the version bundled with the package (or the latest from GitHub).

```bash
npx stash db upgrade [options]
npx stash eql upgrade [options]
```

| Flag | Description |
Expand All @@ -198,7 +198,7 @@ npx stash db upgrade [options]
| `--exclude-operator-family` | Skip operator family creation |
| `--latest` | Fetch the latest EQL from GitHub |

The install SQL is idempotent and safe to re-run. If EQL is not installed, the command suggests running `npx stash db install` instead.
The install SQL is idempotent and safe to re-run. If EQL is not installed, the command suggests running `npx stash eql install` instead.

---

Expand Down Expand Up @@ -260,12 +260,12 @@ npx stash db migrate

---

### `npx stash db status`
### `npx stash eql status`

Show the current state of EQL in your database.

```bash
npx stash db status
npx stash eql status
```

Reports EQL installation status and version, database permission status, and whether an active encrypt config exists in `eql_v2_configuration` (relevant only for CipherStash Proxy).
Expand Down Expand Up @@ -300,10 +300,10 @@ Reads `databaseUrl` from `stash.config.ts`.

## Drizzle migration mode

Use `--drizzle` with `npx stash db install` to add EQL installation to your Drizzle migration history instead of applying it directly. `--drizzle` is auto-detected when your project has `drizzle-orm`, `drizzle-kit`, or a `drizzle.config.*` file, so you usually don't need to pass it explicitly.
Use `--drizzle` with `npx stash eql install` to add EQL installation to your Drizzle migration history instead of applying it directly. `--drizzle` is auto-detected when your project has `drizzle-orm`, `drizzle-kit`, or a `drizzle.config.*` file, so you usually don't need to pass it explicitly.

```bash
npx stash db install --drizzle
npx stash eql install --drizzle
npx drizzle-kit migrate
```

Expand All @@ -315,7 +315,7 @@ How it works:
With a custom name or output directory:

```bash
npx stash db install --drizzle --name setup-eql --out ./migrations
npx stash eql install --drizzle --name setup-eql --out ./migrations
npx drizzle-kit migrate
```

Expand Down
10 changes: 5 additions & 5 deletions packages/cli/src/__tests__/supabase-migration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { SUPABASE_PERMISSIONS_SQL } from '../installer/index.js'
* Mirrors the production function but imported for testing.
*/
function migrationHeader(runner: string): string {
return `-- CipherStash EQL — installed by \`${runner} stash db install --supabase --migration\`.
return `-- CipherStash EQL — installed by \`${runner} stash eql install --supabase --migration\`.
--
-- This migration installs the CipherStash Encrypt Query Language (EQL) types,
-- functions, and operators into the \`eql_v2\` schema, then grants Supabase's
Expand Down Expand Up @@ -136,7 +136,7 @@ describe('writeSupabaseEqlMigration', () => {
const contents = fs.readFileSync(result.path, 'utf-8')
// Header comment block includes the detected runner instruction
expect(contents).toMatch(
/-- CipherStash EQL — installed by `(npx|bunx|pnpm dlx|yarn dlx) stash db install --supabase --migration`/,
/-- CipherStash EQL — installed by `(npx|bunx|pnpm dlx|yarn dlx) stash eql install --supabase --migration`/,
)
expect(contents).toContain('CipherStash')
// EQL SQL body — the bundled supabase variant defines eql_v2.
Expand Down Expand Up @@ -253,18 +253,18 @@ describe('migrationHeader', () => {
it('renders the header with the provided runner for npx', () => {
const header = migrationHeader('npx')
expect(header).toContain(
'-- CipherStash EQL — installed by `npx stash db install --supabase --migration`.',
'-- CipherStash EQL — installed by `npx stash eql install --supabase --migration`.',
)
})

it('renders the header with the provided runner for bunx', () => {
const header = migrationHeader('bunx')
expect(header).toContain('bunx stash db install')
expect(header).toContain('bunx stash eql install')
})

it('renders the header with the provided runner for pnpm dlx', () => {
const header = migrationHeader('pnpm dlx')
expect(header).toContain('pnpm dlx stash db install')
expect(header).toContain('pnpm dlx stash eql install')
})

it('includes all expected documentation lines', () => {
Expand Down
Loading
Loading