From 9eec8a41c9b567bb0f930c80bdfc33fb23ce8633 Mon Sep 17 00:00:00 2001 From: Dan Draper Date: Fri, 31 Jul 2026 00:11:48 +1000 Subject: [PATCH] docs: align references with Stack 1.0 --- IA.md | 13 +- content/docs/get-started/quickstart.mdx | 8 +- content/docs/integrations/drizzle/index.mdx | 12 +- .../integrations/supabase/edge-functions.mdx | 6 +- content/docs/reference/agent-skills.mdx | 121 ++++------ content/docs/reference/cli/auth.mdx | 41 ++-- content/docs/reference/cli/db.mdx | 41 +--- content/docs/reference/cli/doctor.mdx | 6 +- content/docs/reference/cli/encrypt.mdx | 24 +- content/docs/reference/cli/env.mdx | 36 ++- content/docs/reference/cli/eql.mdx | 93 ++++++-- content/docs/reference/cli/impl.mdx | 6 +- content/docs/reference/cli/index.mdx | 20 +- content/docs/reference/cli/init.mdx | 17 +- content/docs/reference/cli/manifest.mdx | 11 +- content/docs/reference/cli/meta.json | 3 +- content/docs/reference/cli/plan.mdx | 10 +- content/docs/reference/cli/schema.mdx | 8 +- content/docs/reference/cli/status.mdx | 6 +- content/docs/reference/cli/telemetry.mdx | 34 +++ content/docs/reference/cli/wizard.mdx | 6 +- content/docs/reference/eql/index.mdx | 35 ++- content/docs/solutions/data-residency.mdx | 2 +- content/docs/solutions/provable-access.mdx | 2 +- scripts/cli-supplements/auth.md | 27 +-- scripts/fixtures/stash-manifest.json | 222 +++++++++--------- scripts/generate-cli-docs.ts | 20 +- scripts/generate-docs.ts | 2 +- scripts/generate-drizzle-docs.ts | 4 +- scripts/generate-prisma-docs.ts | 4 +- scripts/generate-supabase-docs.ts | 4 +- 31 files changed, 442 insertions(+), 402 deletions(-) create mode 100644 content/docs/reference/cli/telemetry.mdx diff --git a/IA.md b/IA.md index c3ef001..6f51750 100644 --- a/IA.md +++ b/IA.md @@ -443,13 +443,10 @@ and the old `/compare/*` paths redirect there (`v2-redirects.mjs`). - [ ] OG images for v2 pages (route only covers legacy tree) - [ ] Correctness CI: snippet type-checking, SQL-vs-EQL-Docker, terminology lint (CIP-3337) - [ ] llms.txt curation + Cloudflare AI crawl policy + md-degradation check (CIP-3339) -- [ ] ⛔ EQL 3.0.0 release alignment (CIP-3352, blocks CIP-3335) — the EQL reference - documents the release as decided, ahead of the eql_v3 branch: payload `v: 3`, - OPE SEM specifier, Docker tag `:17-3.0.0`, `version()` output, schema files. - Each must land upstream or be walked back in the docs before merge -- [ ] ⛔ Stack SDK Supabase-wrapper v3 alignment (CIP-3355, blocks CIP-3335) — the - Supabase section documents the 0.18 wrapper API with v3 wire semantics; the - wrapper itself is still v2 (composite type, `like` wire op, v2 payloads) and - the SDK's v3 branches don't touch `src/supabase/` yet +- [x] EQL 3.0.4 release alignment (CIP-3352) — the EQL reference and CLI target + the released v3 schema and payload. +- [x] Stack SDK and Supabase-wrapper v3 alignment (CIP-3355) — + `@cipherstash/stack` and `@cipherstash/stack-supabase` 1.0.0 are released, + and the integration docs target their stable v3 surfaces. - [ ] Flip `ENABLE_V2_REDIRECTS=1`, delete `content/stack` + `/stack` routes + legacy loader (CIP-3335) - [ ] Consistency sweep + Supabase listing v3 revision (CIP-3335) diff --git a/content/docs/get-started/quickstart.mdx b/content/docs/get-started/quickstart.mdx index 3368e3d..c1175c0 100644 --- a/content/docs/get-started/quickstart.mdx +++ b/content/docs/get-started/quickstart.mdx @@ -5,9 +5,9 @@ type: tutorial components: [encryption, eql, cli, platform] audience: [developer] verifiedAgainst: - stack: "1.0.0-rc.0" - cli: "1.0.0-rc.0" - eql: "3.0.0" + stack: "1.0.0" + cli: "1.0.0" + eql: "3.0.4" --- CipherStash encrypts your data at the field level. Every value gets its own encryption key, and the database never sees plaintext. A breach, a compromised agent, or a curious insider sees ciphertext. @@ -16,7 +16,7 @@ By the end of this page you will have encrypted a field, stored it in Postgres, ## Before you start -- Node.js 18 or later. +- Node.js 22 or later. - A Postgres database you can connect to. - A [CipherStash account](https://dashboard.cipherstash.com/sign-up). The free plan is enough. diff --git a/content/docs/integrations/drizzle/index.mdx b/content/docs/integrations/drizzle/index.mdx index 7900097..9e28935 100644 --- a/content/docs/integrations/drizzle/index.mdx +++ b/content/docs/integrations/drizzle/index.mdx @@ -9,7 +9,7 @@ integration: setup: code-only pairsWith: [supabase, prisma] verifiedAgainst: - stack: "1.0.0-rc.4" + stack: "1.0.0" eql: "3.0.4" --- @@ -19,16 +19,18 @@ Drizzle keeps its shape. You declare each encrypted column with a concrete EQL t ```bash cta cta-type="install" example-id="install-drizzle" npm install @cipherstash/stack @cipherstash/stack-drizzle drizzle-orm +npm install --save-dev drizzle-kit ``` -Then install EQL into your database: +Add EQL to your Drizzle migration history: ```bash -npx stash eql install +npx stash eql migration --drizzle +npx drizzle-kit migrate ``` - -The v3 install (the default) runs directly against the database and cannot generate a Drizzle migration: `--drizzle` is rejected for a v3 install. EQL is therefore not part of your migration history, so a database rebuilt from migrations will not have it. Re-run the install after a rebuild. + +`stash eql migration --drizzle` uses your project-local `drizzle-kit` to create a custom migration, then fills it with the EQL v3 install SQL. Pass `--out` if your migration directory is not `drizzle/`. For a direct, out-of-band install instead, run `npx stash eql install`. ## Credentials diff --git a/content/docs/integrations/supabase/edge-functions.mdx b/content/docs/integrations/supabase/edge-functions.mdx index 84969c0..079f141 100644 --- a/content/docs/integrations/supabase/edge-functions.mdx +++ b/content/docs/integrations/supabase/edge-functions.mdx @@ -22,9 +22,9 @@ Map the `wasm-inline` entries in your function's `deno.json`: ```jsonc title="supabase/functions/encrypt/deno.json" { "imports": { - "@cipherstash/stack/wasm-inline": "npm:@cipherstash/stack@^0.18/wasm-inline", - "@cipherstash/auth/wasm-inline": "npm:@cipherstash/auth@^0.41/wasm-inline", - "@cipherstash/auth/cookies": "npm:@cipherstash/auth@^0.41/cookies" + "@cipherstash/stack/wasm-inline": "npm:@cipherstash/stack@^1.0.0/wasm-inline", + "@cipherstash/auth/wasm-inline": "npm:@cipherstash/auth@^0.42/wasm-inline", + "@cipherstash/auth/cookies": "npm:@cipherstash/auth@^0.42/cookies" } } ``` diff --git a/content/docs/reference/agent-skills.mdx b/content/docs/reference/agent-skills.mdx index 88eb5e5..887f6ba 100644 --- a/content/docs/reference/agent-skills.mdx +++ b/content/docs/reference/agent-skills.mdx @@ -1,109 +1,74 @@ --- title: Agent skills -description: "Install CipherStash agent skills to give your AI coding assistant accurate knowledge of encryption setup, schema building, and integrations." +description: "Install CipherStash agent skills to give your AI coding assistant accurate knowledge of encryption setup, schema building, deployment, and integrations." type: reference components: [encryption, cli] +verifiedAgainst: + stack: "1.0.0" + cli: "1.0.0" --- -CipherStash publishes a set of [agent skills](https://skills.sh/) that give AI coding assistants deep knowledge of the Stack SDK, CLI, and integrations. When installed, your agent can generate encryption schemas, write integration code, and guide you through database setup without hallucinating API surfaces. +CipherStash Stack 1.0 publishes 13 [agent skills](https://skills.sh/) covering the stable SDK, CLI, database surfaces, deployment workflow, and integrations. The skills give an AI coding assistant the exact APIs, commands, constraints, and rollout sequence it needs without making your application code part of the prompt. -Skills work with any AI coding tool that supports the skills protocol, including Claude Code, Cursor, GitHub Copilot, Windsurf, Cline, Gemini, AMP, Goose, Roo, and Trae. +Skills work with AI coding tools that support the skills protocol, including Claude Code, Codex, Cursor, GitHub Copilot, Windsurf, Cline, Gemini, AMP, Goose, Roo, and Trae. -## Install skills +## Install every skill -Skills are installed per project. Run this in your project root: +Install the complete collection in your project root: ```bash cta cta-type="install" example-id="install-agent-skills" npx skills add cipherstash/stack ``` -This installs all six CipherStash skills. Your agent activates the relevant skill based on what you are working on. +This installs all 13 skills. Your agent activates the relevant ones from the task and code it is working on. -### Install via the wizard +## Install through the Stash workflow -`@cipherstash/wizard` offers to copy integration-appropriate skills into `./.claude/skills/` after its post-agent steps: +The `stash` 1.0 CLI bundles the skills and selects a smaller set for the integration detected by `stash init`. When `stash impl` hands the reviewed plan to an agent, it copies the selected skills into the tool's skill directory or includes their guidance in the generated agent instructions. -| Integration | Skills installed | -|---|---| -| Drizzle | `stash-encryption`, `stash-drizzle`, `stash-cli` | -| Supabase | `stash-encryption`, `stash-supabase`, `stash-cli` | -| Prisma or generic | `stash-encryption`, `stash-cli` | +| Integration | Skills selected | +| --- | --- | +| Drizzle | `stash-encryption`, `stash-drizzle`, `stash-indexing`, `stash-deployment`, `stash-zerokms`, `stash-auth`, `stash-cli` | +| Supabase | `stash-encryption`, `stash-supabase`, `stash-indexing`, `stash-postgres`, `stash-edge`, `stash-deployment`, `stash-zerokms`, `stash-auth`, `stash-cli` | +| Prisma ORM 8 | `stash-encryption`, `stash-prisma`, `stash-indexing`, `stash-deployment`, `stash-zerokms`, `stash-auth`, `stash-cli` | +| PostgreSQL | `stash-encryption`, `stash-indexing`, `stash-postgres`, `stash-edge`, `stash-deployment`, `stash-zerokms`, `stash-auth`, `stash-cli` | -## Available skills - -### stash-encryption - -Core field-level encryption with `@cipherstash/stack`. The foundational skill, covering the full encryption API. - -**Covers:** schema definition with `encryptedTable` and `encryptedColumn`; single and bulk encrypt/decrypt; model operations (`encryptModel`, `decryptModel`, `bulkEncryptModels`, `bulkDecryptModels`); searchable encryption (equality, free-text search, range queries, encrypted JSONB); identity-aware encryption with `LockContext`; multi-tenant isolation with keysets; error handling with the `Result` pattern; migration from `@cipherstash/protect`. - -**Activates when:** you are defining encrypted schemas, writing encrypt/decrypt logic, or working with the `@cipherstash/stack` package. - -**Related docs:** [Stack SDK](/reference/stack) - -### stash-cli - -The CipherStash CLI (`stash`) for database setup, schema management, and project initialization. - -**Covers:** `stash.config.ts` configuration; the setup lifecycle (`init`, `plan`, `impl`, `status`); database commands (`db install`, `db upgrade`, `db push`, `db validate`, `db status`, `db test-connection`); `schema build`; `auth login`; the programmatic API (`EQLInstaller`, `loadStashConfig`, `defineConfig`, `loadBundledEqlSql`); Drizzle migration mode (`--drizzle`); Supabase-compatible installs (`--supabase`); automatic Supabase and Drizzle detection; automatic OPE fallback on managed databases. - -**Activates when:** you are working with `stash.config.ts`, running CLI commands, or setting up EQL in a database. - -**Related docs:** [CLI reference](/reference/cli) - -### stash-drizzle - -Drizzle ORM integration using `@cipherstash/stack-drizzle`, covering both EQL v2 and the EQL v3 dialect on `@cipherstash/stack-drizzle/v3`. - -**Covers:** the `encryptedType()` column type; `extractEncryptionSchema()`; `createEncryptionOperators()`; query operators (`eq`, `ne`, `like`, `ilike`, `gt`, `gte`, `lt`, `lte`, `between`, `inArray`, `asc`, `desc`); encrypted JSONB operators (`jsonbPathExists`, `jsonbPathQueryFirst`, `jsonbGet`); batched `and()` / `or()` conditions; EQL migration generation; non-encrypted column fallback; Express, Hono, and Next.js examples. - -**Activates when:** you are using Drizzle ORM with encrypted columns, or importing from `@cipherstash/stack-drizzle`. +Claude Code receives skills under `.claude/skills/`; Codex receives them under `.codex/skills/`. Handoffs to tools that do not load a skill directory receive the same guidance through the generated agent instructions. -**Related docs:** [Drizzle integration](/integrations/drizzle) - -### stash-supabase - -Supabase integration using `@cipherstash/stack-supabase`. - -**Covers:** the `encryptedSupabase()` wrapper; transparent encryption on `insert`, `update`, and `upsert`; transparent decryption on `select`, `single`, and `maybeSingle`; encrypted query filters (`eq`, `neq`, `like`, `ilike`, `gt`, `gte`, `lt`, `lte`, `in`, `match`, `or`, `not`, `filter`); identity-aware encryption with `.withLockContext()`; audit logging with `.audit()`; response types and error handling; Supabase-specific database setup. - -**Activates when:** you are using Supabase with encrypted columns, or importing from `@cipherstash/stack-supabase`. - -**Related docs:** [Supabase integration](/integrations/supabase) - -### stash-dynamodb - -Amazon DynamoDB integration using `@cipherstash/stack/dynamodb`. - -**Covers:** the `encryptedDynamoDB()` helper; attribute naming conventions (`__source` and `__hmac` suffixes); single and bulk encrypt/decrypt model operations; querying encrypted partition keys, sort keys, and GSI keys via HMAC attributes; nested object encryption with `encryptedField`; audit logging; table design patterns; examples with `PutCommand`, `GetCommand`, `QueryCommand`, and `BatchWriteCommand`. - -**Activates when:** you are using DynamoDB with encrypted attributes, or importing from `@cipherstash/stack/dynamodb`. - -**Related docs:** [DynamoDB integration](/stack/cipherstash/encryption/dynamodb) - -### stash-supply-chain-security - -Supply-chain security controls for a project that depends on `@cipherstash/stack`. - -**Covers:** post-install script policy (`onlyBuiltDependencies`); install cooldown (`minimumReleaseAge`); lockfile integrity (`blockExoticSubdeps` and the lockfile registry check); frozen-lockfile CI; registry pinning via `.npmrc`; Dependabot cooldown; and `CODEOWNERS`. +## Available skills -**Activates when:** you are modifying CI workflows, pnpm config, dependency updates, `.github/dependabot.yml`, or anything that changes how packages enter your build. +| Skill | What it covers | +| --- | --- | +| `stash-encryption` | The stable `@cipherstash/stack` EQL v3 typed schema, `EncryptionClient`, encryption and model operations, searchable fields, encrypted JSON, bulk operations, and migration lifecycle. | +| `stash-auth` | Credentials, `AutoStrategy`, `AccessKeyStrategy`, `OidcFederationStrategy`, `DeviceSessionStrategy`, the four `CS_*` variables, lock contexts, and authentication failures. | +| `stash-zerokms` | Keysets, clients, client keys, grants, revocation, key hierarchy, multi-tenant isolation, and diagnosing keyset mismatches. | +| `stash-indexing` | Functional indexes over EQL v3 term extractors, managed-Postgres constraints, `ORDER BY` and `GROUP BY` shapes, and `EXPLAIN` verification. | +| `stash-deployment` | The safe multi-deploy encryption rollout, credentials, backfill, read cutover, rollback, Prisma Compute, and preview environments. | +| `stash-cli` | `init`, `plan`, `impl`, `status`, authentication, `eql install/migration/repair/upgrade/status`, validation, backfill, drop, schema generation, and the agent interface. | +| `stash-drizzle` | `@cipherstash/stack-drizzle` 1.0 column factories, schema extraction, indexes, EQL v3 migration generation, and encrypted query operators such as `eq`, `matches`, `contains`, and `selector`. | +| `stash-supabase` | The `encryptedSupabase` wrapper, encrypted mutations and reads, filters and ordering, identity-aware encryption, and PostgREST limitations. | +| `stash-prisma` | `@cipherstash/stack-prisma` 1.0, encrypted Prisma column types, runtime envelopes, `decryptAll`, `eql*` query operators, and Prisma-owned EQL migrations. | +| `stash-postgres` | Hand-written EQL v3 SQL with `pg` or `postgres`, typed bind parameters, operator selection, `encryptQuery`, and double-encoding failures. | +| `stash-edge` | The `@cipherstash/stack/wasm-inline` entry for Deno, Supabase Edge Functions, Cloudflare Workers, and Bun, including explicit credentials and WASM-specific client behavior. | +| `stash-dynamodb` | The `@cipherstash/stack/dynamodb` surface, encrypted attributes, HMAC query attributes, nested values, bulk operations, and DynamoDB table design. | +| `stash-supply-chain-security` | Dependency admission, install cooldowns, lockfile integrity, frozen CI installs, registry pinning, Dependabot, `CODEOWNERS`, and npm provenance. | ## How skills work -When you ask your agent to help with a CipherStash task, it checks which skills are installed and activates the relevant one. The skill supplies the agent with the complete API surface (method signatures, types, return values), code examples matching the current SDK version, integration-specific patterns, and known limitations. +An installed skill activates when the task matches its description. Integration skills link back to the cross-cutting skills instead of duplicating their rules: authentication questions route to `stash-auth`, index design to `stash-indexing`, production rollout to `stash-deployment`, and key access to `stash-zerokms`. -This means your agent writes accurate CipherStash code on the first try, rather than guessing at API shapes or generating outdated patterns. +That separation keeps the guidance consistent. A Drizzle, Supabase, Prisma, or raw PostgreSQL task uses the same released encryption model and deployment safety rules while adding only the query and schema behavior specific to that integration. ## Typical workflow -1. **Initialize your project.** Ask your agent to set up CipherStash and it runs `stash init`, which authenticates you, installs EQL, scaffolds the encryption client, and writes `.cipherstash/context.json`. -2. **Draft a plan.** `stash plan` produces `.cipherstash/plan.md`, listing the tables and columns to encrypt. Review it before proceeding. -3. **Execute the plan.** `stash impl` reads the plan and wires up `encryptModel` and `decryptModel` in your codebase. -4. **Handle edge cases.** The agent knows about searchable encryption constraints, operator family limitations, identity-aware encryption, and multi-tenant keysets. +1. **Initialize the project.** Run `npx stash init` with `--drizzle`, `--supabase`, or `--prisma` when appropriate. The CLI authenticates, inspects the project, installs compatible packages, and records context under `.cipherstash/`. +2. **Draft a plan.** Run `npx stash plan`. The selected skills help the agent produce a reviewable `.cipherstash/plan.md` without changing the application. +3. **Review the plan.** Confirm the selected columns, capabilities, indexes, migration sequence, and deployment gates. +4. **Implement it.** Run `npx stash impl`. The CLI hands the plan and integration-specific skill set to your chosen agent. +5. **Track the rollout.** Run `npx stash status` as schema changes, dual writes, backfill, read cutover, and plaintext removal progress. ## Requirements -- An AI coding tool that supports the [skills protocol](https://skills.sh/) -- Node.js 18 or later +- Node.js 22 or later +- An AI coding tool that supports skills or generated agent instructions - A CipherStash account ([sign up](https://dashboard.cipherstash.com/sign-up)) diff --git a/content/docs/reference/cli/auth.mdx b/content/docs/reference/cli/auth.mdx index 2ba2a00..c0963c0 100644 --- a/content/docs/reference/cli/auth.mdx +++ b/content/docs/reference/cli/auth.mdx @@ -4,20 +4,25 @@ description: "Reference for the `stash auth` commands." type: reference components: [cli] verifiedAgainst: - cli: "0.17.0" + cli: "1.0.0" --- -{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v0.17.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} +{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v1.0.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} -Generated from **`stash` v0.17.0** via `npx stash@0.17.0 manifest --json`. Run `npx stash@0.17.0 --help` to see the live command surface. +Generated from **`stash` v1.0.0** via `npx stash@1.0.0 manifest --json`. Run `npx stash@1.0.0 --help` to see the live command surface. The `stash auth` command group. ### `auth login` -Authenticate with CipherStash +Runs the OAuth 2.0 device authorization flow: +1. Pick a region for your workspace. +2. Approve in the browser — the URL is printed, so it works over SSH/headless. +3. The CLI polls until you approve, then stores a short-lived token. +4. Your device is bound to the workspace's default keyset, so later + commands authenticate without a fresh login. ```bash npx stash auth login [flags] @@ -32,6 +37,7 @@ npx stash auth login [flags] | `--no-open` | Don't auto-open the verification URL in a browser (already implied by --json). | | `--supabase` | Track Supabase as the referrer. | | `--drizzle` | Track Drizzle as the referrer. | +| `--prisma` | Track Prisma as the referrer. | #### Examples @@ -65,24 +71,13 @@ npx stash auth regions npx stash auth regions --json ``` -## How authentication works +## Switching workspaces -`stash auth login` runs the OAuth 2.0 **device authorization flow**: +`stash` 1.0.0 keeps one active device-session profile at +`~/.cipherstash/auth.json`. To switch workspaces, run `npx stash auth login` +again and complete authorization for the target workspace. The new login +replaces the active session. -1. You pick a **region** for your CipherStash workspace. -2. The CLI opens your browser to a verification URL (and prints it, so it also - works over SSH or in a headless/agent environment) where you approve the - request. -3. Meanwhile the CLI polls CipherStash until you approve, then receives a - short-lived access token (it reports the token's expiry). -4. Your device is **bound to the workspace's default keyset**, so later commands - (`stash eql install`, `stash db push`, …) authenticate without a fresh login. - - -Login is device- and workspace-scoped. Authenticating from a new machine, or for a different workspace, re-runs the device flow. - - -{/* TODO(verify with product): profiles, multiple workspaces, and switching -between them (where they're stored and how they're selected) belong here, or -in a linked CLI concept page. The CLI currently exposes only `auth login`; -confirm the profile / workspace-switching surface before documenting it. */} +`stash init` reuses the active session when it is still valid, so switch +workspaces before running `init`. There is no separate profile manager or +workspace-switch command in `stash` 1.0.0. diff --git a/content/docs/reference/cli/db.mdx b/content/docs/reference/cli/db.mdx index e0c26b2..0d0e6ca 100644 --- a/content/docs/reference/cli/db.mdx +++ b/content/docs/reference/cli/db.mdx @@ -4,48 +4,17 @@ description: "Reference for the `stash db` commands." type: reference components: [cli, eql] verifiedAgainst: - cli: "0.17.0" + cli: "1.0.0" --- -{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v0.17.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} +{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v1.0.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} -Generated from **`stash` v0.17.0** via `npx stash@0.17.0 manifest --json`. Run `npx stash@0.17.0 --help` to see the live command surface. +Generated from **`stash` v1.0.0** via `npx stash@1.0.0 manifest --json`. Run `npx stash@1.0.0 --help` to see the live command surface. The `stash db` command group. -### `db push` - -Push encryption schema (writes pending if active config already exists) - -```bash -npx stash db push [flags] -``` - -#### Flags - -| Flag | Description | -| --- | --- | -| `--dry-run` | Show what would happen without making changes. | -| `--database-url ` | Override DATABASE_URL for this run only — never written to disk. (env: `DATABASE_URL`) | - - -### `db activate` - -Promote pending → active without renames (use after additive db push) - -```bash -npx stash db activate [flags] -``` - -#### Flags - -| Flag | Description | -| --- | --- | -| `--database-url ` | Override DATABASE_URL for this run only — never written to disk. (env: `DATABASE_URL`) | - - ### `db validate` Validate encryption schema @@ -60,7 +29,7 @@ npx stash db validate [flags] | --- | --- | | `--supabase` | Use Supabase-compatible mode. | | `--exclude-operator-family` | Skip operator family creation. | -| `--database-url ` | Override DATABASE_URL for this run only — never written to disk. (env: `DATABASE_URL`) | +| `--database-url ` | Database URL for this run only — never written to disk. Highest precedence in the resolution order: --database-url flag → DATABASE_URL env → supabase status → interactive prompt. A stash.config.ts is not a separate tier (its default databaseUrl re-runs this same chain); a hand-set literal databaseUrl in the config bypasses the resolver and wins over all of these. (env: `DATABASE_URL`) | ### `db migrate` @@ -83,4 +52,4 @@ npx stash db test-connection [flags] | Flag | Description | | --- | --- | -| `--database-url ` | Override DATABASE_URL for this run only — never written to disk. (env: `DATABASE_URL`) | +| `--database-url ` | Database URL for this run only — never written to disk. Highest precedence in the resolution order: --database-url flag → DATABASE_URL env → supabase status → interactive prompt. A stash.config.ts is not a separate tier (its default databaseUrl re-runs this same chain); a hand-set literal databaseUrl in the config bypasses the resolver and wins over all of these. (env: `DATABASE_URL`) | diff --git a/content/docs/reference/cli/doctor.mdx b/content/docs/reference/cli/doctor.mdx index 1c6efb8..176e425 100644 --- a/content/docs/reference/cli/doctor.mdx +++ b/content/docs/reference/cli/doctor.mdx @@ -4,13 +4,13 @@ description: "Diagnose install problems (native binaries, runtime)" type: reference components: [cli] verifiedAgainst: - cli: "0.17.0" + cli: "1.0.0" --- -{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v0.17.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} +{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v1.0.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} -Generated from **`stash` v0.17.0** via `npx stash@0.17.0 manifest --json`. Run `npx stash@0.17.0 --help` to see the live command surface. +Generated from **`stash` v1.0.0** via `npx stash@1.0.0 manifest --json`. Run `npx stash@1.0.0 --help` to see the live command surface. Diagnose install problems (native binaries, runtime) diff --git a/content/docs/reference/cli/encrypt.mdx b/content/docs/reference/cli/encrypt.mdx index 9c03ae8..126a6c8 100644 --- a/content/docs/reference/cli/encrypt.mdx +++ b/content/docs/reference/cli/encrypt.mdx @@ -4,13 +4,13 @@ description: "Reference for the `stash encrypt` commands." type: reference components: [cli, eql] verifiedAgainst: - cli: "0.17.0" + cli: "1.0.0" --- -{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v0.17.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} +{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v1.0.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} -Generated from **`stash` v0.17.0** via `npx stash@0.17.0 manifest --json`. Run `npx stash@0.17.0 --help` to see the live command surface. +Generated from **`stash` v1.0.0** via `npx stash@1.0.0 manifest --json`. Run `npx stash@1.0.0 --help` to see the live command surface. The `stash encrypt` command group. @@ -53,24 +53,6 @@ npx stash encrypt backfill [flags] | `--force` | Proceed past non-fatal safety checks. | -### `encrypt cutover` - -Rename swap encrypted → primary column - -```bash -npx stash encrypt cutover [flags] -``` - -#### Flags - -| Flag | Description | -| --- | --- | -| `--table ` | Target table. | -| `--column ` | Target column. | -| `--proxy-url ` | Proxy URL to verify against. | -| `--migrations-dir ` | Directory to write the rename migration into. | - - ### `encrypt drop` Generate a migration to drop the plaintext column diff --git a/content/docs/reference/cli/env.mdx b/content/docs/reference/cli/env.mdx index fe277a9..4cf0a15 100644 --- a/content/docs/reference/cli/env.mdx +++ b/content/docs/reference/cli/env.mdx @@ -1,19 +1,31 @@ --- title: stash env -description: "(experimental) Print production env vars for deployment" +description: "Mint deployment credentials and print them as env vars" type: reference components: [cli] verifiedAgainst: - cli: "0.17.0" + cli: "1.0.0" --- -{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v0.17.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} +{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v1.0.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} -Generated from **`stash` v0.17.0** via `npx stash@0.17.0 manifest --json`. Run `npx stash@0.17.0 --help` to see the live command surface. +Generated from **`stash` v1.0.0** via `npx stash@1.0.0 manifest --json`. Run `npx stash@1.0.0 --help` to see the live command surface. -(experimental) Print production env vars for deployment +Mints a fresh ZeroKMS client and a CipherStash access key from your +device-code session (`stash auth login`), then prints the four env +vars a deployed app needs: CS_WORKSPACE_CRN, CS_CLIENT_ID, +CS_CLIENT_KEY, CS_CLIENT_ACCESS_KEY. + +The access key is created with the member role (the CLI never mints +admin keys) and is shown exactly once — pipe the output into your +deployment secret store. Creating access keys requires your user to +have the admin role in the workspace. + +Stdout carries only the dotenv block (or the --json events); +progress UI goes to stderr, so `stash env --name x > prod.env` +and pipes into secret stores are safe. ```bash npx stash env [flags] @@ -23,4 +35,16 @@ npx stash env [flags] | Flag | Description | | --- | --- | -| `--write` | Write the vars to a file instead of printing them. | +| `--name ` | Name for the minted access key and ZeroKMS client. Prompted for interactively; required in non-interactive runs. | +| `--write [path]` | Write the vars to a file (default .env.production.local, mode 0600) instead of printing them. An existing file prompts before overwriting — and is refused non-interactively — before anything is minted. | +| `--json` | Emit machine-readable NDJSON (a \{ status: "minted" \} object, or \{ status: "written" \} with --write — deliberately secret-free since the secrets are in the file; failures are \{ status: "error" \}). Implies no prompts. | + + +## Examples + +```bash +npx stash env --name my-app-prod +npx stash env --name my-app-prod --write +npx stash env --name staging --write .env.staging.local +npx stash env --name edge-dev --json +``` diff --git a/content/docs/reference/cli/eql.mdx b/content/docs/reference/cli/eql.mdx index 63bf8be..813e1bb 100644 --- a/content/docs/reference/cli/eql.mdx +++ b/content/docs/reference/cli/eql.mdx @@ -4,13 +4,13 @@ description: "Reference for the `stash eql` commands." type: reference components: [cli, eql] verifiedAgainst: - cli: "0.17.0" + cli: "1.0.0" --- -{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v0.17.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} +{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v1.0.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} -Generated from **`stash` v0.17.0** via `npx stash@0.17.0 manifest --json`. Run `npx stash@0.17.0 --help` to see the live command surface. +Generated from **`stash` v1.0.0** via `npx stash@1.0.0 manifest --json`. Run `npx stash@1.0.0 --help` to see the live command surface. The `stash eql` command group. @@ -30,18 +30,78 @@ npx stash eql install [flags] | `--force` | Reinstall / overwrite even if already installed. | | `--dry-run` | Show what would happen without making changes. | | `--supabase` | Use Supabase-compatible mode (auto-detected from DATABASE_URL). | -| `--drizzle` | Generate a Drizzle migration instead of direct install (auto-detected from project). | -| `--migration` | Write a Supabase migration file instead of running SQL directly (requires --supabase). | -| `--direct` | Run the SQL directly against the database (requires --supabase; mutually exclusive with --migration). | -| `--migrations-dir ` | Override the Supabase migrations directory (requires --supabase). (default: `supabase/migrations`) | -| `--exclude-operator-family` | Skip operator family creation. | -| `--eql-version <2\|3>` | EQL generation to target. v3 is the native eql_v3.* domain schema (direct install only for now). (default: `2`) | -| `--latest` | Fetch the latest EQL from GitHub (v2 only). | -| `--name ` | With --drizzle: name for the generated migration (defaults to a scaffold name). | -| `--out ` | With --drizzle: directory to write the generated migration into. | -| `--database-url ` | Override DATABASE_URL for this run only — never written to disk. (env: `DATABASE_URL`) | +| `--database-url ` | Database URL for this run only — never written to disk. Highest precedence in the resolution order: --database-url flag → DATABASE_URL env → supabase status → interactive prompt. A stash.config.ts is not a separate tier (its default databaseUrl re-runs this same chain); a hand-set literal databaseUrl in the config bypasses the resolver and wins over all of these. (env: `DATABASE_URL`) | +### `eql migration` + +Generate an EQL v3 install migration for your ORM (Drizzle; Prisma Next installs EQL through its own migrations) + +```bash +npx stash eql migration [flags] +``` + +#### Flags + +| Flag | Description | +| --- | --- | +| `--drizzle` | Emit a Drizzle custom migration containing the EQL v3 install SQL. | +| `--prisma` | Not needed: Prisma Next installs EQL through its own migration framework — run `prisma-next migrate` instead. | +| `--supabase` | Append the Supabase role grants (eql_v3 + eql_v3_internal for anon/authenticated/service_role). | +| `--name ` | Name for the generated migration (Drizzle). Letters, numbers, dashes, underscores only. Defaults to `install-eql`. | +| `--out ` | Directory drizzle-kit writes the migration into (passed to `drizzle-kit generate --out`). Defaults to `drizzle`; set it to match your drizzle.config.ts. | +| `--dry-run` | Show what would happen without making changes. | + + +#### Examples + +```bash +npx stash eql migration --drizzle +npx stash eql migration --drizzle --supabase +``` + +### `eql repair` + +Sweep an existing Drizzle output directory for in-place +`ALTER COLUMN ... SET DATA TYPE ` statements — which cannot run, +because Postgres has no cast from text/numeric to an EQL domain — and rewrite +each into an additive encrypted column that preserves the source column. + +This is the same sweep `eql migration --drizzle` runs, without having to +generate an EQL install migration you do not want just to trigger it. + +Migrations the database has already applied are reported and left alone: +rewriting one would leave its .sql describing a shape that database never got +from it, so a fresh CI or staging database replaying the file would silently +diverge. Pass --database-url so that check can run; without it the repair +proceeds and warns that applied state could not be verified. If your +drizzle.config.ts overrides `migrations.table` / `migrations.schema`, name +the ledger with --migrations-table — otherwise the check queries the default +relation, finds nothing, and reports applied state as unverified. + +```bash +npx stash eql repair [flags] +``` + +#### Flags + +| Flag | Description | +| --- | --- | +| `--drizzle` | Repair a Drizzle migration directory. | +| `--out ` | Directory holding the migrations to sweep. Defaults to `drizzle`; set it to match your drizzle.config.ts. | +| `--migrations-table <[schema.]table>` | Drizzle's migration ledger, when drizzle.config.ts overrides `migrations.table` / `migrations.schema`. Defaults to `drizzle.__drizzle_migrations`. Only read with --database-url. | +| `--dry-run` | Show what would happen without making changes. | +| `--database-url ` | Database URL for this run only — never written to disk. Highest precedence in the resolution order: --database-url flag → DATABASE_URL env → supabase status → interactive prompt. A stash.config.ts is not a separate tier (its default databaseUrl re-runs this same chain); a hand-set literal databaseUrl in the config bypasses the resolver and wins over all of these. (env: `DATABASE_URL`) | + + +#### Examples + +```bash +npx stash eql repair --drizzle +npx stash eql repair --drizzle --dry-run +npx stash eql repair --drizzle --out db/migrations --database-url postgres://… +``` + ### `eql upgrade` Upgrade EQL extensions to the latest version @@ -56,10 +116,7 @@ npx stash eql upgrade [flags] | --- | --- | | `--dry-run` | Show what would happen without making changes. | | `--supabase` | Use Supabase-compatible mode. | -| `--exclude-operator-family` | Skip operator family creation. | -| `--eql-version <2\|3>` | EQL generation to target. (default: `2`) | -| `--latest` | Fetch the latest EQL from GitHub (v2 only). | -| `--database-url ` | Override DATABASE_URL for this run only — never written to disk. (env: `DATABASE_URL`) | +| `--database-url ` | Database URL for this run only — never written to disk. Highest precedence in the resolution order: --database-url flag → DATABASE_URL env → supabase status → interactive prompt. A stash.config.ts is not a separate tier (its default databaseUrl re-runs this same chain); a hand-set literal databaseUrl in the config bypasses the resolver and wins over all of these. (env: `DATABASE_URL`) | ### `eql status` @@ -74,4 +131,4 @@ npx stash eql status [flags] | Flag | Description | | --- | --- | -| `--database-url ` | Override DATABASE_URL for this run only — never written to disk. (env: `DATABASE_URL`) | +| `--database-url ` | Database URL for this run only — never written to disk. Highest precedence in the resolution order: --database-url flag → DATABASE_URL env → supabase status → interactive prompt. A stash.config.ts is not a separate tier (its default databaseUrl re-runs this same chain); a hand-set literal databaseUrl in the config bypasses the resolver and wins over all of these. (env: `DATABASE_URL`) | diff --git a/content/docs/reference/cli/impl.mdx b/content/docs/reference/cli/impl.mdx index b3ce114..af1fbd0 100644 --- a/content/docs/reference/cli/impl.mdx +++ b/content/docs/reference/cli/impl.mdx @@ -4,13 +4,13 @@ description: "Execute the plan with a local agent" type: reference components: [cli] verifiedAgainst: - cli: "0.17.0" + cli: "1.0.0" --- -{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v0.17.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} +{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v1.0.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} -Generated from **`stash` v0.17.0** via `npx stash@0.17.0 manifest --json`. Run `npx stash@0.17.0 --help` to see the live command surface. +Generated from **`stash` v1.0.0** via `npx stash@1.0.0 manifest --json`. Run `npx stash@1.0.0 --help` to see the live command surface. Execute the plan with a local agent diff --git a/content/docs/reference/cli/index.mdx b/content/docs/reference/cli/index.mdx index b8f6a0a..eadd67e 100644 --- a/content/docs/reference/cli/index.mdx +++ b/content/docs/reference/cli/index.mdx @@ -1,20 +1,20 @@ --- title: CLI navTitle: Overview -description: "Command reference for the stash CLI, generated from v0.17.0." +description: "Command reference for the stash CLI, generated from v1.0.0." type: reference components: [cli] verifiedAgainst: - cli: "0.17.0" + cli: "1.0.0" --- -{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v0.17.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} +{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v1.0.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} -Generated from **`stash` v0.17.0** via `npx stash@0.17.0 manifest --json`. Run `npx stash@0.17.0 --help` to see the live command surface. +Generated from **`stash` v1.0.0** via `npx stash@1.0.0 manifest --json`. Run `npx stash@1.0.0 --help` to see the live command surface. -The `stash` CLI. Install with `npx stash@0.17.0`. Every command accepts `--help` and `--version`. +The `stash` CLI. Install with `npx stash@1.0.0`. Every command accepts `--help` and `--version`. ### Setup & workflow @@ -27,6 +27,7 @@ The `stash` CLI. Install with `npx stash@0.17.0`. Every command accepts `--help` | [`wizard`](/reference/cli/wizard) | AI-guided encryption setup (reads your codebase) | | [`doctor`](/reference/cli/doctor) | Diagnose install problems (native binaries, runtime) | | [`manifest`](/reference/cli/manifest) | Print the structured, versioned command surface | +| [`telemetry`](/reference/cli/telemetry) | Manage anonymous usage analytics | ### Auth @@ -40,6 +41,8 @@ The `stash` CLI. Install with `npx stash@0.17.0`. Every command accepts `--help` | Command | Description | | --- | --- | | [`eql install`](/reference/cli/eql#eql-install) | Scaffold stash.config.ts (if missing) and install EQL extensions | +| [`eql migration`](/reference/cli/eql#eql-migration) | Generate an EQL v3 install migration for your ORM (Drizzle; Prisma Next installs EQL through its own migrations) | +| [`eql repair`](/reference/cli/eql#eql-repair) | Repair migrations drizzle-kit generated with an un-runnable ALTER COLUMN to an encrypted type | | [`eql upgrade`](/reference/cli/eql#eql-upgrade) | Upgrade EQL extensions to the latest version | | [`eql status`](/reference/cli/eql#eql-status) | Show EQL installation status | @@ -47,8 +50,6 @@ The `stash` CLI. Install with `npx stash@0.17.0`. Every command accepts `--help` | Command | Description | | --- | --- | -| [`db push`](/reference/cli/db#db-push) | Push encryption schema (writes pending if active config already exists) | -| [`db activate`](/reference/cli/db#db-activate) | Promote pending → active without renames (use after additive db push) | | [`db validate`](/reference/cli/db#db-validate) | Validate encryption schema | | [`db migrate`](/reference/cli/db#db-migrate) | Run pending encrypt config migrations (not yet implemented) | | [`db test-connection`](/reference/cli/db#db-test-connection) | Test database connectivity | @@ -66,11 +67,10 @@ The `stash` CLI. Install with `npx stash@0.17.0`. Every command accepts `--help` | [`encrypt status`](/reference/cli/encrypt#encrypt-status) | Show per-column migration status (phase, progress, drift) | | [`encrypt plan`](/reference/cli/encrypt#encrypt-plan) | Diff intent (.cipherstash/migrations.json) vs observed state | | [`encrypt backfill`](/reference/cli/encrypt#encrypt-backfill) | Resumably encrypt plaintext into the encrypted column | -| [`encrypt cutover`](/reference/cli/encrypt#encrypt-cutover) | Rename swap encrypted → primary column | | [`encrypt drop`](/reference/cli/encrypt#encrypt-drop) | Generate a migration to drop the plaintext column | -### Experimental +### Deployment | Command | Description | | --- | --- | -| [`env`](/reference/cli/env) | (experimental) Print production env vars for deployment | +| [`env`](/reference/cli/env) | Mint deployment credentials and print them as env vars | diff --git a/content/docs/reference/cli/init.mdx b/content/docs/reference/cli/init.mdx index 518544b..e7fc9ef 100644 --- a/content/docs/reference/cli/init.mdx +++ b/content/docs/reference/cli/init.mdx @@ -4,16 +4,19 @@ description: "Initialize CipherStash for your project" type: reference components: [cli] verifiedAgainst: - cli: "0.17.0" + cli: "1.0.0" --- -{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v0.17.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} +{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v1.0.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} -Generated from **`stash` v0.17.0** via `npx stash@0.17.0 manifest --json`. Run `npx stash@0.17.0 --help` to see the live command surface. +Generated from **`stash` v1.0.0** via `npx stash@1.0.0 manifest --json`. Run `npx stash@1.0.0 --help` to see the live command surface. -Initialize CipherStash for your project +Set up CipherStash end-to-end: authenticate, introspect your database, +install dependencies, install EQL, and hand off the rest to your local +coding agent. Every prompt has a non-interactive escape hatch, so init +never blocks waiting on a TTY (CI, agents, pipes). ```bash npx stash init [flags] @@ -25,9 +28,7 @@ npx stash init [flags] | --- | --- | | `--supabase` | Use Supabase-specific setup flow. | | `--drizzle` | Use Drizzle-specific setup flow. | -| `--prisma-next` | Use Prisma Next-specific setup flow (EQL bundle installed via prisma-next migration apply). | -| `--proxy` | Query encrypted data via CipherStash Proxy. | -| `--no-proxy` | Query encrypted data directly via the SDK. (default: `true`) | +| `--prisma` | Use Prisma Next-specific setup flow (EQL bundle installed via prisma-next migrate). | | `--region ` | Region to authenticate against (e.g. us-east-1). Skips the interactive region picker. Required for non-interactive init when not already logged in. (env: `STASH_REGION`) | @@ -36,6 +37,6 @@ npx stash init [flags] ```bash npx stash init npx stash init --supabase -npx stash init --prisma-next +npx stash init --prisma npx stash init --region us-east-1 ``` diff --git a/content/docs/reference/cli/manifest.mdx b/content/docs/reference/cli/manifest.mdx index 4c7578d..0ccb5aa 100644 --- a/content/docs/reference/cli/manifest.mdx +++ b/content/docs/reference/cli/manifest.mdx @@ -4,16 +4,19 @@ description: "Print the structured, versioned command surface" type: reference components: [cli] verifiedAgainst: - cli: "0.17.0" + cli: "1.0.0" --- -{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v0.17.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} +{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v1.0.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} -Generated from **`stash` v0.17.0** via `npx stash@0.17.0 manifest --json`. Run `npx stash@0.17.0 --help` to see the live command surface. +Generated from **`stash` v1.0.0** via `npx stash@1.0.0 manifest --json`. Run `npx stash@1.0.0 --help` to see the live command surface. -Print the structured, versioned command surface +Emit the CLI command surface as data. `--json` produces the machine- +readable manifest the docs generator and agents consume; without it a +grouped command list is printed. The manifest is stamped with the CLI +version, so a page generated from it always names the version it describes. ```bash npx stash manifest [flags] diff --git a/content/docs/reference/cli/meta.json b/content/docs/reference/cli/meta.json index 86e9f17..93463e4 100644 --- a/content/docs/reference/cli/meta.json +++ b/content/docs/reference/cli/meta.json @@ -10,6 +10,7 @@ "wizard", "doctor", "manifest", + "telemetry", "---Auth---", "auth", "---EQL---", @@ -20,7 +21,7 @@ "schema", "---Encrypt---", "encrypt", - "---Experimental---", + "---Deployment---", "env" ] } diff --git a/content/docs/reference/cli/plan.mdx b/content/docs/reference/cli/plan.mdx index 4904f7a..082ec50 100644 --- a/content/docs/reference/cli/plan.mdx +++ b/content/docs/reference/cli/plan.mdx @@ -4,13 +4,13 @@ description: "Draft a reviewable encryption plan at .cipherstash/plan.md" type: reference components: [cli] verifiedAgainst: - cli: "0.17.0" + cli: "1.0.0" --- -{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v0.17.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} +{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v1.0.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} -Generated from **`stash` v0.17.0** via `npx stash@0.17.0 manifest --json`. Run `npx stash@0.17.0 --help` to see the live command surface. +Generated from **`stash` v1.0.0** via `npx stash@1.0.0 manifest --json`. Run `npx stash@1.0.0 --help` to see the live command surface. Draft a reviewable encryption plan at .cipherstash/plan.md @@ -23,7 +23,8 @@ npx stash plan [flags] | Flag | Description | | --- | --- | -| `--complete-rollout` | Plan the entire encryption lifecycle (schema-add through drop) in one document. Skips the production-deploy gate; only safe when this database is not backing a deployed application. | +| `--complete-rollout` | Plan the entire encryption lifecycle (schema-add through drop) in one document. Skips the production-deploy gate; only safe when this database is not backing a deployed application. Needs confirmation — an interactive prompt, or --yes non-interactively (else it exits non-zero without drafting). | +| `--yes` | Confirm --complete-rollout's gate-skip without a prompt (for automation / CI). No effect without --complete-rollout. | | `--target ` | Skip the agent-target picker and hand off directly to one of claude-code \| codex \| agents-md \| wizard. Safe in non-TTY contexts. | @@ -32,4 +33,5 @@ npx stash plan [flags] ```bash npx stash plan npx stash plan --target claude-code +npx stash plan --complete-rollout --yes --target claude-code ``` diff --git a/content/docs/reference/cli/schema.mdx b/content/docs/reference/cli/schema.mdx index 9b5e360..ada1471 100644 --- a/content/docs/reference/cli/schema.mdx +++ b/content/docs/reference/cli/schema.mdx @@ -4,13 +4,13 @@ description: "Reference for the `stash schema` commands." type: reference components: [cli, eql] verifiedAgainst: - cli: "0.17.0" + cli: "1.0.0" --- -{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v0.17.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} +{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v1.0.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} -Generated from **`stash` v0.17.0** via `npx stash@0.17.0 manifest --json`. Run `npx stash@0.17.0 --help` to see the live command surface. +Generated from **`stash` v1.0.0** via `npx stash@1.0.0 manifest --json`. Run `npx stash@1.0.0 --help` to see the live command surface. The `stash schema` command group. @@ -28,4 +28,4 @@ npx stash schema build [flags] | Flag | Description | | --- | --- | | `--supabase` | Use Supabase-compatible mode. | -| `--database-url ` | Override DATABASE_URL for this run only — never written to disk. (env: `DATABASE_URL`) | +| `--database-url ` | Database URL for this run only — never written to disk. Highest precedence in the resolution order: --database-url flag → DATABASE_URL env → supabase status → interactive prompt. A stash.config.ts is not a separate tier (its default databaseUrl re-runs this same chain); a hand-set literal databaseUrl in the config bypasses the resolver and wins over all of these. (env: `DATABASE_URL`) | diff --git a/content/docs/reference/cli/status.mdx b/content/docs/reference/cli/status.mdx index ba033d7..9fcd239 100644 --- a/content/docs/reference/cli/status.mdx +++ b/content/docs/reference/cli/status.mdx @@ -4,13 +4,13 @@ description: "Displays implementation status" type: reference components: [cli] verifiedAgainst: - cli: "0.17.0" + cli: "1.0.0" --- -{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v0.17.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} +{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v1.0.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} -Generated from **`stash` v0.17.0** via `npx stash@0.17.0 manifest --json`. Run `npx stash@0.17.0 --help` to see the live command surface. +Generated from **`stash` v1.0.0** via `npx stash@1.0.0 manifest --json`. Run `npx stash@1.0.0 --help` to see the live command surface. Displays implementation status diff --git a/content/docs/reference/cli/telemetry.mdx b/content/docs/reference/cli/telemetry.mdx new file mode 100644 index 0000000..3eaebce --- /dev/null +++ b/content/docs/reference/cli/telemetry.mdx @@ -0,0 +1,34 @@ +--- +title: stash telemetry +description: "Manage anonymous usage analytics" +type: reference +components: [cli] +verifiedAgainst: + cli: "1.0.0" +--- + +{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v1.0.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} + + +Generated from **`stash` v1.0.0** via `npx stash@1.0.0 manifest --json`. Run `npx stash@1.0.0 --help` to see the live command surface. + + +Manage the anonymous, opt-out usage analytics the CLI collects to +improve the tool. `status` (the default) reports whether telemetry is +on and which setting governs it; `enable` / `disable` write your saved +preference. Telemetry is also disabled by the DO_NOT_TRACK or +STASH_TELEMETRY_DISABLED environment variables and automatically in CI. +No plaintext, schema, table/column names, or connection details are +ever collected. See https://cipherstash.com/docs/reference/cli. + +```bash +npx stash telemetry +``` + +## Examples + +```bash +npx stash telemetry status +npx stash telemetry disable +npx stash telemetry enable +``` diff --git a/content/docs/reference/cli/wizard.mdx b/content/docs/reference/cli/wizard.mdx index 05678ed..f3e6956 100644 --- a/content/docs/reference/cli/wizard.mdx +++ b/content/docs/reference/cli/wizard.mdx @@ -4,13 +4,13 @@ description: "AI-guided encryption setup (reads your codebase)" type: reference components: [cli] verifiedAgainst: - cli: "0.17.0" + cli: "1.0.0" --- -{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v0.17.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} +{/* GENERATED — do not edit. Produced by scripts/generate-cli-docs.ts from `stash manifest --json` (v1.0.0). Re-run `bun run generate-docs:cli` to refresh from the latest published CLI. */} -Generated from **`stash` v0.17.0** via `npx stash@0.17.0 manifest --json`. Run `npx stash@0.17.0 --help` to see the live command surface. +Generated from **`stash` v1.0.0** via `npx stash@1.0.0 manifest --json`. Run `npx stash@1.0.0 --help` to see the live command surface. AI-guided encryption setup (reads your codebase) diff --git a/content/docs/reference/eql/index.mdx b/content/docs/reference/eql/index.mdx index d09cd07..0b1bebe 100644 --- a/content/docs/reference/eql/index.mdx +++ b/content/docs/reference/eql/index.mdx @@ -5,7 +5,7 @@ description: "Encrypt Query Language (EQL) installs encrypted column types and o type: reference components: [eql] verifiedAgainst: - eql: "3.0.0" + eql: "3.0.4" --- @@ -26,13 +26,13 @@ Every encrypted column is a `jsonb`-backed domain type in the `public` schema (t Point the [Stash CLI](/reference/cli) at your database and install the `eql_v3` schema: ```bash -npx stash eql install --eql-version 3 +npx stash eql install ``` `stash eql install` scaffolds a [`stash.config.ts`](#configuration) if your project doesn't have one, then installs the `eql_v3` schema — all domain types, operators, functions, and aggregates — along with the `cs_migrations` tracking schema that the `stash encrypt` commands depend on. It is idempotent: re-running reports that EQL is already installed and changes nothing. Pass `--force` to reinstall in place. - -`--eql-version 3` selects the native `eql_v3` domain schema this reference documents. Without it the CLI installs EQL v2. v3 installs directly against the database, so the `--drizzle`, `--migration`, and `--latest` flags — all v2-only — don't apply. + +EQL v3 is the only installation target in `stash` 1.0.0, so no version flag is required. The [EQL v2 reference](/reference/eql/v2) remains available for applications maintaining an existing v2 deployment. @@ -43,7 +43,7 @@ npx stash eql install --eql-version 3 The CLI reads the connection string from `DATABASE_URL` (your environment or a `.env` file) and prompts if it can't find one. Override it for a single run — handy when installing across several databases — with `--database-url`, which is used for that run only and never written to disk: ```bash -npx stash eql install --eql-version 3 \ +npx stash eql install \ --database-url postgres://user:pass@host:5432/mydb ``` @@ -62,13 +62,13 @@ Or check directly from SQL: ```sql SELECT eql_v3.version(); --- '3.0.0' +-- '3.0.4' ``` -To pull in a newer EQL release later, run `npx stash eql upgrade --eql-version 3`. +To pull in a newer EQL release later, run `npx stash eql upgrade`. To uninstall, drop both EQL schemas: `DROP SCHEMA eql_v3, eql_v3_internal CASCADE`. This removes the encrypted operators and functions, so queries against encrypted columns stop resolving — but your data survives: the `public.*` domain types (and the columns typed as them) live in the `public` schema and are left untouched. Remove those separately only if you intend to drop or re-type the columns. @@ -92,6 +92,25 @@ export default defineConfig({ }); ``` +### Drizzle migration history + +For a Drizzle project, generate a custom migration instead of installing EQL directly: + +```bash +npx stash eql migration --drizzle +npx drizzle-kit migrate +``` + +The command runs your project-local `drizzle-kit`, creates a custom migration, and writes the same EQL v3 SQL that `stash eql install` applies directly. Add `--supabase` when the database is also reached through Supabase PostgREST, and use `--out` when your Drizzle migration directory is not `drizzle/`. + +If `drizzle-kit generate` has already emitted an in-place `ALTER COLUMN ... SET DATA TYPE` for an encrypted domain, repair the unapplied migration before running it: + +```bash +npx stash eql repair --drizzle --database-url "$DATABASE_URL" +``` + +See the [`eql migration`](/reference/cli/eql#eql-migration) and [`eql repair`](/reference/cli/eql#eql-repair) references for all options. Prisma ORM 8 installs EQL through its own migration graph and does not use either command. + ### dbdev EQL is also published to [dbdev](https://database.dev/cipherstash/eql). The dbdev release can lag behind GitHub releases, so prefer `stash eql install` when you need the latest version. @@ -105,7 +124,7 @@ docker run --rm -p 5432:5432 -e POSTGRES_PASSWORD=postgres \ ghcr.io/cipherstash/postgres-eql:17 ``` -EQL installs automatically on first boot. Images are available for PostgreSQL 14–17 (`:14` through `:17`), and you can pin a specific EQL version with a suffixed tag (for example `:17-3.0.0`). +EQL installs automatically on first boot. Images are available for PostgreSQL 14–17 (`:14` through `:17`), and you can pin a specific EQL version with a suffixed tag (for example `:17-3.0.4`). ## Permissions diff --git a/content/docs/solutions/data-residency.mdx b/content/docs/solutions/data-residency.mdx index 74effb9..6c24689 100644 --- a/content/docs/solutions/data-residency.mdx +++ b/content/docs/solutions/data-residency.mdx @@ -5,7 +5,7 @@ type: concept components: [platform, encryption] audience: [cto, ciso] verifiedAgainst: - stack: "0.18.0" + stack: "1.0.0" --- CipherStash provides data residency guarantees through regional key management, encryption that happens entirely in your infrastructure, and cryptographic key splitting. This page covers the deployment patterns for organizations with cross-border data requirements. diff --git a/content/docs/solutions/provable-access.mdx b/content/docs/solutions/provable-access.mdx index 84875fd..950b917 100644 --- a/content/docs/solutions/provable-access.mdx +++ b/content/docs/solutions/provable-access.mdx @@ -5,7 +5,7 @@ type: concept components: [platform, encryption] audience: [ciso, cto] verifiedAgainst: - stack: "0.19.0" + stack: "1.0.0" auth: "0.42.0" --- diff --git a/scripts/cli-supplements/auth.md b/scripts/cli-supplements/auth.md index b17fc57..aa87664 100644 --- a/scripts/cli-supplements/auth.md +++ b/scripts/cli-supplements/auth.md @@ -1,21 +1,10 @@ -## How authentication works +## Switching workspaces -`stash auth login` runs the OAuth 2.0 **device authorization flow**: +`stash` 1.0.0 keeps one active device-session profile at +`~/.cipherstash/auth.json`. To switch workspaces, run `npx stash auth login` +again and complete authorization for the target workspace. The new login +replaces the active session. -1. You pick a **region** for your CipherStash workspace. -2. The CLI opens your browser to a verification URL (and prints it, so it also - works over SSH or in a headless/agent environment) where you approve the - request. -3. Meanwhile the CLI polls CipherStash until you approve, then receives a - short-lived access token (it reports the token's expiry). -4. Your device is **bound to the workspace's default keyset**, so later commands - (`stash eql install`, `stash db push`, …) authenticate without a fresh login. - - -Login is device- and workspace-scoped. Authenticating from a new machine, or for a different workspace, re-runs the device flow. - - -{/* TODO(verify with product): profiles, multiple workspaces, and switching -between them (where they're stored and how they're selected) belong here, or -in a linked CLI concept page. The CLI currently exposes only `auth login`; -confirm the profile / workspace-switching surface before documenting it. */} +`stash init` reuses the active session when it is still valid, so switch +workspaces before running `init`. There is no separate profile manager or +workspace-switch command in `stash` 1.0.0. diff --git a/scripts/fixtures/stash-manifest.json b/scripts/fixtures/stash-manifest.json index 8190378..9c54546 100644 --- a/scripts/fixtures/stash-manifest.json +++ b/scripts/fixtures/stash-manifest.json @@ -1,6 +1,6 @@ { "name": "stash", - "version": "0.17.0", + "version": "1.0.0", "groups": [ { "title": "Setup & workflow", @@ -12,7 +12,7 @@ "examples": [ "init", "init --supabase", - "init --prisma-next", + "init --prisma", "init --region us-east-1" ], "flags": [ @@ -25,17 +25,8 @@ "description": "Use Drizzle-specific setup flow." }, { - "name": "--prisma-next", - "description": "Use Prisma Next-specific setup flow (EQL bundle installed via prisma-next migration apply)." - }, - { - "name": "--proxy", - "description": "Query encrypted data via CipherStash Proxy." - }, - { - "name": "--no-proxy", - "description": "Query encrypted data directly via the SDK.", - "default": "true" + "name": "--prisma", + "description": "Use Prisma Next-specific setup flow (EQL bundle installed via prisma-next migrate)." }, { "name": "--region", @@ -48,11 +39,19 @@ { "name": "plan", "summary": "Draft a reviewable encryption plan at .cipherstash/plan.md", - "examples": ["plan", "plan --target claude-code"], + "examples": [ + "plan", + "plan --target claude-code", + "plan --complete-rollout --yes --target claude-code" + ], "flags": [ { "name": "--complete-rollout", - "description": "Plan the entire encryption lifecycle (schema-add through drop) in one document. Skips the production-deploy gate; only safe when this database is not backing a deployed application." + "description": "Plan the entire encryption lifecycle (schema-add through drop) in one document. Skips the production-deploy gate; only safe when this database is not backing a deployed application. Needs confirmation — an interactive prompt, or --yes non-interactively (else it exits non-zero without drafting)." + }, + { + "name": "--yes", + "description": "Confirm --complete-rollout's gate-skip without a prompt (for automation / CI). No effect without --complete-rollout." }, { "name": "--target", @@ -118,6 +117,16 @@ "description": "Emit the structured JSON manifest instead of a text list." } ] + }, + { + "name": "telemetry", + "summary": "Manage anonymous usage analytics", + "long": "Manage the anonymous, opt-out usage analytics the CLI collects to\nimprove the tool. `status` (the default) reports whether telemetry is\non and which setting governs it; `enable` / `disable` write your saved\npreference. Telemetry is also disabled by the DO_NOT_TRACK or\nSTASH_TELEMETRY_DISABLED environment variables and automatically in CI.\nNo plaintext, schema, table/column names, or connection details are\never collected. See https://cipherstash.com/docs/reference/cli.", + "examples": [ + "telemetry status", + "telemetry disable", + "telemetry enable" + ] } ] }, @@ -156,6 +165,10 @@ { "name": "--drizzle", "description": "Track Drizzle as the referrer." + }, + { + "name": "--prisma", + "description": "Track Prisma as the referrer." } ] }, @@ -191,52 +204,82 @@ "name": "--supabase", "description": "Use Supabase-compatible mode (auto-detected from DATABASE_URL)." }, + { + "name": "--database-url", + "value": "", + "description": "Database URL for this run only — never written to disk. Highest precedence in the resolution order: --database-url flag → DATABASE_URL env → supabase status → interactive prompt. A stash.config.ts is not a separate tier (its default databaseUrl re-runs this same chain); a hand-set literal databaseUrl in the config bypasses the resolver and wins over all of these.", + "env": "DATABASE_URL" + } + ] + }, + { + "name": "eql migration", + "summary": "Generate an EQL v3 install migration for your ORM (Drizzle; Prisma Next installs EQL through its own migrations)", + "examples": [ + "eql migration --drizzle", + "eql migration --drizzle --supabase" + ], + "flags": [ { "name": "--drizzle", - "description": "Generate a Drizzle migration instead of direct install (auto-detected from project)." + "description": "Emit a Drizzle custom migration containing the EQL v3 install SQL." }, { - "name": "--migration", - "description": "Write a Supabase migration file instead of running SQL directly (requires --supabase)." + "name": "--prisma", + "description": "Not needed: Prisma Next installs EQL through its own migration framework — run `prisma-next migrate` instead." }, { - "name": "--direct", - "description": "Run the SQL directly against the database (requires --supabase; mutually exclusive with --migration)." + "name": "--supabase", + "description": "Append the Supabase role grants (eql_v3 + eql_v3_internal for anon/authenticated/service_role)." }, { - "name": "--migrations-dir", - "value": "", - "description": "Override the Supabase migrations directory (requires --supabase).", - "default": "supabase/migrations" + "name": "--name", + "value": "", + "description": "Name for the generated migration (Drizzle). Letters, numbers, dashes, underscores only. Defaults to `install-eql`." }, { - "name": "--exclude-operator-family", - "description": "Skip operator family creation." + "name": "--out", + "value": "", + "description": "Directory drizzle-kit writes the migration into (passed to `drizzle-kit generate --out`). Defaults to `drizzle`; set it to match your drizzle.config.ts." }, { - "name": "--eql-version", - "value": "<2|3>", - "description": "EQL generation to target. v3 is the native eql_v3.* domain schema (direct install only for now).", - "default": "2" + "name": "--dry-run", + "description": "Show what would happen without making changes." + } + ] + }, + { + "name": "eql repair", + "summary": "Repair migrations drizzle-kit generated with an un-runnable ALTER COLUMN to an encrypted type", + "long": "Sweep an existing Drizzle output directory for in-place\n`ALTER COLUMN ... SET DATA TYPE ` statements — which cannot run,\nbecause Postgres has no cast from text/numeric to an EQL domain — and rewrite\neach into an additive encrypted column that preserves the source column.\n\nThis is the same sweep `eql migration --drizzle` runs, without having to\ngenerate an EQL install migration you do not want just to trigger it.\n\nMigrations the database has already applied are reported and left alone:\nrewriting one would leave its .sql describing a shape that database never got\nfrom it, so a fresh CI or staging database replaying the file would silently\ndiverge. Pass --database-url so that check can run; without it the repair\nproceeds and warns that applied state could not be verified. If your\ndrizzle.config.ts overrides `migrations.table` / `migrations.schema`, name\nthe ledger with --migrations-table — otherwise the check queries the default\nrelation, finds nothing, and reports applied state as unverified.", + "examples": [ + "eql repair --drizzle", + "eql repair --drizzle --dry-run", + "eql repair --drizzle --out db/migrations --database-url postgres://…" + ], + "flags": [ + { + "name": "--drizzle", + "description": "Repair a Drizzle migration directory." }, { - "name": "--latest", - "description": "Fetch the latest EQL from GitHub (v2 only)." + "name": "--out", + "value": "", + "description": "Directory holding the migrations to sweep. Defaults to `drizzle`; set it to match your drizzle.config.ts." }, { - "name": "--name", - "value": "", - "description": "With --drizzle: name for the generated migration (defaults to a scaffold name)." + "name": "--migrations-table", + "value": "<[schema.]table>", + "description": "Drizzle's migration ledger, when drizzle.config.ts overrides `migrations.table` / `migrations.schema`. Defaults to `drizzle.__drizzle_migrations`. Only read with --database-url." }, { - "name": "--out", - "value": "", - "description": "With --drizzle: directory to write the generated migration into." + "name": "--dry-run", + "description": "Show what would happen without making changes." }, { "name": "--database-url", "value": "", - "description": "Override DATABASE_URL for this run only — never written to disk.", + "description": "Database URL for this run only — never written to disk. Highest precedence in the resolution order: --database-url flag → DATABASE_URL env → supabase status → interactive prompt. A stash.config.ts is not a separate tier (its default databaseUrl re-runs this same chain); a hand-set literal databaseUrl in the config bypasses the resolver and wins over all of these.", "env": "DATABASE_URL" } ] @@ -253,24 +296,10 @@ "name": "--supabase", "description": "Use Supabase-compatible mode." }, - { - "name": "--exclude-operator-family", - "description": "Skip operator family creation." - }, - { - "name": "--eql-version", - "value": "<2|3>", - "description": "EQL generation to target.", - "default": "2" - }, - { - "name": "--latest", - "description": "Fetch the latest EQL from GitHub (v2 only)." - }, { "name": "--database-url", "value": "", - "description": "Override DATABASE_URL for this run only — never written to disk.", + "description": "Database URL for this run only — never written to disk. Highest precedence in the resolution order: --database-url flag → DATABASE_URL env → supabase status → interactive prompt. A stash.config.ts is not a separate tier (its default databaseUrl re-runs this same chain); a hand-set literal databaseUrl in the config bypasses the resolver and wins over all of these.", "env": "DATABASE_URL" } ] @@ -282,7 +311,7 @@ { "name": "--database-url", "value": "", - "description": "Override DATABASE_URL for this run only — never written to disk.", + "description": "Database URL for this run only — never written to disk. Highest precedence in the resolution order: --database-url flag → DATABASE_URL env → supabase status → interactive prompt. A stash.config.ts is not a separate tier (its default databaseUrl re-runs this same chain); a hand-set literal databaseUrl in the config bypasses the resolver and wins over all of these.", "env": "DATABASE_URL" } ] @@ -292,34 +321,6 @@ { "title": "Database", "commands": [ - { - "name": "db push", - "summary": "Push encryption schema (writes pending if active config already exists)", - "flags": [ - { - "name": "--dry-run", - "description": "Show what would happen without making changes." - }, - { - "name": "--database-url", - "value": "", - "description": "Override DATABASE_URL for this run only — never written to disk.", - "env": "DATABASE_URL" - } - ] - }, - { - "name": "db activate", - "summary": "Promote pending → active without renames (use after additive db push)", - "flags": [ - { - "name": "--database-url", - "value": "", - "description": "Override DATABASE_URL for this run only — never written to disk.", - "env": "DATABASE_URL" - } - ] - }, { "name": "db validate", "summary": "Validate encryption schema", @@ -335,7 +336,7 @@ { "name": "--database-url", "value": "", - "description": "Override DATABASE_URL for this run only — never written to disk.", + "description": "Database URL for this run only — never written to disk. Highest precedence in the resolution order: --database-url flag → DATABASE_URL env → supabase status → interactive prompt. A stash.config.ts is not a separate tier (its default databaseUrl re-runs this same chain); a hand-set literal databaseUrl in the config bypasses the resolver and wins over all of these.", "env": "DATABASE_URL" } ] @@ -351,7 +352,7 @@ { "name": "--database-url", "value": "", - "description": "Override DATABASE_URL for this run only — never written to disk.", + "description": "Database URL for this run only — never written to disk. Highest precedence in the resolution order: --database-url flag → DATABASE_URL env → supabase status → interactive prompt. A stash.config.ts is not a separate tier (its default databaseUrl re-runs this same chain); a hand-set literal databaseUrl in the config bypasses the resolver and wins over all of these.", "env": "DATABASE_URL" } ] @@ -372,7 +373,7 @@ { "name": "--database-url", "value": "", - "description": "Override DATABASE_URL for this run only — never written to disk.", + "description": "Database URL for this run only — never written to disk. Highest precedence in the resolution order: --database-url flag → DATABASE_URL env → supabase status → interactive prompt. A stash.config.ts is not a separate tier (its default databaseUrl re-runs this same chain); a hand-set literal databaseUrl in the config bypasses the resolver and wins over all of these.", "env": "DATABASE_URL" } ] @@ -434,32 +435,6 @@ } ] }, - { - "name": "encrypt cutover", - "summary": "Rename swap encrypted → primary column", - "flags": [ - { - "name": "--table", - "value": "", - "description": "Target table." - }, - { - "name": "--column", - "value": "", - "description": "Target column." - }, - { - "name": "--proxy-url", - "value": "", - "description": "Proxy URL to verify against." - }, - { - "name": "--migrations-dir", - "value": "", - "description": "Directory to write the rename migration into." - } - ] - }, { "name": "encrypt drop", "summary": "Generate a migration to drop the plaintext column", @@ -484,15 +459,32 @@ ] }, { - "title": "Experimental", + "title": "Deployment", "commands": [ { "name": "env", - "summary": "(experimental) Print production env vars for deployment", + "summary": "Mint deployment credentials and print them as env vars", + "long": "Mints a fresh ZeroKMS client and a CipherStash access key from your\ndevice-code session (`stash auth login`), then prints the four env\nvars a deployed app needs: CS_WORKSPACE_CRN, CS_CLIENT_ID,\nCS_CLIENT_KEY, CS_CLIENT_ACCESS_KEY.\n\nThe access key is created with the member role (the CLI never mints\nadmin keys) and is shown exactly once — pipe the output into your\ndeployment secret store. Creating access keys requires your user to\nhave the admin role in the workspace.\n\nStdout carries only the dotenv block (or the --json events);\nprogress UI goes to stderr, so `stash env --name x > prod.env`\nand pipes into secret stores are safe.", + "examples": [ + "env --name my-app-prod", + "env --name my-app-prod --write", + "env --name staging --write .env.staging.local", + "env --name edge-dev --json" + ], "flags": [ + { + "name": "--name", + "value": "", + "description": "Name for the minted access key and ZeroKMS client. Prompted for interactively; required in non-interactive runs." + }, { "name": "--write", - "description": "Write the vars to a file instead of printing them." + "value": "[path]", + "description": "Write the vars to a file (default .env.production.local, mode 0600) instead of printing them. An existing file prompts before overwriting — and is refused non-interactively — before anything is minted." + }, + { + "name": "--json", + "description": "Emit machine-readable NDJSON (a { status: \"minted\" } object, or { status: \"written\" } with --write — deliberately secret-free since the secrets are in the file; failures are { status: \"error\" }). Implies no prompts." } ] } diff --git a/scripts/generate-cli-docs.ts b/scripts/generate-cli-docs.ts index 05bffbe..3a017fc 100644 --- a/scripts/generate-cli-docs.ts +++ b/scripts/generate-cli-docs.ts @@ -82,6 +82,7 @@ interface Command { sub?: string; // "install" group: string; // nav group title, from the manifest summary: string; + long?: string; flags: Flag[]; examples: string[]; } @@ -177,6 +178,7 @@ function toManifest(m: CliManifest): Manifest { sub: rest.length ? rest.join(" ") : undefined, group: group.title, summary: c.summary, + long: c.long, flags: (c.flags ?? []).map(mapFlag), examples: (c.examples ?? []).map((e) => `${RUNNER} ${CLI_NAME} ${e}`), }); @@ -199,15 +201,21 @@ Generated from **\`${CLI_NAME}\` v${CLI_VERSION}** via \`${RUNNER} ${CLI_NAME}@$ // e.g. the `auth regions` flag description "[{ slug, label }]" would otherwise // evaluate `slug` and crash the prerender) and stray `<` (tags). Flag names and // values render inside code spans, which are literal, so this only applies to -// manifest-derived prose (descriptions, summaries). -const escapeMdxText = (s: string): string => s.replace(/([{}<])/g, "\\$1"); +// manifest-derived prose (descriptions, summaries, and long help). +const escapeMdxText = (s: string): string => + s + .split(/(`[^`\n]*`)/g) + .map((part) => + part.startsWith("`") ? part : part.replace(/([{}<])/g, "\\$1"), + ) + .join(""); function flagsTable(flags: Flag[]): string { if (!flags.length) return ""; const rows = flags .map((f) => { - // Escape pipes (e.g. the `<2|3>` in `--eql-version`) so they don't read - // as table-column separators, even inside the code span. + // Escape pipes in option values so they don't read as table-column + // separators, even inside the code span. const opt = `\`${f.name}${f.value ? ` ${f.value}` : ""}\``.replace( /\|/g, "\\|", @@ -224,7 +232,7 @@ function commandSection(cmd: Command, level: "##" | "###"): string { const parts = [ `${level} \`${cmd.path}\``, "", - escapeMdxText(cmd.summary), + escapeMdxText(cmd.long ?? cmd.summary), "", "```bash", synopsis, @@ -276,7 +284,7 @@ function renderPage( } else { const c = cmds[0]; parts.push( - escapeMdxText(c.summary), + escapeMdxText(c.long ?? c.summary), "", "```bash", `${RUNNER} ${CLI_NAME} ${c.path}${c.flags.length ? " [flags]" : ""}`, diff --git a/scripts/generate-docs.ts b/scripts/generate-docs.ts index 98d2c45..fb0d205 100644 --- a/scripts/generate-docs.ts +++ b/scripts/generate-docs.ts @@ -16,7 +16,7 @@ const stackConfig: DocsConfig = { packageName: "@cipherstash/stack", projectName: "@cipherstash/stack", repoUrl: "https://github.com/cipherstash/stack.git", - sourceRef: "main", + sourceRef: "@cipherstash/stack@1.0.0", tempDirName: ".tmp-stack", baseOutputDir: path.join( process.cwd(), diff --git a/scripts/generate-drizzle-docs.ts b/scripts/generate-drizzle-docs.ts index a66af22..37498e1 100644 --- a/scripts/generate-drizzle-docs.ts +++ b/scripts/generate-drizzle-docs.ts @@ -1,5 +1,5 @@ #!/usr/bin/env tsx -/** Generate the Drizzle ORM integration's API reference from Stack main. */ +/** Generate the Drizzle integration's API reference from its Stack 1.0 tag. */ import path from "node:path"; import { type DocsConfig, generateDocs } from "./lib/docs-generator.js"; @@ -7,7 +7,7 @@ const drizzleConfig: DocsConfig = { packageName: "@cipherstash/stack-drizzle", projectName: "@cipherstash/stack-drizzle", repoUrl: "https://github.com/cipherstash/stack.git", - sourceRef: "main", + sourceRef: "@cipherstash/stack-drizzle@1.0.0", tempDirName: ".tmp-stack-drizzle", baseOutputDir: path.join( process.cwd(), diff --git a/scripts/generate-prisma-docs.ts b/scripts/generate-prisma-docs.ts index 9675aa4..f9f8618 100644 --- a/scripts/generate-prisma-docs.ts +++ b/scripts/generate-prisma-docs.ts @@ -1,5 +1,5 @@ #!/usr/bin/env tsx -/** Generate the Prisma ORM integration's API reference from Stack main. */ +/** Generate the Prisma integration's API reference from its Stack 1.0 tag. */ import path from "node:path"; import { type DocsConfig, generateDocs } from "./lib/docs-generator.js"; @@ -7,7 +7,7 @@ const prismaConfig: DocsConfig = { packageName: "@cipherstash/stack-prisma", projectName: "@cipherstash/stack-prisma", repoUrl: "https://github.com/cipherstash/stack.git", - sourceRef: "main", + sourceRef: "@cipherstash/stack-prisma@1.0.0", tempDirName: ".tmp-stack-prisma", baseOutputDir: path.join( process.cwd(), diff --git a/scripts/generate-supabase-docs.ts b/scripts/generate-supabase-docs.ts index a25c917..175bcd9 100644 --- a/scripts/generate-supabase-docs.ts +++ b/scripts/generate-supabase-docs.ts @@ -1,5 +1,5 @@ #!/usr/bin/env tsx -/** Generate the Supabase integration's API reference from Stack main. */ +/** Generate the Supabase integration's API reference from its Stack 1.0 tag. */ import path from "node:path"; import { type DocsConfig, generateDocs } from "./lib/docs-generator.js"; @@ -7,7 +7,7 @@ const supabaseConfig: DocsConfig = { packageName: "@cipherstash/stack-supabase", projectName: "@cipherstash/stack-supabase", repoUrl: "https://github.com/cipherstash/stack.git", - sourceRef: "main", + sourceRef: "@cipherstash/stack-supabase@1.0.0", tempDirName: ".tmp-stack-supabase", baseOutputDir: path.join( process.cwd(),