Skip to content

stash eql install --print-sql: emit the install SQL instead of only executing it #886

Description

@coderdan

Reported by a Lovable agent implementing CipherStash end-to-end in a Lovable-hosted project. Lovable runs the app in a sandbox where the database role is sandbox_exec, not postgres, and where the durable way to change the database is the platform's own migration tool, which accepts raw SQL. It ranked this the single highest-value change we could make.

The gap

stash eql install only ever executes the SQL. There is no way to obtain it.

EQLInstaller.install() (packages/cli/src/installer/index.ts:169-194) connects, wraps loadBundledEqlSql() and — in Supabase mode — SUPABASE_PERMISSIONS_SQL_V3 in a transaction, and runs them. The registry entry for eql install (packages/cli/src/cli/registry.ts:304-320) offers --force, --dry-run, --supabase and --database-url; none of them emit SQL.

On a managed platform the agent has no Postgres superuser/owner credentials but does have a privileged migration path that takes SQL. So its only options today are:

  1. Dig cipherstash-encrypt.sql out of node_modules/@cipherstash/eql/dist/sql/, and
  2. hand-reassemble the Supabase grants by reverse-engineering them out of the bundled CLI chunk.

Both version-drift silently. The reassembled grants are the worse half: get them wrong and every encrypted filter fails at query time with permission denied for schema eql_v3_internal, long after "install succeeded".

stash eql migration --supabase writes the same content into supabase/migrations/, but that assumes a Supabase CLI project layout on disk. It is not a general "give me the SQL" path.

Proposal

Add stash eql install --print-sql (and/or --output <file>): write the exact SQL the installer would run to stdout or a file, and exit without connecting to a database. Not connecting is the point — on these platforms there is no reachable database URL for the agent to supply.

Requirements:

  • Emits the complete install: the pinned EQL v3 bundle plus, in Supabase mode, the grants block. One idempotent script.
  • Honours --supabase (including the auto-detection in packages/cli/src/commands/db/install.ts:119-126 when a DATABASE_URL happens to be present — but must not require one).
  • Pairs with the owner-scoped-grant split in the sibling issue: the deferred, privileged statements should be emitted in a clearly labelled tail section rather than inlined where they will abort the transaction.

The agent instruction then collapses to one line:

npx stash eql install --print-sql --supabase > eql.sql
# pass the contents to your platform's migration tool

Why this over publishing a prebuilt .sql artefact

We considered publishing a "Supabase-ready" bundle at a stable URL for CLI-less agents. --print-sql is strictly better where the CLI can run (it did here, via npx): the SQL is pinned to the installed CLI version, so it cannot drift from what the rest of the tooling expects.

Verification note

The agent reached for the raw cipherstash-encrypt.sql release asset first, before it had confirmed the CLI could authenticate headlessly, and only switched to the CLI after stash auth login --json worked. That ordering is itself a docs problem — covered in the managed-platform skill issue.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions