Skip to content

spike(npm): distribute proxy via npx stash proxy#398

Draft
coderdan wants to merge 6 commits into
dan/cli-connection-flagsfrom
dan/npx-stash-proxy-prototype
Draft

spike(npm): distribute proxy via npx stash proxy#398
coderdan wants to merge 6 commits into
dan/cli-connection-flagsfrom
dan/npx-stash-proxy-prototype

Conversation

@coderdan
Copy link
Copy Markdown
Contributor

Spike / draft. Stacked on #397 (dan/cli-connection-flags). Review that one first; this PR's diff is only the npm/ tree.

Prototype of distributing CipherStash Proxy via npm so people can run it with a single command:

npx stash proxy --database-url postgres://user:pass@host:5432/db
npx stash proxy --psql --database-url ...   # also opens a SQL session through the proxy

Approach

Follows the esbuild distribution pattern rather than native bindings:

  • A thin meta package (stash) with a pure-JS bin/ launcher that resolves and execs the right prebuilt binary, forwarding argv / stdio / exit codes / signals.
  • Per-platform packages (@cipherstash/proxy-{darwin,linux}-{arm64,x64}) carrying just the binary, selected automatically via os/cpu-filtered optionalDependencies.
  • macOS arm64 binaries get free ad-hoc signing (no notarization needed for local/dev use).

What's here

  • npm/packages/stash/ — launcher (bin/stash.js), binary resolver (lib/resolve.js), and a pure-JS SQL shell fallback (lib/repl.js) used when psql isn't on PATH.
  • npm/packages/proxy-*/ — the four platform package manifests.
  • npm/build-binaries.sh — builds + stages the host binary into its platform package.
  • npm/demo.sh — end-to-end local proof (build → install → run via npx and via the stash bin).
  • npm/release-workflow.example.yml — sketch of the CI matrix that would build all four targets and publish.

DX niceties (depend on #397)

Status

Proven end-to-end locally on macOS. Not wired into release CI yet; platform binaries are not published. Opening as a draft to capture the approach and gather feedback on whether to productionize.

coderdan added 6 commits May 30, 2026 13:34
Proof-of-concept for shipping the proxy via npm as `npx stash proxy`, using the
esbuild/Biome/SWC pattern (per-platform packages + os/cpu-filtered
optionalDependencies + a thin JS launcher) -- NOT native N-API bindings, since
proxy is a standalone server we only need to distribute and launch.

Verified end-to-end locally on darwin-arm64: npx -> stash shim -> exec native
cipherstash-proxy binary, with --version/--help passthrough, correct exit-code
forwarding (0 / clap's 2), signal forwarding, and os/cpu platform resolution.

Binaries are git-ignored build artifacts (build-binaries.sh / demo.sh
regenerate them). Packages are private + 0.0.0-prototype to prevent publish.
See npm/README.md for how this maps to a production CI matrix and the
code-signing rationale (skips notarization/Developer-ID; keeps free ad-hoc
signing on Apple Silicon).
`stash proxy --psql ...` starts the proxy, waits for it to report its listen
address (parsing the OS-assigned port when the default is in use), then launches
psql connected to the proxy with the target db/user/password. psql is the
foreground session; the proxy is torn down when it exits. Falls back with a
clear message if psql is not on PATH.

Connection details are taken from --database-url, then --db-* flags, then
CS_DATABASE__* env. Validated against a local dev DB.
When `--psql` is used and psql isn't on PATH (or STASH_USE_BUILTIN_SQL=1 is
set), open a small built-in SQL shell (lib/repl.js) instead of failing. It uses
the pure-JS `pg` driver (no native binaries) and runs SQL through the proxy with
tabular output and a few meta-commands (\l, \dt, \d, \?, \q).

Not a psql replacement -- a convenience fallback. Real psql is still preferred
when installed. Validated end-to-end against a local dev DB via the proxy.

Background: bundling real psql isn't viable off-the-shelf -- the
@embedded-postgres/* packages ship initdb/pg_ctl/postgres but strip psql -- so a
pure-JS shell is the pragmatic no-native-deps fallback.
Visually distinguishes a via-proxy session from a direct psql connection: the
prompt becomes e.g. `stash:mydb=>` with "stash" in cyan (on a TTY). Applied to
both real psql (via PROMPT1/PROMPT2 --set) and the built-in shell.

Override with STASH_PSQL_PROMPT (set empty to use psql's default / ~/.psqlrc);
colour honours NO_COLOR and is disabled off a TTY.
A literal ESC byte in PROMPT1 was stripped by psql's variable parser, so the
prompt showed in the default colour. psql's own %033 octal escape produces the
ESC reliably (verified: \001 ESC[36m \002 stash \001 ESC[0m \002 -- 'stash'
wrapped in cyan).
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 30, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 47445073-8e8f-45e3-832e-7997c0071df3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dan/npx-stash-proxy-prototype

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant