diff --git a/.changeset/breezy-cloths-wave.md b/.changeset/breezy-cloths-wave.md new file mode 100644 index 00000000..c1f34d00 --- /dev/null +++ b/.changeset/breezy-cloths-wave.md @@ -0,0 +1,28 @@ +--- +"stash": minor +"@cipherstash/wizard": patch +--- + +Rename the CLI package from `@cipherstash/cli` to `stash`. The published code, commands, and flags are unchanged — this is a pure rename so the day-to-day invocation drops from `npx @cipherstash/cli ...` to `npx stash ...`. + +**Migration** + +1. Update your `package.json` devDependencies: + + ```diff + - "@cipherstash/cli": "^0.10.0" + + "stash": "^0.10.1" + ``` + +2. Update the `defineConfig` import in `stash.config.ts`: + + ```diff + - import { defineConfig } from '@cipherstash/cli' + + import { defineConfig } from 'stash' + ``` + +3. Update any `npx @cipherstash/cli ...` / `bunx @cipherstash/cli ...` / `pnpm dlx @cipherstash/cli ...` / `yarn dlx @cipherstash/cli ...` invocations in scripts, CI, READMEs, and team docs to use `stash` instead. Programmatic exports (`defineConfig`, `loadStashConfig`, `EQLInstaller`, `loadBundledEqlSql`, `downloadEqlSql`, `PermissionCheckResult`) are re-exported from `stash` with the same shapes. + +**Wizard impact (`@cipherstash/wizard`)** + +The wizard's post-agent step and its prerequisite / agent-error hints now reference `stash` (e.g. `Run: bunx stash auth login`, `Running bunx stash db install...`) rather than `@cipherstash/cli`. The wizard package name and `stash-wizard` binary are unchanged — only the strings the wizard prints and the commands it shells out to are affected. diff --git a/.changeset/cli-database-url-resolution.md b/.changeset/cli-database-url-resolution.md index 4c01fa06..673afbcc 100644 --- a/.changeset/cli-database-url-resolution.md +++ b/.changeset/cli-database-url-resolution.md @@ -1,5 +1,5 @@ --- -'@cipherstash/cli': minor +'stash': minor --- Layered `DATABASE_URL` resolution for DB / schema commands. @@ -16,7 +16,7 @@ if `DATABASE_URL` wasn't already in the environment. The CLI auto-loaded `.env.l The scaffolded `stash.config.ts` now calls a resolver directly: ```ts -import { defineConfig, resolveDatabaseUrl } from '@cipherstash/cli' +import { defineConfig, resolveDatabaseUrl } from 'stash' export default defineConfig({ databaseUrl: await resolveDatabaseUrl(), diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7ef66e8f..f475542b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -86,7 +86,7 @@ jobs: # pseudo-terminal via node-pty. Run via turbo so the `^build` + `build` # deps declared on the `test:e2e` task are honored. - name: Run CLI E2E tests - run: pnpm exec turbo run test:e2e --filter @cipherstash/cli + run: pnpm exec turbo run test:e2e --filter stash e2e-tests: name: Run E2E Tests diff --git a/AGENTS.md b/AGENTS.md index d51eb7da..60a4c75f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -142,7 +142,7 @@ pnpm changeset:publish - Prefer testing via the public API. Avoid reaching into private internals. - Some tests have larger timeouts (e.g., 30s) to accommodate network calls. - `packages/cli` has a second suite — pty-driven E2E tests under - `packages/cli/tests/e2e/**` run via `pnpm --filter @cipherstash/cli + `packages/cli/tests/e2e/**` run via `pnpm --filter stash test:e2e` (requires a build). See `packages/cli/AGENTS.md` for when to add or update them. diff --git a/docs/plans/cli-pty-integration-tests.md b/docs/plans/cli-pty-integration-tests.md index cd2c65b6..ec3d1b08 100644 --- a/docs/plans/cli-pty-integration-tests.md +++ b/docs/plans/cli-pty-integration-tests.md @@ -1,4 +1,4 @@ -# Plan: node-pty Integration Tests for `@cipherstash/cli` +# Plan: node-pty Integration Tests for `stash` ## Goal @@ -75,7 +75,7 @@ harness is proven. 7. `turbo.json` task `test:e2e` with `dependsOn: ["^build", "build"]` so the CLI is rebuilt before E2E runs. Keep `cache: false`. 8. CI: extend the existing test workflow to also run `pnpm --filter - @cipherstash/cli test:e2e`. Confirm the prebuilt binary resolves on + stash test:e2e`. Confirm the prebuilt binary resolves on the GH runners (Linux x64, macOS arm64). If it doesn't, fall back to upstream `node-pty` and add `python3` / build tools to the workflow. @@ -182,7 +182,7 @@ export const messages = { }, db: { migrateNotImplemented: - '"npx @cipherstash/cli db migrate" is not yet implemented.', + '"npx stash db migrate" is not yet implemented.', }, } as const ``` diff --git a/e2e/package.json b/e2e/package.json index cb612264..f3b5c0d8 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -8,7 +8,7 @@ "test:e2e": "vitest run" }, "dependencies": { - "@cipherstash/cli": "workspace:*", + "stash": "workspace:*", "@cipherstash/wizard": "workspace:*" }, "devDependencies": { diff --git a/e2e/tests/package-managers.e2e.test.ts b/e2e/tests/package-managers.e2e.test.ts index a25d5860..0aee50b0 100644 --- a/e2e/tests/package-managers.e2e.test.ts +++ b/e2e/tests/package-managers.e2e.test.ts @@ -35,19 +35,19 @@ describe('CLI init providers — package-manager-aware Next Steps', () => { label: 'base', create: createBaseProvider, firstStep: (r) => - `Set up your database: ${r} @cipherstash/cli db install`, + `Set up your database: ${r} stash db install`, }, { label: 'drizzle', create: createDrizzleProvider, firstStep: (r) => - `Set up your database: ${r} @cipherstash/cli db install --drizzle`, + `Set up your database: ${r} stash db install --drizzle`, }, { label: 'supabase', create: createSupabaseProvider, firstStep: (r) => - `Install EQL: ${r} @cipherstash/cli db install --supabase (prompts for migration vs direct)`, + `Install EQL: ${r} stash db install --supabase (prompts for migration vs direct)`, }, ] @@ -141,12 +141,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]} @cipherstash/cli db install`) + expect(out).toContain(`Run: ${RUNNER[pm]} stash db install`) }) it('falls back to npx when no lockfile and no user agent', () => { const out = runWizard({}) - expect(out).toContain('Run: npx @cipherstash/cli db install') + expect(out).toContain('Run: npx stash db install') }) }) @@ -157,7 +157,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]} @cipherstash/cli db install`) + expect(out).toContain(`Run: ${RUNNER[pm]} stash db install`) }) }) @@ -167,7 +167,7 @@ describe.skipIf(!authConfigured)( lockfile: 'pnpm-lock.yaml', userAgent: 'bun/1.1.40 npm/? node/v22.3.0', }) - expect(out).toContain('Run: bunx @cipherstash/cli db install') + expect(out).toContain('Run: bunx stash db install') }) it('npm user agent is ignored in favour of a lockfile', () => { @@ -175,7 +175,7 @@ describe.skipIf(!authConfigured)( lockfile: 'bun.lock', userAgent: 'npm/10.2.4 node/v20.0.0', }) - expect(out).toContain('Run: bunx @cipherstash/cli db install') + expect(out).toContain('Run: bunx stash db install') }) }) }, diff --git a/examples/basic/package.json b/examples/basic/package.json index 2463f205..423840ee 100644 --- a/examples/basic/package.json +++ b/examples/basic/package.json @@ -16,7 +16,7 @@ "pg": "8.13.1" }, "devDependencies": { - "@cipherstash/cli": "workspace:*", + "stash": "workspace:*", "tsx": "catalog:repo", "typescript": "catalog:repo" } diff --git a/examples/basic/stash.config.ts b/examples/basic/stash.config.ts index e57bab2a..b95f3d6e 100644 --- a/examples/basic/stash.config.ts +++ b/examples/basic/stash.config.ts @@ -1,4 +1,4 @@ -import { defineConfig } from '@cipherstash/cli' +import { defineConfig } from 'stash' export default defineConfig({ databaseUrl: process.env.DATABASE_URL!, diff --git a/packages/cli/AGENTS.md b/packages/cli/AGENTS.md index 0a358728..5efd2a7b 100644 --- a/packages/cli/AGENTS.md +++ b/packages/cli/AGENTS.md @@ -1,4 +1,4 @@ -# `@cipherstash/cli` — agent notes +# `stash` — agent notes ## Two test suites @@ -6,8 +6,8 @@ This package has **two** Vitest configs. Run the right one for the change. | Command | Config | Scope | Needs build? | | --- | --- | --- | --- | -| `pnpm --filter @cipherstash/cli test` | `vitest.config.ts` | Unit tests under `src/__tests__/**` and `src/**/__tests__/**` | No | -| `pnpm --filter @cipherstash/cli test:e2e` | `vitest.integration.config.ts` | E2E tests under `tests/e2e/**.e2e.test.ts` driving the built `dist/bin/stash.js` through a real pty (`node-pty`) | **Yes** — run `pnpm --filter @cipherstash/cli build` first, or use the turbo `test:e2e` task which depends on `build`. | +| `pnpm --filter stash test` | `vitest.config.ts` | Unit tests under `src/__tests__/**` and `src/**/__tests__/**` | No | +| `pnpm --filter stash test:e2e` | `vitest.integration.config.ts` | E2E tests under `tests/e2e/**.e2e.test.ts` driving the built `dist/bin/stash.js` through a real pty (`node-pty`) | **Yes** — run `pnpm --filter stash build` first, or use the turbo `test:e2e` task which depends on `build`. | The unit config explicitly excludes `tests/e2e/**` so the default `pnpm test` stays fast and self-contained. diff --git a/packages/cli/README.md b/packages/cli/README.md index 76259f72..913172b7 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -1,7 +1,7 @@ -# @cipherstash/cli +# stash -[![npm version](https://img.shields.io/npm/v/@cipherstash/cli.svg?style=for-the-badge&labelColor=000000)](https://www.npmjs.com/package/@cipherstash/cli) -[![License: MIT](https://img.shields.io/npm/l/@cipherstash/cli.svg?style=for-the-badge&labelColor=000000)](https://github.com/cipherstash/protectjs/blob/main/LICENSE.md) +[![npm version](https://img.shields.io/npm/v/stash.svg?style=for-the-badge&labelColor=000000)](https://www.npmjs.com/package/stash) +[![License: MIT](https://img.shields.io/npm/l/stash.svg?style=for-the-badge&labelColor=000000)](https://github.com/cipherstash/protectjs/blob/main/LICENSE.md) The single CLI for CipherStash. It handles authentication, project initialization, EQL database lifecycle (install, upgrade, validate, push, migrate), schema building, and encrypted secrets management. Install it as a devDependency alongside the runtime SDK `@cipherstash/stack`. @@ -10,16 +10,16 @@ The single CLI for CipherStash. It handles authentication, project initializatio ## Quickstart ```bash -npm install -D @cipherstash/cli -npx @cipherstash/cli auth login # authenticate with CipherStash -npx @cipherstash/cli init # scaffold encryption schema and install dependencies -npx @cipherstash/cli db install # scaffold stash.config.ts (if missing) and install EQL +npm install -D stash +npx stash auth login # authenticate with CipherStash +npx stash init # scaffold encryption schema and install dependencies +npx stash db install # scaffold stash.config.ts (if missing) and install EQL ``` What each step does: - `auth login` — opens a browser-based device code flow and saves a token to `~/.cipherstash/auth.json`. -- `init` — generates your encryption client file and installs `@cipherstash/cli` as a dev dependency. Pass `--supabase` or `--drizzle` for provider-specific setup. +- `init` — generates your encryption client file and installs `stash` as a dev dependency. Pass `--supabase` or `--drizzle` for provider-specific setup. - `db install` — detects your encryption client, writes `stash.config.ts` if it's missing, and installs EQL extensions in a single step. After `db install`, declare which columns to encrypt — either run [`@cipherstash/wizard`](https://www.npmjs.com/package/@cipherstash/wizard) to do it automatically, or edit your encryption client file (default `./src/encryption/index.ts`) by hand. @@ -29,15 +29,15 @@ After `db install`, declare which columns to encrypt — either run [`@ciphersta ## Recommended flow ``` -npx @cipherstash/cli auth login - └── npx @cipherstash/cli init - └── npx @cipherstash/cli db install +npx stash auth login + └── npx stash init + └── npx stash db install └── npx @cipherstash/wizard ← fast path: AI edits your files OR Edit schema files by hand ← escape hatch ``` -`@cipherstash/cli` covers authentication, initialization, EQL install/upgrade/validate/push/migrate, and schema introspection. The wizard ([`@cipherstash/wizard`](https://www.npmjs.com/package/@cipherstash/wizard)) is a separate package that calls back into these cli commands after its AI agent finishes editing your schema files. +`stash` covers authentication, initialization, EQL install/upgrade/validate/push/migrate, and schema introspection. The wizard ([`@cipherstash/wizard`](https://www.npmjs.com/package/@cipherstash/wizard)) is a separate package that calls back into these cli commands after its AI agent finishes editing your schema files. --- @@ -46,7 +46,7 @@ npx @cipherstash/cli auth login `stash.config.ts` is the single source of truth for database-touching commands. Create it in your project root: ```typescript filename="stash.config.ts" -import { defineConfig } from '@cipherstash/cli' +import { defineConfig } from 'stash' export default defineConfig({ databaseUrl: process.env.DATABASE_URL!, @@ -67,12 +67,12 @@ Commands that consume `stash.config.ts`: `db install`, `db upgrade`, `db push`, ## Commands reference -### `npx @cipherstash/cli init` +### `npx stash init` -Scaffold CipherStash for your project. Generates an encryption client file, writes initial schema code, and installs `@cipherstash/cli` as a dev dependency. +Scaffold CipherStash for your project. Generates an encryption client file, writes initial schema code, and installs `stash` as a dev dependency. ```bash -npx @cipherstash/cli init [--supabase] [--drizzle] +npx stash init [--supabase] [--drizzle] ``` | Flag | Description | @@ -80,28 +80,28 @@ npx @cipherstash/cli init [--supabase] [--drizzle] | `--supabase` | Use the Supabase-specific setup flow | | `--drizzle` | Use the Drizzle-specific setup flow | -After `init` completes, the Next Steps output tells you to run `npx @cipherstash/cli db install`, then edit your encryption client file directly. +After `init` completes, the Next Steps output tells you to run `npx stash db install`, then edit your encryption client file directly. --- -### `npx @cipherstash/cli auth login` +### `npx stash auth login` Authenticate with CipherStash using a browser-based device code flow. ```bash -npx @cipherstash/cli auth login +npx stash auth login ``` Saves the token to `~/.cipherstash/auth.json`. Database-touching commands check for this file before running. --- -### `npx @cipherstash/cli secrets` +### `npx stash secrets` Manage end-to-end encrypted secrets. ```bash -npx @cipherstash/cli secrets [options] +npx stash secrets [options] ``` | Subcommand | Description | @@ -124,23 +124,23 @@ npx @cipherstash/cli secrets [options] **Examples:** ```bash -npx @cipherstash/cli secrets set -n DATABASE_URL -V "postgres://..." -e production -npx @cipherstash/cli secrets get -n DATABASE_URL -e production -npx @cipherstash/cli secrets get-many -n DATABASE_URL,API_KEY -e production -npx @cipherstash/cli secrets list -e production -npx @cipherstash/cli secrets delete -n DATABASE_URL -e production -y +npx stash secrets set -n DATABASE_URL -V "postgres://..." -e production +npx stash secrets get -n DATABASE_URL -e production +npx stash secrets get-many -n DATABASE_URL,API_KEY -e production +npx stash secrets list -e production +npx stash secrets delete -n DATABASE_URL -e production -y ``` --- -### `npx @cipherstash/cli db install` +### `npx stash db install` -Configure your database and install CipherStash EQL extensions in a single command. Run this after `npx @cipherstash/cli init`. +Configure your database and install CipherStash EQL extensions in a single command. Run this after `npx stash init`. 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 @cipherstash/cli db install [options] +npx stash db install [options] ``` | Flag | Description | @@ -160,12 +160,12 @@ The `--supabase` flag uses a Supabase-specific SQL variant and grants `USAGE`, t --- -### `npx @cipherstash/cli db upgrade` +### `npx stash db upgrade` Upgrade an existing EQL installation to the version bundled with the package (or the latest from GitHub). ```bash -npx @cipherstash/cli db upgrade [options] +npx stash db upgrade [options] ``` | Flag | Description | @@ -175,16 +175,16 @@ npx @cipherstash/cli 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 @cipherstash/cli db install` instead. +The install SQL is idempotent and safe to re-run. If EQL is not installed, the command suggests running `npx stash db install` instead. --- -### `npx @cipherstash/cli db push` +### `npx stash db push` Push your encryption schema to the database. **Only required when using CipherStash Proxy.** If you use the SDK directly with Drizzle, Supabase, or plain PostgreSQL, skip this step. ```bash -npx @cipherstash/cli db push [--dry-run] +npx stash db push [--dry-run] ``` | Flag | Description | @@ -206,12 +206,12 @@ When pushing, the CLI loads the encryption client from `stash.config.ts`, runs s --- -### `npx @cipherstash/cli db validate` +### `npx stash db validate` Validate your encryption schema for common misconfigurations. ```bash -npx @cipherstash/cli db validate [--supabase] [--exclude-operator-family] +npx stash db validate [--supabase] [--exclude-operator-family] ``` | Rule | Severity | @@ -225,48 +225,48 @@ The command exits with code 1 on errors (not on warnings or info). Validation al --- -### `npx @cipherstash/cli db migrate` +### `npx stash db migrate` Run pending encrypt config migrations. ```bash -npx @cipherstash/cli db migrate +npx stash db migrate ``` > **Good to know:** This command is not yet implemented. --- -### `npx @cipherstash/cli db status` +### `npx stash db status` Show the current state of EQL in your database. ```bash -npx @cipherstash/cli db status +npx stash db 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). --- -### `npx @cipherstash/cli db test-connection` +### `npx stash db test-connection` Verify that the database URL in your config is valid and the database is reachable. ```bash -npx @cipherstash/cli db test-connection +npx stash db test-connection ``` Reports the database name, connected role, and PostgreSQL server version. --- -### `npx @cipherstash/cli schema build` +### `npx stash schema build` Build an encryption client file from your database schema using DB introspection. ```bash -npx @cipherstash/cli schema build [--supabase] +npx stash schema build [--supabase] ``` Connects to your database, lets you select tables and columns to encrypt, asks about searchable indexes, and generates a typed encryption client file. @@ -277,10 +277,10 @@ Reads `databaseUrl` from `stash.config.ts`. ## Drizzle migration mode -Use `--drizzle` with `npx @cipherstash/cli 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 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. ```bash -npx @cipherstash/cli db install --drizzle +npx stash db install --drizzle npx drizzle-kit migrate ``` @@ -292,7 +292,7 @@ How it works: With a custom name or output directory: ```bash -npx @cipherstash/cli db install --drizzle --name setup-eql --out ./migrations +npx stash db install --drizzle --name setup-eql --out ./migrations npx drizzle-kit migrate ``` @@ -321,7 +321,7 @@ import { EQLInstaller, loadBundledEqlSql, downloadEqlSql, -} from '@cipherstash/cli' +} from 'stash' ``` ### `defineConfig` @@ -329,7 +329,7 @@ import { Type-safe identity function for `stash.config.ts`: ```typescript filename="stash.config.ts" -import { defineConfig } from '@cipherstash/cli' +import { defineConfig } from 'stash' export default defineConfig({ databaseUrl: process.env.DATABASE_URL!, @@ -342,7 +342,7 @@ export default defineConfig({ Finds and loads the nearest `stash.config.ts`, validates it with Zod, applies defaults, and returns the typed config: ```typescript -import { loadStashConfig } from '@cipherstash/cli' +import { loadStashConfig } from 'stash' const config = await loadStashConfig() // config.databaseUrl — validated non-empty string @@ -354,7 +354,7 @@ const config = await loadStashConfig() Programmatic access to EQL installation: ```typescript -import { EQLInstaller } from '@cipherstash/cli' +import { EQLInstaller } from 'stash' const installer = new EQLInstaller({ databaseUrl: process.env.DATABASE_URL! }) @@ -383,7 +383,7 @@ Install options: `excludeOperatorFamily`, `supabase`, `latest` (all boolean). Load the bundled EQL install SQL as a string: ```typescript -import { loadBundledEqlSql } from '@cipherstash/cli' +import { loadBundledEqlSql } from 'stash' const sql = loadBundledEqlSql() const sql = loadBundledEqlSql({ supabase: true }) @@ -395,7 +395,7 @@ const sql = loadBundledEqlSql({ excludeOperatorFamily: true }) Download the latest EQL install SQL from GitHub: ```typescript -import { downloadEqlSql } from '@cipherstash/cli' +import { downloadEqlSql } from 'stash' const sql = await downloadEqlSql() // standard const sql = await downloadEqlSql(true) // no operator family variant @@ -405,7 +405,7 @@ const sql = await downloadEqlSql(true) // no operator family variant ## Relationship to `@cipherstash/stack` -`@cipherstash/stack` is the runtime SDK. It stays lean with no heavy dependencies like `pg` and ships in your production bundle. `@cipherstash/cli` is a devDependency: it handles database tooling and schema lifecycle at development time. Think of it like Drizzle Kit — a companion tool that prepares the database while the runtime SDK handles queries. +`@cipherstash/stack` is the runtime SDK. It stays lean with no heavy dependencies like `pg` and ships in your production bundle. `stash` is a devDependency: it handles database tooling and schema lifecycle at development time. Think of it like Drizzle Kit — a companion tool that prepares the database while the runtime SDK handles queries. --- diff --git a/packages/cli/package.json b/packages/cli/package.json index 039fc26a..d13c76f0 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,5 +1,5 @@ { - "name": "@cipherstash/cli", + "name": "stash", "version": "0.10.1", "description": "CipherStash CLI — the one stash command for auth, init, encryption schema, database setup, and secrets.", "license": "MIT", diff --git a/packages/cli/src/bin/stash.ts b/packages/cli/src/bin/stash.ts index 9154dac1..725a2bc1 100644 --- a/packages/cli/src/bin/stash.ts +++ b/packages/cli/src/bin/stash.ts @@ -41,7 +41,7 @@ async function requireStack(importFn: () => Promise): Promise { p.log.error( '@cipherstash/stack is required for this command.\n' + ' Install it with: npm install @cipherstash/stack\n' + - ' Or run: npx @cipherstash/cli init', + ' Or run: npx stash init', ) process.exit(1) as never } @@ -96,12 +96,12 @@ DB Flags: --database-url (all db / schema commands) Override DATABASE_URL for this run only — never written to disk Examples: - npx @cipherstash/cli init - npx @cipherstash/cli init --supabase - npx @cipherstash/cli auth login - npx @cipherstash/cli db install - npx @cipherstash/cli db push - npx @cipherstash/cli schema build + npx stash init + npx stash init --supabase + npx stash auth login + npx stash db install + npx stash db push + npx stash schema build `.trim() interface ParsedArgs { diff --git a/packages/cli/src/commands/auth/index.ts b/packages/cli/src/commands/auth/index.ts index e52358b3..e76c1ad7 100644 --- a/packages/cli/src/commands/auth/index.ts +++ b/packages/cli/src/commands/auth/index.ts @@ -12,8 +12,8 @@ Options: --drizzle Track Drizzle as the referrer Examples: - npx @cipherstash/cli auth login - npx @cipherstash/cli auth login --supabase + npx stash auth login + npx stash auth login --supabase `.trim() function referrerFromFlags(flags: Record): string | undefined { diff --git a/packages/cli/src/commands/db/config-scaffold.ts b/packages/cli/src/commands/db/config-scaffold.ts index f45cb115..b5e623c4 100644 --- a/packages/cli/src/commands/db/config-scaffold.ts +++ b/packages/cli/src/commands/db/config-scaffold.ts @@ -73,7 +73,7 @@ function generateConfig(clientPath: string): string { // walks a layered chain (--database-url flag → env → supabase status // → interactive prompt) and returns a usable URL. The connection // string is never persisted — only this declarative call is. - return `import { defineConfig, resolveDatabaseUrl } from '@cipherstash/cli' + return `import { defineConfig, resolveDatabaseUrl } from 'stash' export default defineConfig({ databaseUrl: await resolveDatabaseUrl(), diff --git a/packages/cli/src/commands/db/install.ts b/packages/cli/src/commands/db/install.ts index 19aa4f31..4aef5e30 100644 --- a/packages/cli/src/commands/db/install.ts +++ b/packages/cli/src/commands/db/install.ts @@ -66,7 +66,7 @@ export interface InstallOptions { export type SupabaseInstallMode = 'migration' | 'direct' export async function installCommand(options: InstallOptions) { - p.intro(runnerCommand(detectPackageManager(), '@cipherstash/cli db install')) + p.intro(runnerCommand(detectPackageManager(), 'stash db install')) // Validate mutually-exclusive / supabase-required flags BEFORE doing any // I/O. `--migration` and `--direct` only make sense in the Supabase flow; diff --git a/packages/cli/src/commands/db/push.ts b/packages/cli/src/commands/db/push.ts index c39b76c0..f676132d 100644 --- a/packages/cli/src/commands/db/push.ts +++ b/packages/cli/src/commands/db/push.ts @@ -32,7 +32,7 @@ export async function pushCommand(options: { dryRun?: boolean databaseUrl?: string }) { - p.intro(runnerCommand(detectPackageManager(), '@cipherstash/cli db push')) + p.intro(runnerCommand(detectPackageManager(), 'stash db push')) p.log.info( 'This command pushes the encryption schema to the database for use with CipherStash Proxy.\nIf you are using the SDK directly (Drizzle, Supabase, or plain PostgreSQL), this step is not required.', ) diff --git a/packages/cli/src/commands/db/rewrite-migrations.ts b/packages/cli/src/commands/db/rewrite-migrations.ts index 0b6cadfe..4ddd826c 100644 --- a/packages/cli/src/commands/db/rewrite-migrations.ts +++ b/packages/cli/src/commands/db/rewrite-migrations.ts @@ -74,7 +74,7 @@ export async function rewriteEncryptedAlterColumns( function renderSafeAlter(table: string, column: string): string { const tmp = `${column}__cipherstash_tmp` return [ - '-- Rewritten by @cipherstash/cli: in-place ALTER COLUMN cannot cast to', + '-- Rewritten by stash: in-place ALTER COLUMN cannot cast to', `-- eql_v2_encrypted. If "${table}" already has rows, backfill the new`, "-- column via @cipherstash/stack's encryptModel in application code BEFORE", '-- running this migration in production. Empty tables are safe as-is.', diff --git a/packages/cli/src/commands/db/status.ts b/packages/cli/src/commands/db/status.ts index 78ef209d..7051da63 100644 --- a/packages/cli/src/commands/db/status.ts +++ b/packages/cli/src/commands/db/status.ts @@ -6,7 +6,7 @@ import pg from 'pg' export async function statusCommand(options: { databaseUrl?: string } = {}) { const pm = detectPackageManager() - p.intro(runnerCommand(pm, '@cipherstash/cli db status')) + p.intro(runnerCommand(pm, 'stash db status')) const s = p.spinner() @@ -44,7 +44,7 @@ export async function statusCommand(options: { databaseUrl?: string } = {}) { } else { s.stop('EQL is not installed.') p.log.warn( - `EQL is not installed. Run \`${runnerCommand(pm, '@cipherstash/cli db install')}\` to install it.`, + `EQL is not installed. Run \`${runnerCommand(pm, 'stash db install')}\` to install it.`, ) p.outro('Status check complete.') return @@ -104,7 +104,7 @@ export async function statusCommand(options: { databaseUrl?: string } = {}) { const message = error instanceof Error ? error.message : String(error) if (message.includes('does not exist')) { p.log.info( - `Active encrypt config: table not found (run \`${runnerCommand(pm, '@cipherstash/cli db push')}\` to create it)`, + `Active encrypt config: table not found (run \`${runnerCommand(pm, 'stash db push')}\` to create it)`, ) } else { p.log.error(`Failed to check encrypt configuration: ${message}`) diff --git a/packages/cli/src/commands/db/supabase-migration.ts b/packages/cli/src/commands/db/supabase-migration.ts index 2da49988..04222a86 100644 --- a/packages/cli/src/commands/db/supabase-migration.ts +++ b/packages/cli/src/commands/db/supabase-migration.ts @@ -24,7 +24,7 @@ export const SUPABASE_EQL_MIGRATION_FILENAME = * this file exists for future maintainers reading their own migrations * directory. */ -const MIGRATION_HEADER = `-- CipherStash EQL — installed by \`npx @cipherstash/cli db install --supabase --migration\`. +const MIGRATION_HEADER = `-- CipherStash EQL — installed by \`npx stash db 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 diff --git a/packages/cli/src/commands/db/test-connection.ts b/packages/cli/src/commands/db/test-connection.ts index 990feb52..3cf477d4 100644 --- a/packages/cli/src/commands/db/test-connection.ts +++ b/packages/cli/src/commands/db/test-connection.ts @@ -8,12 +8,7 @@ import pg from 'pg' export async function testConnectionCommand( options: { databaseUrl?: string } = {}, ) { - p.intro( - runnerCommand( - detectPackageManager(), - '@cipherstash/cli db test-connection', - ), - ) + p.intro(runnerCommand(detectPackageManager(), 'stash db test-connection')) const s = p.spinner() diff --git a/packages/cli/src/commands/db/upgrade.ts b/packages/cli/src/commands/db/upgrade.ts index fb7f5bcb..696ce4d7 100644 --- a/packages/cli/src/commands/db/upgrade.ts +++ b/packages/cli/src/commands/db/upgrade.ts @@ -11,7 +11,7 @@ export async function upgradeCommand(options: { databaseUrl?: string }) { const pm = detectPackageManager() - p.intro(runnerCommand(pm, '@cipherstash/cli db upgrade')) + p.intro(runnerCommand(pm, 'stash db upgrade')) const s = p.spinner() @@ -32,7 +32,7 @@ export async function upgradeCommand(options: { if (!installed) { s.stop('EQL is not installed.') p.log.warn( - `EQL is not currently installed. Run "${runnerCommand(pm, '@cipherstash/cli db install')}" first.`, + `EQL is not currently installed. Run "${runnerCommand(pm, 'stash db install')}" first.`, ) p.outro('Upgrade aborted.') process.exit(1) diff --git a/packages/cli/src/commands/db/validate.ts b/packages/cli/src/commands/db/validate.ts index db7c27e6..c7871669 100644 --- a/packages/cli/src/commands/db/validate.ts +++ b/packages/cli/src/commands/db/validate.ts @@ -150,7 +150,7 @@ export async function validateCommand(options: { excludeOperatorFamily?: boolean databaseUrl?: string }) { - p.intro(runnerCommand(detectPackageManager(), '@cipherstash/cli db validate')) + p.intro(runnerCommand(detectPackageManager(), 'stash db validate')) const s = p.spinner() diff --git a/packages/cli/src/commands/env/index.ts b/packages/cli/src/commands/env/index.ts index 1dab4983..9ac03d58 100644 --- a/packages/cli/src/commands/env/index.ts +++ b/packages/cli/src/commands/env/index.ts @@ -28,12 +28,12 @@ export async function envCommand(options: EnvOptions = {}): Promise { return } - p.intro('npx @cipherstash/cli env') + p.intro('npx stash env') const creds = await fetchProdCredentials() if (!creds) { p.log.error( - 'Could not mint production credentials. Make sure you are logged in: npx @cipherstash/cli auth login', + 'Could not mint production credentials. Make sure you are logged in: npx stash auth login', ) process.exit(1) } @@ -82,7 +82,7 @@ async function fetchProdCredentials(): Promise { function formatEnvBlock(creds: ProdCredentials): string { return [ - '# Generated by `npx @cipherstash/cli env` — production credentials', + '# Generated by `npx stash env` — production credentials', `CS_CLIENT_ID=${creds.clientId}`, `CS_CLIENT_KEY=${creds.clientKey}`, `CS_WORKSPACE_ID=${creds.workspaceId}`, diff --git a/packages/cli/src/commands/init/__tests__/utils.test.ts b/packages/cli/src/commands/init/__tests__/utils.test.ts index e53d6489..1e331deb 100644 --- a/packages/cli/src/commands/init/__tests__/utils.test.ts +++ b/packages/cli/src/commands/init/__tests__/utils.test.ts @@ -111,58 +111,58 @@ describe('prodInstallCommand', () => { describe('devInstallCommand', () => { it('returns bun add -D for bun', () => { - expect(devInstallCommand('bun', '@cipherstash/cli')).toBe( - 'bun add -D @cipherstash/cli', + expect(devInstallCommand('bun', 'stash')).toBe( + 'bun add -D stash', ) }) it('returns pnpm add -D for pnpm', () => { - expect(devInstallCommand('pnpm', '@cipherstash/cli')).toBe( - 'pnpm add -D @cipherstash/cli', + expect(devInstallCommand('pnpm', 'stash')).toBe( + 'pnpm add -D stash', ) }) it('returns yarn add -D for yarn', () => { - expect(devInstallCommand('yarn', '@cipherstash/cli')).toBe( - 'yarn add -D @cipherstash/cli', + expect(devInstallCommand('yarn', 'stash')).toBe( + 'yarn add -D stash', ) }) it('returns npm install -D for npm', () => { - expect(devInstallCommand('npm', '@cipherstash/cli')).toBe( - 'npm install -D @cipherstash/cli', + expect(devInstallCommand('npm', 'stash')).toBe( + 'npm install -D stash', ) }) }) describe('runnerCommand', () => { it('returns npx for npm', () => { - expect(runnerCommand('npm', '@cipherstash/cli')).toBe( - 'npx @cipherstash/cli', + expect(runnerCommand('npm', 'stash')).toBe( + 'npx stash', ) }) it('returns bunx for bun', () => { - expect(runnerCommand('bun', '@cipherstash/cli')).toBe( - 'bunx @cipherstash/cli', + expect(runnerCommand('bun', 'stash')).toBe( + 'bunx stash', ) }) it('returns pnpm dlx for pnpm', () => { - expect(runnerCommand('pnpm', '@cipherstash/cli')).toBe( - 'pnpm dlx @cipherstash/cli', + expect(runnerCommand('pnpm', 'stash')).toBe( + 'pnpm dlx stash', ) }) it('returns yarn dlx for yarn', () => { - expect(runnerCommand('yarn', '@cipherstash/cli')).toBe( - 'yarn dlx @cipherstash/cli', + expect(runnerCommand('yarn', 'stash')).toBe( + 'yarn dlx stash', ) }) it('passes the package reference through verbatim (multi-word args allowed)', () => { - expect(runnerCommand('bun', '@cipherstash/cli db install')).toBe( - 'bunx @cipherstash/cli db install', + expect(runnerCommand('bun', 'stash db install')).toBe( + 'bunx stash db install', ) }) }) diff --git a/packages/cli/src/commands/init/providers/__tests__/base.test.ts b/packages/cli/src/commands/init/providers/__tests__/base.test.ts index ddfec294..602546a8 100644 --- a/packages/cli/src/commands/init/providers/__tests__/base.test.ts +++ b/packages/cli/src/commands/init/providers/__tests__/base.test.ts @@ -7,7 +7,7 @@ describe('createBaseProvider getNextSteps', () => { it('uses npx when package manager is npm', () => { const steps = provider.getNextSteps({}, 'npm') expect(steps[0]).toBe( - 'Set up your database: npx @cipherstash/cli db install', + 'Set up your database: npx stash db install', ) expect(steps[1]).toContain('npx @cipherstash/wizard') }) @@ -15,7 +15,7 @@ describe('createBaseProvider getNextSteps', () => { it('uses bunx when package manager is bun', () => { const steps = provider.getNextSteps({}, 'bun') expect(steps[0]).toBe( - 'Set up your database: bunx @cipherstash/cli db install', + 'Set up your database: bunx stash db install', ) expect(steps[1]).toContain('bunx @cipherstash/wizard') // Sanity: the old hardcoded `npx` should be gone. @@ -25,7 +25,7 @@ describe('createBaseProvider getNextSteps', () => { it('uses pnpm dlx when package manager is pnpm', () => { const steps = provider.getNextSteps({}, 'pnpm') expect(steps[0]).toBe( - 'Set up your database: pnpm dlx @cipherstash/cli db install', + 'Set up your database: pnpm dlx stash db install', ) expect(steps[1]).toContain('pnpm dlx @cipherstash/wizard') }) @@ -33,7 +33,7 @@ describe('createBaseProvider getNextSteps', () => { it('uses yarn dlx when package manager is yarn', () => { const steps = provider.getNextSteps({}, 'yarn') expect(steps[0]).toBe( - 'Set up your database: yarn dlx @cipherstash/cli db install', + 'Set up your database: yarn dlx stash db install', ) }) diff --git a/packages/cli/src/commands/init/providers/__tests__/drizzle.test.ts b/packages/cli/src/commands/init/providers/__tests__/drizzle.test.ts index 7d665f7c..1f247670 100644 --- a/packages/cli/src/commands/init/providers/__tests__/drizzle.test.ts +++ b/packages/cli/src/commands/init/providers/__tests__/drizzle.test.ts @@ -7,14 +7,14 @@ describe('createDrizzleProvider getNextSteps', () => { it('uses npx when package manager is npm', () => { const steps = provider.getNextSteps({}, 'npm') expect(steps[0]).toBe( - 'Set up your database: npx @cipherstash/cli db install --drizzle', + 'Set up your database: npx stash db install --drizzle', ) }) it('uses bunx when package manager is bun', () => { const steps = provider.getNextSteps({}, 'bun') expect(steps[0]).toBe( - 'Set up your database: bunx @cipherstash/cli db install --drizzle', + 'Set up your database: bunx stash db install --drizzle', ) expect(steps[1]).toContain('bunx @cipherstash/wizard') for (const s of steps) expect(s).not.toMatch(/\bnpx\b/) @@ -23,14 +23,14 @@ describe('createDrizzleProvider getNextSteps', () => { it('uses pnpm dlx when package manager is pnpm', () => { const steps = provider.getNextSteps({}, 'pnpm') expect(steps[0]).toBe( - 'Set up your database: pnpm dlx @cipherstash/cli db install --drizzle', + 'Set up your database: pnpm dlx stash db install --drizzle', ) }) it('uses yarn dlx when package manager is yarn', () => { const steps = provider.getNextSteps({}, 'yarn') expect(steps[0]).toBe( - 'Set up your database: yarn dlx @cipherstash/cli db install --drizzle', + 'Set up your database: yarn dlx stash db install --drizzle', ) }) }) diff --git a/packages/cli/src/commands/init/providers/__tests__/supabase.test.ts b/packages/cli/src/commands/init/providers/__tests__/supabase.test.ts index 7e8030f6..e23049a8 100644 --- a/packages/cli/src/commands/init/providers/__tests__/supabase.test.ts +++ b/packages/cli/src/commands/init/providers/__tests__/supabase.test.ts @@ -7,14 +7,14 @@ describe('createSupabaseProvider getNextSteps', () => { it('uses npx when package manager is npm', () => { const steps = provider.getNextSteps({}, 'npm') expect(steps[0]).toBe( - 'Install EQL: npx @cipherstash/cli db install --supabase (prompts for migration vs direct)', + 'Install EQL: npx stash db install --supabase (prompts for migration vs direct)', ) }) it('uses bunx when package manager is bun', () => { const steps = provider.getNextSteps({}, 'bun') expect(steps[0]).toBe( - 'Install EQL: bunx @cipherstash/cli db install --supabase (prompts for migration vs direct)', + 'Install EQL: bunx stash db install --supabase (prompts for migration vs direct)', ) expect(steps[2]).toContain('bunx @cipherstash/wizard') // wizard step is third for (const s of steps) expect(s).not.toMatch(/\bnpx\b/) @@ -23,14 +23,14 @@ describe('createSupabaseProvider getNextSteps', () => { it('uses pnpm dlx when package manager is pnpm', () => { const steps = provider.getNextSteps({}, 'pnpm') expect(steps[0]).toContain( - 'pnpm dlx @cipherstash/cli db install --supabase', + 'pnpm dlx stash db install --supabase', ) }) it('uses yarn dlx when package manager is yarn', () => { const steps = provider.getNextSteps({}, 'yarn') expect(steps[0]).toBe( - 'Install EQL: yarn dlx @cipherstash/cli db install --supabase (prompts for migration vs direct)', + 'Install EQL: yarn dlx stash db install --supabase (prompts for migration vs direct)', ) expect(steps[2]).toContain('yarn dlx @cipherstash/wizard') // Sanity: the supabase CLI commands stay untouched. diff --git a/packages/cli/src/commands/init/providers/base.ts b/packages/cli/src/commands/init/providers/base.ts index fe3c41fb..4f8ba279 100644 --- a/packages/cli/src/commands/init/providers/base.ts +++ b/packages/cli/src/commands/init/providers/base.ts @@ -6,7 +6,7 @@ export function createBaseProvider(): InitProvider { name: 'base', introMessage: 'Setting up CipherStash for your project...', getNextSteps(state: InitState, pm: PackageManager): string[] { - const cli = runnerCommand(pm, '@cipherstash/cli') + const cli = runnerCommand(pm, 'stash') const wizard = runnerCommand(pm, '@cipherstash/wizard') const manualEdit = state.clientFilePath ? `edit ${state.clientFilePath} directly` diff --git a/packages/cli/src/commands/init/providers/drizzle.ts b/packages/cli/src/commands/init/providers/drizzle.ts index c611e767..8b443882 100644 --- a/packages/cli/src/commands/init/providers/drizzle.ts +++ b/packages/cli/src/commands/init/providers/drizzle.ts @@ -6,7 +6,7 @@ export function createDrizzleProvider(): InitProvider { name: 'drizzle', introMessage: 'Setting up CipherStash for your Drizzle project...', getNextSteps(state: InitState, pm: PackageManager): string[] { - const cli = runnerCommand(pm, '@cipherstash/cli') + const cli = runnerCommand(pm, 'stash') const wizard = runnerCommand(pm, '@cipherstash/wizard') const steps = [`Set up your database: ${cli} db install --drizzle`] diff --git a/packages/cli/src/commands/init/providers/supabase.ts b/packages/cli/src/commands/init/providers/supabase.ts index ab17e66e..b9cbcf2b 100644 --- a/packages/cli/src/commands/init/providers/supabase.ts +++ b/packages/cli/src/commands/init/providers/supabase.ts @@ -6,7 +6,7 @@ export function createSupabaseProvider(): InitProvider { name: 'supabase', introMessage: 'Setting up CipherStash for your Supabase project...', getNextSteps(state: InitState, pm: PackageManager): string[] { - const cli = runnerCommand(pm, '@cipherstash/cli') + const cli = runnerCommand(pm, 'stash') const wizard = runnerCommand(pm, '@cipherstash/wizard') const steps = [ `Install EQL: ${cli} db install --supabase (prompts for migration vs direct)`, diff --git a/packages/cli/src/commands/init/steps/install-forge.ts b/packages/cli/src/commands/init/steps/install-forge.ts index 4d9febe1..53b45188 100644 --- a/packages/cli/src/commands/init/steps/install-forge.ts +++ b/packages/cli/src/commands/init/steps/install-forge.ts @@ -9,7 +9,7 @@ import { } from '../utils.js' const STACK_PACKAGE = '@cipherstash/stack' -const FORGE_PACKAGE = '@cipherstash/cli' +const FORGE_PACKAGE = 'stash' export const installForgeStep: InitStep = { id: 'install-forge', diff --git a/packages/cli/src/commands/init/utils.ts b/packages/cli/src/commands/init/utils.ts index 40c9d19c..e7563f6b 100644 --- a/packages/cli/src/commands/init/utils.ts +++ b/packages/cli/src/commands/init/utils.ts @@ -122,8 +122,8 @@ export function combinedInstallCommands( * pnpm → `pnpm dlx` * yarn → `yarn dlx` * - * `ref` is appended verbatim, so callers may pass `'@cipherstash/cli'` - * or `'@cipherstash/cli db install'`. + * `ref` is appended verbatim, so callers may pass `'stash'` or + * `'stash db install'`. */ export function runnerCommand(pm: PackageManager, ref: string): string { switch (pm) { diff --git a/packages/cli/src/config/database-url.ts b/packages/cli/src/config/database-url.ts index 48466b3b..a786b04a 100644 --- a/packages/cli/src/config/database-url.ts +++ b/packages/cli/src/config/database-url.ts @@ -2,7 +2,7 @@ * Layered DATABASE_URL resolution. Called from inside the user's * `stash.config.ts` via: * - * import { defineConfig, resolveDatabaseUrl } from '@cipherstash/cli' + * import { defineConfig, resolveDatabaseUrl } from 'stash' * export default defineConfig({ * databaseUrl: await resolveDatabaseUrl(), * }) diff --git a/packages/cli/src/config/index.ts b/packages/cli/src/config/index.ts index 2f992eb7..3af8eea1 100644 --- a/packages/cli/src/config/index.ts +++ b/packages/cli/src/config/index.ts @@ -25,7 +25,7 @@ export type ResolvedStashConfig = Required> & * * @example * ```ts - * import { defineConfig } from '@cipherstash/cli' + * import { defineConfig } from 'stash' * * export default defineConfig({ * databaseUrl: process.env.DATABASE_URL!, @@ -100,7 +100,7 @@ export async function loadStashConfig( Create a ${CONFIG_FILENAME} file in your project root: - import { defineConfig, resolveDatabaseUrl } from '@cipherstash/cli' + import { defineConfig, resolveDatabaseUrl } from 'stash' export default defineConfig({ databaseUrl: await resolveDatabaseUrl(), diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 9f50052e..c3dec3e8 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -1,4 +1,4 @@ -// @cipherstash/cli +// stash // Public API exports export { defineConfig, loadStashConfig } from './config/index.ts' diff --git a/packages/cli/src/installer/index.ts b/packages/cli/src/installer/index.ts index bfd75fa9..54f31679 100644 --- a/packages/cli/src/installer/index.ts +++ b/packages/cli/src/installer/index.ts @@ -315,7 +315,7 @@ export class EQLInstaller { return readFileSync(bundledSqlPath(filename), 'utf-8') } catch (error) { throw new Error( - `Failed to load bundled EQL install script (${filename}). The package may be corrupted — try reinstalling @cipherstash/cli.`, + `Failed to load bundled EQL install script (${filename}). The package may be corrupted — try reinstalling stash.`, { cause: error }, ) } @@ -386,7 +386,7 @@ export function loadBundledEqlSql( return readFileSync(bundledSqlPath(filename), 'utf-8') } catch (error) { throw new Error( - `Failed to load bundled EQL install script (${filename}). The package may be corrupted — try reinstalling @cipherstash/cli.`, + `Failed to load bundled EQL install script (${filename}). The package may be corrupted — try reinstalling stash.`, { cause: error }, ) } diff --git a/packages/cli/src/messages.ts b/packages/cli/src/messages.ts index 30153686..62f335e8 100644 --- a/packages/cli/src/messages.ts +++ b/packages/cli/src/messages.ts @@ -12,19 +12,18 @@ export const messages = { cli: { versionBannerPrefix: 'CipherStash CLI v', - usagePrefix: 'Usage: npx @cipherstash/cli', + usagePrefix: 'Usage: npx stash', unknownCommand: 'Unknown command', }, auth: { - usagePrefix: 'Usage: npx @cipherstash/cli auth', + usagePrefix: 'Usage: npx stash auth', unknownSubcommand: 'Unknown auth command', selectRegion: 'Select a region', cancelled: 'Cancelled.', }, db: { unknownSubcommand: 'Unknown db subcommand', - migrateNotImplemented: - '"npx @cipherstash/cli db migrate" is not yet implemented.', + migrateNotImplemented: '"npx stash db migrate" is not yet implemented.', /** Source labels surfaced after DATABASE_URL resolution. */ urlResolvedFromFlag: 'Using DATABASE_URL from --database-url flag', urlResolvedFromSupabase: 'Using DATABASE_URL from supabase status', diff --git a/packages/cli/tests/e2e/database-url.e2e.test.ts b/packages/cli/tests/e2e/database-url.e2e.test.ts index 4757871c..d38bdecc 100644 --- a/packages/cli/tests/e2e/database-url.e2e.test.ts +++ b/packages/cli/tests/e2e/database-url.e2e.test.ts @@ -10,8 +10,8 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)) // Absolute path to the built CLI's `dist/index.js`. The test config imports // from this path because the tmp dir doesn't have a node_modules with -// `@cipherstash/cli` symlinked. Real users get a clean -// `import { resolveDatabaseUrl } from '@cipherstash/cli'`. +// `stash` symlinked. Real users get a clean +// `import { resolveDatabaseUrl } from 'stash'`. const CLI_DIST_INDEX = path.resolve(__dirname, '../../dist/index.js') describe('db test-connection — DATABASE_URL resolver', () => { diff --git a/packages/cli/tests/helpers/pty.ts b/packages/cli/tests/helpers/pty.ts index baf9b90f..3d7b787e 100644 --- a/packages/cli/tests/helpers/pty.ts +++ b/packages/cli/tests/helpers/pty.ts @@ -7,7 +7,7 @@ import stripAnsi from 'strip-ansi' const __dirname = dirname(fileURLToPath(import.meta.url)) -// Built CLI binary. Tests assume `pnpm --filter @cipherstash/cli build` has run. +// Built CLI binary. Tests assume `pnpm --filter stash build` has run. export const STASH_BIN = resolve(__dirname, '../../dist/bin/stash.js') // pnpm strips the executable bit when unpacking node-pty's macOS prebuilds, diff --git a/packages/protect/src/bin/stash.ts b/packages/protect/src/bin/stash.ts index 5b393f7c..9b023cef 100644 --- a/packages/protect/src/bin/stash.ts +++ b/packages/protect/src/bin/stash.ts @@ -166,9 +166,9 @@ Store a secret value that will be encrypted locally before being sent to the Cip The secret is encrypted end-to-end, ensuring your plaintext never leaves your machine unencrypted. Examples: - npx @cipherstash/cli secrets set --name DATABASE_URL --value "postgres://..." --environment production - npx @cipherstash/cli secrets set -n DATABASE_URL -V "postgres://..." -e production - npx @cipherstash/cli secrets set --name API_KEY --value "sk-123..." --environment staging + npx stash secrets set --name DATABASE_URL --value "postgres://..." --environment production + npx stash secrets set -n DATABASE_URL -V "postgres://..." -e production + npx stash secrets set --name API_KEY --value "sk-123..." --environment staging `.trim(), }, }) @@ -221,9 +221,9 @@ Retrieve a secret from CipherStash and decrypt it locally. The secret value is d on your machine, ensuring end-to-end security. Examples: - npx @cipherstash/cli secrets get --name DATABASE_URL --environment production - npx @cipherstash/cli secrets get -n DATABASE_URL -e production - npx @cipherstash/cli secrets get --name API_KEY --environment staging + npx stash secrets get --name DATABASE_URL --environment production + npx stash secrets get -n DATABASE_URL -e production + npx stash secrets get --name API_KEY --environment staging `.trim(), }, }) @@ -305,9 +305,9 @@ List all secrets stored in the specified environment. Only secret names and meta are returned; values remain encrypted and are not displayed. Examples: - npx @cipherstash/cli secrets list --environment production - npx @cipherstash/cli secrets list -e production - npx @cipherstash/cli secrets list --environment staging + npx stash secrets list --environment production + npx stash secrets list -e production + npx stash secrets list --environment staging `.trim(), }, }) @@ -385,9 +385,9 @@ Permanently delete a secret from the specified environment. This action cannot b By default, you will be prompted for confirmation before deletion. Use --yes to skip the confirmation. Examples: - npx @cipherstash/cli secrets delete --name DATABASE_URL --environment production - npx @cipherstash/cli secrets delete -n DATABASE_URL -e production --yes - npx @cipherstash/cli secrets delete --name API_KEY --environment staging -y + npx stash secrets delete --name DATABASE_URL --environment production + npx stash secrets delete -n DATABASE_URL -e production --yes + npx stash secrets delete --name API_KEY --environment staging -y `.trim(), }, }) @@ -421,15 +421,15 @@ Environment Variables: CS_CLIENT_ACCESS_KEY CipherStash client access key (required) Examples: - npx @cipherstash/cli secrets set --name DATABASE_URL --value "postgres://..." --environment production - npx @cipherstash/cli secrets set -n DATABASE_URL -V "postgres://..." -e production - npx @cipherstash/cli secrets get --name DATABASE_URL --environment production - npx @cipherstash/cli secrets get -n DATABASE_URL -e production - npx @cipherstash/cli secrets list --environment production - npx @cipherstash/cli secrets list -e production - npx @cipherstash/cli secrets delete --name DATABASE_URL --environment production - npx @cipherstash/cli secrets delete -n DATABASE_URL -e production --yes - npx @cipherstash/cli secrets delete -n DATABASE_URL -e production -y + npx stash secrets set --name DATABASE_URL --value "postgres://..." --environment production + npx stash secrets set -n DATABASE_URL -V "postgres://..." -e production + npx stash secrets get --name DATABASE_URL --environment production + npx stash secrets get -n DATABASE_URL -e production + npx stash secrets list --environment production + npx stash secrets list -e production + npx stash secrets delete --name DATABASE_URL --environment production + npx stash secrets delete -n DATABASE_URL -e production --yes + npx stash secrets delete -n DATABASE_URL -e production -y `.trim(), }, }) @@ -452,13 +452,13 @@ your machine unencrypted. Quick Start: 1. Set required environment variables (CS_WORKSPACE_CRN, CS_CLIENT_ID, etc.) - 2. Use 'npx @cipherstash/cli secrets set' to store your first secret - 3. Use 'npx @cipherstash/cli secrets get' to retrieve secrets when needed + 2. Use 'npx stash secrets set' to store your first secret + 3. Use 'npx stash secrets get' to retrieve secrets when needed Commands: secrets Manage encrypted secrets -Run 'npx @cipherstash/cli --help' for more information about a command. +Run 'npx stash --help' for more information about a command. `.trim(), }, }) diff --git a/packages/stack/README.md b/packages/stack/README.md index a1d0fb8f..1a57a8cb 100644 --- a/packages/stack/README.md +++ b/packages/stack/README.md @@ -47,7 +47,7 @@ pnpm add @cipherstash/stack ### 1. Initialize and authenticate your project ```bash -npx @cipherstash/cli init +npx stash init ``` The wizard will authenticate you, walk you through choosing a database connection method, build an encryption schema, and install the required dependencies. @@ -438,25 +438,25 @@ await secrets.delete("DATABASE_URL") ## CLI Reference -The CLI is available via `npx @cipherstash/cli` after install. +The CLI is available via `npx stash` after install. -### `npx @cipherstash/cli auth` +### `npx stash auth` Authenticate with CipherStash. ```bash -npx @cipherstash/cli auth login +npx stash auth login ``` This runs the device code flow: it opens your browser, you confirm the code, and a token is saved to `~/.cipherstash/auth.json`. No environment variables or credentials files are needed for local development. -### `npx @cipherstash/cli init` +### `npx stash init` Initialize CipherStash for your project with an interactive wizard. ```bash -npx @cipherstash/cli init -npx @cipherstash/cli init --supabase +npx stash init +npx stash init --supabase ``` The wizard will: @@ -464,31 +464,31 @@ The wizard will: 2. Bind your device to the default Keyset 3. Choose your database connection method (Drizzle ORM, Supabase JS, Prisma, or Raw SQL) 4. Build an encryption schema interactively or use a placeholder, then generate the encryption client file -5. Install `@cipherstash/cli` as a dev dependency for database tooling +5. Install `stash` as a dev dependency for database tooling -After init, run `npx @cipherstash/cli db setup` to configure your database. +After init, run `npx stash db setup` to configure your database. | Flag | Description | |------|-------------| | `--supabase` | Use Supabase-specific setup flow | -### `npx @cipherstash/cli secrets` +### `npx stash secrets` Manage encrypted secrets from the terminal. ```bash -npx @cipherstash/cli secrets set -name DATABASE_URL -value "postgres://..." -environment production -npx @cipherstash/cli secrets get -name DATABASE_URL -environment production -npx @cipherstash/cli secrets list -environment production -npx @cipherstash/cli secrets delete -name DATABASE_URL -environment production +npx stash secrets set -name DATABASE_URL -value "postgres://..." -environment production +npx stash secrets get -name DATABASE_URL -environment production +npx stash secrets list -environment production +npx stash secrets delete -name DATABASE_URL -environment production ``` | Command | Flags | Aliases | Description | |-----|----|-----|-------| -| `npx @cipherstash/cli secrets set` | `-name`, `-value`, `-environment` | `-n`, `-V`, `-e` | Encrypt and store a secret | -| `npx @cipherstash/cli secrets get` | `-name`, `-environment` | `-n`, `-e` | Retrieve and decrypt a secret | -| `npx @cipherstash/cli secrets list` | `-environment` | `-e` | List all secret names in an environment | -| `npx @cipherstash/cli secrets delete` | `-name`, `-environment`, `-yes` | `-n`, `-e`, `-y` | Delete a secret (prompts for confirmation unless `-yes`) | +| `npx stash secrets set` | `-name`, `-value`, `-environment` | `-n`, `-V`, `-e` | Encrypt and store a secret | +| `npx stash secrets get` | `-name`, `-environment` | `-n`, `-e` | Retrieve and decrypt a secret | +| `npx stash secrets list` | `-environment` | `-e` | List all secret names in an environment | +| `npx stash secrets delete` | `-name`, `-environment`, `-yes` | `-n`, `-e`, `-y` | Delete a secret (prompts for confirmation unless `-yes`) | ## Configuration @@ -676,7 +676,7 @@ If you are migrating from `@cipherstash/protect`, the following table maps the o | `csColumn(name)` | `encryptedColumn(name)` | `@cipherstash/stack/schema` | | `import { LockContext } from "@cipherstash/protect/identify"` | `import { LockContext } from "@cipherstash/stack/identity"` | `@cipherstash/stack/identity` | | N/A | `Secrets` class | `@cipherstash/stack/secrets` | -| N/A | CLI | `npx @cipherstash/cli` | +| N/A | CLI | `npx stash` | All method signatures on the encryption client (`encrypt`, `decrypt`, `encryptModel`, etc.) remain the same. The `Result` pattern (`data` / `failure`) is unchanged. diff --git a/packages/wizard/README.md b/packages/wizard/README.md index 6d9dff8a..5b9bd8b3 100644 --- a/packages/wizard/README.md +++ b/packages/wizard/README.md @@ -19,7 +19,7 @@ bunx @cipherstash/wizard # bun Before running the wizard, your project should have: -- `@cipherstash/cli` available (the wizard shells out to `stash db install` / +- `stash` available (the wizard shells out to `stash db install` / `db push` after the agent finishes editing) - A `stash.config.ts` (or the wizard will run `stash db install` to scaffold one) - A reachable database via `DATABASE_URL` diff --git a/packages/wizard/src/__tests__/errors-runner.test.ts b/packages/wizard/src/__tests__/errors-runner.test.ts index c211aa80..99e4fa9a 100644 --- a/packages/wizard/src/__tests__/errors-runner.test.ts +++ b/packages/wizard/src/__tests__/errors-runner.test.ts @@ -4,19 +4,19 @@ import { classifyError, classifyHttpError } from '../agent/errors.js' describe('classifyError runner', () => { it('uses npx by default for auth failure', () => { expect(classifyError('authentication_failed', '')).toContain( - 'Run: npx @cipherstash/cli auth login', + 'Run: npx stash auth login', ) }) it('uses bunx when runner=bunx', () => { expect(classifyError('authentication_failed', '', 'bunx')).toContain( - 'Run: bunx @cipherstash/cli auth login', + 'Run: bunx stash auth login', ) }) it('uses pnpm dlx when runner=pnpm dlx', () => { expect(classifyError('authentication_failed', '', 'pnpm dlx')).toContain( - 'Run: pnpm dlx @cipherstash/cli auth login', + 'Run: pnpm dlx stash auth login', ) }) }) @@ -24,13 +24,13 @@ describe('classifyError runner', () => { describe('classifyHttpError runner', () => { it('uses npx by default for 401', () => { expect(classifyHttpError(401, '')).toContain( - 'Run: npx @cipherstash/cli auth login', + 'Run: npx stash auth login', ) }) it('uses bunx when runner=bunx for 401', () => { expect(classifyHttpError(401, '', 'bunx')).toContain( - 'Run: bunx @cipherstash/cli auth login', + 'Run: bunx stash auth login', ) }) }) diff --git a/packages/wizard/src/__tests__/format.test.ts b/packages/wizard/src/__tests__/format.test.ts index 411adcac..df16a25b 100644 --- a/packages/wizard/src/__tests__/format.test.ts +++ b/packages/wizard/src/__tests__/format.test.ts @@ -71,7 +71,7 @@ describe('formatAgentOutput', () => { '## Next Steps', '', '1. Run `npx drizzle-kit generate`', - '2. Run `npx @cipherstash/cli db push`', + '2. Run `npx stash db push`', ].join('\n') const result = formatAgentOutput(input) diff --git a/packages/wizard/src/__tests__/gateway-messages.test.ts b/packages/wizard/src/__tests__/gateway-messages.test.ts index a65dc358..bb043f26 100644 --- a/packages/wizard/src/__tests__/gateway-messages.test.ts +++ b/packages/wizard/src/__tests__/gateway-messages.test.ts @@ -66,7 +66,7 @@ describe('Gateway AI Messages (integration)', () => { */ function shouldBail(res: Response): boolean { if (res.status === 401) { - console.warn('Skipping: CipherStash token expired. Run `npx @cipherstash/cli auth login`.') + console.warn('Skipping: CipherStash token expired. Run `npx stash auth login`.') return true } if (res.status === 429) { diff --git a/packages/wizard/src/__tests__/interface.test.ts b/packages/wizard/src/__tests__/interface.test.ts index f0dc252b..c2287bd6 100644 --- a/packages/wizard/src/__tests__/interface.test.ts +++ b/packages/wizard/src/__tests__/interface.test.ts @@ -65,10 +65,10 @@ describe('wizardCanUseTool', () => { expect(wizardCanUseTool('Bash', { command: 'bun run build' })).toBe(true) }) - it('allows npx drizzle-kit, tsc, and npx @cipherstash/cli db', () => { + it('allows npx drizzle-kit, tsc, and npx stash db', () => { expect(wizardCanUseTool('Bash', { command: 'npx drizzle-kit generate' })).toBe(true) expect(wizardCanUseTool('Bash', { command: 'npx tsc --noEmit' })).toBe(true) - expect(wizardCanUseTool('Bash', { command: 'npx @cipherstash/cli db push' })).toBe(true) + expect(wizardCanUseTool('Bash', { command: 'npx stash db push' })).toBe(true) }) it('blocks commands not in allowlist', () => { diff --git a/packages/wizard/src/__tests__/post-agent.test.ts b/packages/wizard/src/__tests__/post-agent.test.ts index 83faee12..880c2876 100644 --- a/packages/wizard/src/__tests__/post-agent.test.ts +++ b/packages/wizard/src/__tests__/post-agent.test.ts @@ -35,8 +35,8 @@ describe('runPostAgentSteps execution commands', () => { const commands = vi .mocked(childProcess.execSync) .mock.calls.map((c) => c[0] as string) - expect(commands).toContain('bunx @cipherstash/cli db install') - expect(commands).toContain('bunx @cipherstash/cli db push') + expect(commands).toContain('bunx stash db install') + expect(commands).toContain('bunx stash db push') // Sanity: no leftover npx forms for the cipherstash binaries. for (const cmd of commands) { expect(cmd).not.toMatch(/^npx @cipherstash/) @@ -56,8 +56,8 @@ describe('runPostAgentSteps execution commands', () => { const commands = vi .mocked(childProcess.execSync) .mock.calls.map((c) => c[0] as string) - expect(commands).toContain('bunx @cipherstash/cli db push') - expect(commands).not.toContain('bunx @cipherstash/cli db install') + expect(commands).toContain('bunx stash db push') + expect(commands).not.toContain('bunx stash db install') }) it('falls back to npx when packageManager is undefined', async () => { @@ -73,7 +73,7 @@ describe('runPostAgentSteps execution commands', () => { const commands = vi .mocked(childProcess.execSync) .mock.calls.map((c) => c[0] as string) - expect(commands).toContain('npx @cipherstash/cli db install') - expect(commands).toContain('npx @cipherstash/cli db push') + expect(commands).toContain('npx stash db install') + expect(commands).toContain('npx stash db push') }) }) diff --git a/packages/wizard/src/__tests__/prerequisites.test.ts b/packages/wizard/src/__tests__/prerequisites.test.ts index 2634aaea..34f69901 100644 --- a/packages/wizard/src/__tests__/prerequisites.test.ts +++ b/packages/wizard/src/__tests__/prerequisites.test.ts @@ -40,10 +40,10 @@ describe('checkPrerequisites missing-list copy', () => { const r = await checkPrerequisites(tmp) expect(r.ok).toBe(false) expect(r.missing.join('\n')).toContain( - 'Run: bunx @cipherstash/cli auth login', + 'Run: bunx stash auth login', ) expect(r.missing.join('\n')).toContain( - 'Run: bunx @cipherstash/cli db install', + 'Run: bunx stash db install', ) expect(r.missing.join('\n')).not.toMatch(/\bnpx\b/) }) @@ -52,14 +52,14 @@ describe('checkPrerequisites missing-list copy', () => { writeFileSync(join(tmp, 'pnpm-lock.yaml'), '') const r = await checkPrerequisites(tmp) expect(r.missing.join('\n')).toContain( - 'Run: pnpm dlx @cipherstash/cli auth login', + 'Run: pnpm dlx stash auth login', ) }) it('falls back to npx when no package manager can be detected', async () => { const r = await checkPrerequisites(tmp) expect(r.missing.join('\n')).toContain( - 'Run: npx @cipherstash/cli auth login', + 'Run: npx stash auth login', ) }) }) diff --git a/packages/wizard/src/agent/commandments.ts b/packages/wizard/src/agent/commandments.ts index c1b5c9a8..24b52398 100644 --- a/packages/wizard/src/agent/commandments.ts +++ b/packages/wizard/src/agent/commandments.ts @@ -7,7 +7,7 @@ export const COMMANDMENTS = [ 'Make targeted changes. Do not reformat or refactor unrelated code.', 'Do not embed secrets in code. Use environment variables.', 'Do not create temporary files or scripts.', - '@cipherstash/stack and @cipherstash/cli are public npm packages. Install them normally.', + '@cipherstash/stack and stash are public npm packages. Install them normally.', 'Be concise. State what you did, what to run next, and stop. No summaries or recaps.', ] as const diff --git a/packages/wizard/src/agent/errors.ts b/packages/wizard/src/agent/errors.ts index eee58cc1..49e5e9c6 100644 --- a/packages/wizard/src/agent/errors.ts +++ b/packages/wizard/src/agent/errors.ts @@ -31,7 +31,7 @@ export function classifyError( if (errorCode === 'authentication_failed') { return formatWizardError( 'Authentication failed.', - `Your CipherStash token may be expired or invalid. Run: ${runner} @cipherstash/cli auth login`, + `Your CipherStash token may be expired or invalid. Run: ${runner} stash auth login`, ) } if (errorCode === 'rate_limit') { @@ -102,7 +102,7 @@ export function classifyHttpError( if (status === 401) { return formatWizardError( 'Authentication failed (HTTP 401).', - `Your CipherStash token may be expired. Run: ${runner} @cipherstash/cli auth login`, + `Your CipherStash token may be expired. Run: ${runner} stash auth login`, ) } if (status === 429) { diff --git a/packages/wizard/src/agent/interface.ts b/packages/wizard/src/agent/interface.ts index cae06f97..5f700a90 100644 --- a/packages/wizard/src/agent/interface.ts +++ b/packages/wizard/src/agent/interface.ts @@ -66,7 +66,7 @@ const ALLOWED_BASH_COMMANDS = [ // Build & validation 'npx drizzle-kit', 'npx tsc', - 'npx @cipherstash/cli db', + 'npx stash db', 'stash db', ] diff --git a/packages/wizard/src/lib/post-agent.ts b/packages/wizard/src/lib/post-agent.ts index f0c0b9ca..89347a14 100644 --- a/packages/wizard/src/lib/post-agent.ts +++ b/packages/wizard/src/lib/post-agent.ts @@ -41,14 +41,14 @@ export async function runPostAgentSteps(opts: PostAgentOptions): Promise { cwd, ) - // Step 2: Run runner @cipherstash/cli db install if the project doesn't yet + // Step 2: Run runner stash db install if the project doesn't yet // have a stash.config.ts. `db install` scaffolds the config and installs // EQL in a single step (CIP-2986). if (!gathered.hasStashConfig) { await runStep( - `Running ${runner} @cipherstash/cli db install...`, - `${runner} @cipherstash/cli db install complete`, - `${runner} @cipherstash/cli db install`, + `Running ${runner} stash db install...`, + `${runner} stash db install complete`, + `${runner} stash db install`, cwd, ) } @@ -57,7 +57,7 @@ export async function runPostAgentSteps(opts: PostAgentOptions): Promise { await runStep( 'Pushing encryption config to database...', 'Encryption config pushed', - `${runner} @cipherstash/cli db push`, + `${runner} stash db push`, cwd, ) diff --git a/packages/wizard/src/lib/prerequisites.ts b/packages/wizard/src/lib/prerequisites.ts index 0c815fb3..ab240bd0 100644 --- a/packages/wizard/src/lib/prerequisites.ts +++ b/packages/wizard/src/lib/prerequisites.ts @@ -21,13 +21,13 @@ export async function checkPrerequisites( if (!(await hasCredentials())) { missing.push( - `Not authenticated with CipherStash. Run: ${runner} @cipherstash/cli auth login`, + `Not authenticated with CipherStash. Run: ${runner} stash auth login`, ) } if (!findStashConfig(cwd)) { missing.push( - `No stash.config.ts found. Run: ${runner} @cipherstash/cli db install`, + `No stash.config.ts found. Run: ${runner} stash db install`, ) } diff --git a/packages/wizard/src/lib/rewrite-migrations.ts b/packages/wizard/src/lib/rewrite-migrations.ts index e6ab0522..b6618f12 100644 --- a/packages/wizard/src/lib/rewrite-migrations.ts +++ b/packages/wizard/src/lib/rewrite-migrations.ts @@ -18,7 +18,7 @@ import { join } from 'node:path' * - $1: table name (without quotes) * - $2: column name (without quotes) * - * Note: a copy of this lives in `@cipherstash/cli` (`db/rewrite-migrations.ts`) + * Note: a copy of this lives in `stash` (`db/rewrite-migrations.ts`) * because cli's `db install --drizzle` uses the same fix. Both copies are * tightly coupled to drizzle-kit's output format — if drizzle-kit changes, * both need to be updated together. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 84a4ccdb..039c8c73 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -48,12 +48,12 @@ importers: e2e: dependencies: - '@cipherstash/cli': - specifier: workspace:* - version: link:../packages/cli '@cipherstash/wizard': specifier: workspace:* version: link:../packages/wizard + stash: + specifier: workspace:* + version: link:../packages/cli devDependencies: vitest: specifier: catalog:repo @@ -71,7 +71,7 @@ importers: specifier: 8.13.1 version: 8.13.1 devDependencies: - '@cipherstash/cli': + stash: specifier: workspace:* version: link:../../packages/cli tsx: diff --git a/skills/stash-cli/SKILL.md b/skills/stash-cli/SKILL.md index 28a0985e..91d23111 100644 --- a/skills/stash-cli/SKILL.md +++ b/skills/stash-cli/SKILL.md @@ -1,17 +1,17 @@ --- name: stash-cli -description: Configure and use the `@cipherstash/cli` package for project initialization, EQL database setup, encryption schema management, and Supabase integration. Replaces the legacy `@cipherstash/stack-forge` skill. The AI wizard is now a separate package (`@cipherstash/wizard`). +description: Configure and use the `stash` package for project initialization, EQL database setup, encryption schema management, and Supabase integration. Replaces the legacy `@cipherstash/stack-forge` skill. The AI wizard is now a separate package (`@cipherstash/wizard`). --- # CipherStash CLI -Configure and use `@cipherstash/cli` for project initialization, EQL database setup, encryption schema management, and Supabase integration. Previously published as `@cipherstash/stack-forge`; the `stash-forge` binary is now consolidated under `npx @cipherstash/cli`. The AI-powered wizard formerly bundled here lives in [`@cipherstash/wizard`](https://www.npmjs.com/package/@cipherstash/wizard). +Configure and use `stash` for project initialization, EQL database setup, encryption schema management, and Supabase integration. Previously published as `@cipherstash/stack-forge`; the `stash-forge` binary is now consolidated under `npx stash`. The AI-powered wizard formerly bundled here lives in [`@cipherstash/wizard`](https://www.npmjs.com/package/@cipherstash/wizard). ## Trigger Use this skill when: - The user asks about setting up CipherStash EQL in a database -- Code imports `@cipherstash/cli` (or legacy `@cipherstash/stack-forge`) +- Code imports `stash` (or legacy `@cipherstash/stack-forge`) - A `stash.config.ts` file exists or needs to be created - The user wants to install, configure, or manage the EQL extension in PostgreSQL - The user mentions "stash CLI", "stash db", "stack-forge", "stash-forge", "EQL install", or "encryption schema" @@ -21,9 +21,9 @@ Do NOT trigger when: - The user is running the AI wizard — that's `@cipherstash/wizard`, a separate package - General PostgreSQL questions unrelated to CipherStash -## What is @cipherstash/cli? +## What is stash? -`@cipherstash/cli` is a **dev-time CLI and TypeScript library** for managing CipherStash EQL (Encrypted Query Language) in PostgreSQL databases. It is a companion to the `@cipherstash/stack` runtime SDK — it handles project setup and database tooling during development while `@cipherstash/stack` handles runtime encryption/decryption operations. +`stash` is a **dev-time CLI and TypeScript library** for managing CipherStash EQL (Encrypted Query Language) in PostgreSQL databases. It is a companion to the `@cipherstash/stack` runtime SDK — it handles project setup and database tooling during development while `@cipherstash/stack` handles runtime encryption/decryption operations. Think of it like Prisma Migrate or Drizzle Kit: a dev-time tool that prepares your database while the runtime SDK handles queries. @@ -34,7 +34,7 @@ The binary is named `stash`. Top-level commands: `init`, `auth`, `db`, `schema`, ### 1. Create `stash.config.ts` in the project root ```typescript -import { defineConfig } from '@cipherstash/cli' +import { defineConfig } from 'stash' export default defineConfig({ databaseUrl: process.env.DATABASE_URL!, @@ -60,25 +60,25 @@ type StashConfig = { ## CLI Usage -The primary interface is the `@cipherstash/cli` package, run via `npx` (or your package manager's equivalent runner): +The primary interface is the `stash` package, run via `npx` (or your package manager's equivalent runner): ```bash -npx @cipherstash/cli [options] +npx stash [options] ``` ### `init` — Initialize CipherStash for your project ```bash -npx @cipherstash/cli init -npx @cipherstash/cli init --supabase -npx @cipherstash/cli init --drizzle +npx stash init +npx stash init --supabase +npx stash init --drizzle ``` Init runs nearly silently, with prompts only when it can't make a sensible default choice: 1. **Authenticate** — only prompts when not already logged in (otherwise logs `Using workspace X (region)` and proceeds). 2. **Generate encryption client** — auto-detects your framework (Drizzle from `drizzle.config.*` / `drizzle-orm` / `drizzle-kit` in `package.json`; Supabase from the `DATABASE_URL` host) and silently writes a placeholder client to `./src/encryption/index.ts`. Only prompts you if a file already exists at that path. -3. **Install dependencies** — single combined prompt for `@cipherstash/stack` and `@cipherstash/cli`. Skipped entirely when both are already in `node_modules`. +3. **Install dependencies** — single combined prompt for `@cipherstash/stack` and `stash`. Skipped entirely when both are already in `node_modules`. 4. **Print next steps** — points you at `db install` and the optional `@cipherstash/wizard` for AI-guided setup. The `--supabase` and `--drizzle` flags tailor the intro message and next-steps output. They don't drive prompts — file scaffolding uses the same auto-detection regardless. @@ -86,7 +86,7 @@ The `--supabase` and `--drizzle` flags tailor the intro message and next-steps o ### `auth login` — Authenticate with CipherStash ```bash -npx @cipherstash/cli auth login +npx stash auth login ``` Opens a browser-based device code flow and saves a token to `~/.cipherstash/auth.json`. Database-touching commands check for this file before running. @@ -94,12 +94,12 @@ Opens a browser-based device code flow and saves a token to `~/.cipherstash/auth ### `db install` — Configure the database and install EQL extensions ```bash -npx @cipherstash/cli db install -npx @cipherstash/cli db install --supabase -npx @cipherstash/cli db install --supabase --migration -npx @cipherstash/cli db install --supabase --direct -npx @cipherstash/cli db install --drizzle -npx @cipherstash/cli db install --force +npx stash db install +npx stash db install --supabase +npx stash db install --supabase --migration +npx stash db install --supabase --direct +npx stash db install --drizzle +npx stash db install --force ``` `db install` is the single command that gets a project from zero to installed EQL: @@ -148,10 +148,10 @@ Direct-push installs (`--supabase --direct`) do **not** survive `supabase db res ### `db upgrade` — Upgrade EQL extensions ```bash -npx @cipherstash/cli db upgrade -npx @cipherstash/cli db upgrade --dry-run -npx @cipherstash/cli db upgrade --supabase -npx @cipherstash/cli db upgrade --latest +npx stash db upgrade +npx stash db upgrade --dry-run +npx stash db upgrade --supabase +npx stash db upgrade --latest ``` **Flags:** @@ -168,9 +168,9 @@ The EQL install SQL is idempotent and safe to re-run. The command checks the cur ### `db validate` — Validate encryption schema ```bash -npx @cipherstash/cli db validate -npx @cipherstash/cli db validate --supabase -npx @cipherstash/cli db validate --exclude-operator-family +npx stash db validate +npx stash db validate --supabase +npx stash db validate --exclude-operator-family ``` **Flags:** @@ -196,8 +196,8 @@ Validation also runs automatically before `db push` — issues are logged as war This command is **only required when using CipherStash Proxy**. If you're using the SDK directly (Drizzle, Supabase, or plain PostgreSQL), this step is not needed — the schema lives in your application code as the source of truth. ```bash -npx @cipherstash/cli db push -npx @cipherstash/cli db push --dry-run +npx stash db push +npx stash db push --dry-run ``` **Flags:** @@ -228,7 +228,7 @@ When pushing, the CLI: ### `db status` — Show EQL installation status ```bash -npx @cipherstash/cli db status +npx stash db status ``` Reports: @@ -239,7 +239,7 @@ Reports: ### `db test-connection` — Test database connectivity ```bash -npx @cipherstash/cli db test-connection +npx stash db test-connection ``` Verifies the database URL in your config is valid and the database is reachable. Reports the database name, connected role, and PostgreSQL server version. Useful for debugging connection issues before running `db install`. @@ -247,7 +247,7 @@ Verifies the database URL in your config is valid and the database is reachable. ### `db migrate` — Run pending encrypt config migrations ```bash -npx @cipherstash/cli db migrate +npx stash db migrate ``` Not yet implemented — placeholder for future encrypt-config migration tooling. @@ -255,8 +255,8 @@ Not yet implemented — placeholder for future encrypt-config migration tooling. ### `schema build` — Generate an encryption client from your database ```bash -npx @cipherstash/cli schema build -npx @cipherstash/cli schema build --supabase +npx stash schema build +npx stash schema build --supabase ``` Connects to your database, lets you select tables and columns to encrypt, asks about searchable indexes, and generates a typed encryption client file. Reads `databaseUrl` from `stash.config.ts`. @@ -266,8 +266,8 @@ For AI-guided schema integration that edits your existing schema files in place, ### `env` — Print production env vars for deployment ```bash -npx @cipherstash/cli env -npx @cipherstash/cli env --write +npx stash env +npx stash env --write ``` Experimental. Prints the environment variables (`CS_*`) you need to deploy a CipherStash-backed app. With `--write`, writes them into a `.env.production` file. @@ -287,7 +287,7 @@ Finds and loads `stash.config.ts` from the current directory or any parent. Vali Load the bundled EQL install SQL as a string: ```typescript -import { loadBundledEqlSql } from '@cipherstash/cli' +import { loadBundledEqlSql } from 'stash' const sql = loadBundledEqlSql() // standard const sql = loadBundledEqlSql({ supabase: true }) // supabase variant @@ -301,7 +301,7 @@ Download the latest EQL install SQL from GitHub releases. ### `EQLInstaller` ```typescript -import { EQLInstaller } from '@cipherstash/cli' +import { EQLInstaller } from 'stash' const installer = new EQLInstaller({ databaseUrl: 'postgresql://...' }) ``` @@ -345,7 +345,7 @@ await installer.install({ ## Full programmatic example ```typescript -import { EQLInstaller, loadStashConfig } from '@cipherstash/cli' +import { EQLInstaller, loadStashConfig } from 'stash' const config = await loadStashConfig() const installer = new EQLInstaller({ databaseUrl: config.databaseUrl }) @@ -382,7 +382,7 @@ The database role needs `CREATE` privileges on the database and public schema, o ### Config not found -`stash.config.ts` must be in the project root or a parent directory. The file must `export default defineConfig(...)`. Or run `npx @cipherstash/cli db install` to scaffold it. +`stash.config.ts` must be in the project root or a parent directory. The file must `export default defineConfig(...)`. Or run `npx stash db install` to scaffold it. ### Supabase environments diff --git a/skills/stash-secrets/SKILL.md b/skills/stash-secrets/SKILL.md index a983c7d1..ddf5afbd 100644 --- a/skills/stash-secrets/SKILL.md +++ b/skills/stash-secrets/SKILL.md @@ -129,41 +129,41 @@ if (result.failure) { ## CLI Usage -The CLI is available via `npx @cipherstash/cli` after install. +The CLI is available via `npx stash` after install. ### Set a Secret ```bash -npx @cipherstash/cli secrets set --name DATABASE_URL --value "postgres://..." --environment production -npx @cipherstash/cli secrets set -n DATABASE_URL -V "postgres://..." -e production +npx stash secrets set --name DATABASE_URL --value "postgres://..." --environment production +npx stash secrets set -n DATABASE_URL -V "postgres://..." -e production ``` ### Get a Secret ```bash -npx @cipherstash/cli secrets get --name DATABASE_URL --environment production -npx @cipherstash/cli secrets get -n DATABASE_URL -e production +npx stash secrets get --name DATABASE_URL --environment production +npx stash secrets get -n DATABASE_URL -e production ``` ### Get Many Secrets ```bash -npx @cipherstash/cli secrets get-many --name DATABASE_URL,API_KEY --environment production -npx @cipherstash/cli secrets get-many -n DATABASE_URL,API_KEY,JWT_SECRET -e production +npx stash secrets get-many --name DATABASE_URL,API_KEY --environment production +npx stash secrets get-many -n DATABASE_URL,API_KEY,JWT_SECRET -e production ``` ### List Secrets ```bash -npx @cipherstash/cli secrets list --environment production -npx @cipherstash/cli secrets list -e production +npx stash secrets list --environment production +npx stash secrets list -e production ``` ### Delete a Secret ```bash -npx @cipherstash/cli secrets delete --name DATABASE_URL --environment production -npx @cipherstash/cli secrets delete -n DATABASE_URL -e production --yes # skip confirmation +npx stash secrets delete --name DATABASE_URL --environment production +npx stash secrets delete -n DATABASE_URL -e production --yes # skip confirmation ``` ### CLI Flag Reference