Skip to content

spike(npm): prototype npx stash proxy distribution - #398

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

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

Conversation

@coderdan

@coderdan coderdan commented May 30, 2026

Copy link
Copy Markdown
Contributor

Spike / draft implementing CIP-3824. Stacked on #397 (dan/cli-connection-flags); the review diff is limited to npm/.

Prototypes distributing CipherStash Proxy through npm so it can be launched with:

npx stash proxy --database-url postgres://user:pass@host:5432/db
npx stash proxy --psql --database-url postgres://user:pass@host:5432/db

Distribution design

  • A thin pure-JavaScript stash meta package resolves and launches the correct prebuilt Proxy binary while forwarding argv, stdio, exit status, and common termination signals.
  • Four os/cpu-filtered optional platform packages cover macOS and Linux on arm64 and x64.
  • The macOS arm64 staging path applies an ad-hoc signature and fails if signing does not succeed.
  • npm/build-binaries.sh builds and stages the current host binary.
  • npm/release-workflow.example.yml sketches a four-target build/publish matrix, including a working Linux arm64 cross setup.

--psql workflow

  • Starts Proxy and waits for its reported listen address, including an OS-assigned fallback port.
  • Launches system psql, or a pure-JavaScript SQL shell when psql is unavailable.
  • Uses a cyan stash:<db>=> prompt on interactive terminals.
  • Propagates connection URL, individual long/short flags, --flag=value forms, positional database name, and environment fallbacks using the same CLI-over-URL-over-environment precedence as Proxy.

Review fixes

  • Fixed the demo's expected-failure assertion so set -e no longer terminates it prematurely.
  • Extracted connection interpretation from the launcher and added dependency-free unit tests.
  • Preserved child signal termination semantics and added SIGQUIT forwarding.
  • Rebased onto the reviewed feat(cli): connection flags + DX (quiet logging, random port, best-effort TLS) #397 head and added required DCO sign-offs to all seven commits.

Validation

  • node --check for all launcher modules.
  • npm test: 3/3 connection-propagation tests pass.
  • bash -n npm/build-binaries.sh npm/demo.sh.
  • npm pack --dry-run for the meta package and all four platform packages.
  • Full macOS arm64 proof: release build, ad-hoc signing, local npm install, correct platform-package resolution, npx version/help passthrough, and exit-code validation.

Status / decision

This remains a non-publishable prototype: packages are private and versioned 0.0.0-prototype; no release workflow is active and no platform package has been published.

  • Decide whether to productionize this distribution channel.
  • If yes, wire the example workflow into release CI and define npm access plus synchronized package versioning.

@coderabbitai

coderabbitai Bot commented May 30, 2026

Copy link
Copy Markdown

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.

@freshtonic
freshtonic force-pushed the dan/cli-connection-flags branch from c928bdf to fde3ad2 Compare August 18, 2026 06:46
coderdan and others added 7 commits August 18, 2026 17:06
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).

Signed-off-by: James Sadler <james@cipherstash.com>
Signed-off-by: James Sadler <james@cipherstash.com>
`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.

Signed-off-by: James Sadler <james@cipherstash.com>
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.

Signed-off-by: James Sadler <james@cipherstash.com>
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.

Signed-off-by: James Sadler <james@cipherstash.com>
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).

Signed-off-by: James Sadler <james@cipherstash.com>
Signed-off-by: James Sadler <james@cipherstash.com>
@freshtonic
freshtonic force-pushed the dan/npx-stash-proxy-prototype branch from 59bed52 to 6f82ea5 Compare August 18, 2026 07:06
@freshtonic freshtonic changed the title spike(npm): distribute proxy via npx stash proxy spike(npm): prototype npx stash proxy distribution Aug 18, 2026
@freshtonic
freshtonic marked this pull request as ready for review August 18, 2026 12:19
@freshtonic freshtonic self-assigned this Aug 18, 2026
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.

2 participants