relayburn: install wrapper dispatches Rust burn binary via platform packages#360
relayburn: install wrapper dispatches Rust burn binary via platform packages#360willwashburn merged 3 commits intomainfrom
Conversation
…ackages Mirror the napi-rs `@relayburn/sdk-<platform>` shape: the umbrella `relayburn` package declares per-platform `@relayburn/cli-<platform>` packages as `optionalDependencies`, and the `burn` shim in `packages/relayburn/bin/burn.js` resolves and execs the prebuilt Rust binary out of whichever one npm installed. Replaces the prior dispatch through `@relayburn/cli` (TS). Per-platform packages cover darwin-arm64, darwin-x64, linux-arm64-gnu, linux-x64-gnu; Windows is forward-compat in the dispatcher mapping but not yet shipped (#359). Adds `.github/workflows/cli-build.yml` matrix build (mirrors `napi-build.yml`); the `publish:` job is left as a stub until the cutover publish.yml integration follow-up. The `bin/` directory under each platform package is gitignored — populated by the matrix build. Refs #240.
The umbrella `relayburn` package now lists per-platform Rust binary packages (`@relayburn/cli-darwin-arm64`, …) as `optionalDependencies`. Those don't exist on npm yet, so pnpm 10 silently drops them from the lockfile during install — and CI's `pnpm install --frozen-lockfile` then rejects the lockfile because the specifiers in `package.json` aren't represented. Mirror the `sdk-node` exclusion in `pnpm-workspace.yaml`: drop `packages/relayburn` from the workspace. Nothing in-repo consumes it (it's a thin install wrapper that spawns the Rust binary), so this is a no-op for everyone except the install-time path.
📝 WalkthroughWalkthroughBuilds precompiled relayburn ChangesPrebuilt CLI Distribution
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related issues
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 58733a05d2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "@relayburn/cli-darwin-arm64": "1.10.0", | ||
| "@relayburn/cli-darwin-x64": "1.10.0", | ||
| "@relayburn/cli-linux-arm64-gnu": "1.10.0", | ||
| "@relayburn/cli-linux-x64-gnu": "1.10.0" |
There was a problem hiding this comment.
Derive platform optionalDependency versions from package version
Pinning the four @relayburn/cli-* optional dependencies to 1.10.0 will drift on the next lockstep release: .github/workflows/publish.yml only bumps/publishes reader ledger analyze ingest sdk mcp cli relayburn, so relayburn@1.10.1+ will still install @relayburn/cli-*@1.10.0. That means global installs can execute an older burn binary than the wrapper version (and eventually fail if that exact version is unavailable), which is a production regression for every future release unless these versions are automatically synchronized.
Useful? React with 👍 / 👎.
| "optionalDependencies": { | ||
| "@relayburn/cli-darwin-arm64": "1.10.0", | ||
| "@relayburn/cli-darwin-x64": "1.10.0", | ||
| "@relayburn/cli-linux-arm64-gnu": "1.10.0", | ||
| "@relayburn/cli-linux-x64-gnu": "1.10.0" | ||
| }, |
There was a problem hiding this comment.
🔴 Hardcoded optionalDependencies versions will silently drift from lockstep publish bumps
The old dependency "@relayburn/cli": "workspace:*" was automatically resolved by pnpm at pnpm pack time, keeping the umbrella in sync with every lockstep release. The replacement optionalDependencies use hardcoded "1.10.0" strings that npm version (used by the Bump versions step in publish.yml:200-221) does not touch.
On the next lockstep publish, relayburn bumps to e.g. 1.11.0, but the tarball still declares @relayburn/cli-*@1.10.0 as optional deps. Those versions either won't exist on npm (if the platform packages are also bumped to 1.11.0 by the cutover pipeline) or will be stale. relayburn IS in the lockstep pipeline (publish.yml:107: packages=reader ledger analyze ingest sdk mcp cli relayburn), so this will break the very next release.
How the publish workflow bumps versions without updating optionalDependencies
The Bump step at publish.yml:207-221 runs npm version "$BUMP" --no-git-tag-version inside each package dir, which only updates the top-level version field. Neither npm version nor pnpm pack rewrites hardcoded version strings in optionalDependencies. The sdk-node package (packages/sdk-node/package.json:45-49) has the same pattern but is explicitly excluded from the lockstep workspace (pnpm-workspace.yaml:11), so the issue hasn't surfaced there.
Prompt for agents
The optionalDependencies in packages/relayburn/package.json use hardcoded version 1.10.0 for the @relayburn/cli-* platform packages. The lockstep publish workflow (publish.yml) bumps each packages version field via npm version but does NOT update optionalDependencies references. After a lockstep bump, relayburn@1.11.0 would ship declaring deps on @relayburn/cli-*@1.10.0 which is wrong.
The fix needs to happen in one of two places (or both):
1. Update the publish.yml Bump versions step (around line 200-239) to also: (a) bump the version in each packages/relayburn/npm/*/package.json, and (b) rewrite the optionalDependencies versions in packages/relayburn/package.json to match the new version. A small node script inline (similar to the lockstep-heal script) could read the new version and sed/JSON-patch both locations.
2. Alternatively, use a version range like >=1.10.0 in optionalDependencies so exact version matching isnt required. However this is unusual for the platform-package pattern (napi-rs and similar tools use exact versions) and could pull in incompatible future versions.
Option 1 is the standard approach used by napi-rs publish workflows and is recommended here.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
.github/workflows/cli-build.yml (1)
149-155: ⚡ Quick winSmoke-test the dispatcher, not just the raw binary.
These checks only execute the staged artifact directly. A bad package name, missing
bin/entry, or brokenrequire.resolvepath inpackages/relayburn/bin/burn.jswould still pass this workflow. Please add one native-leg smoke test that installs the staged platform package and runs the umbrella launcher itself.Minimal CI smoke test
- name: Smoke test (`burn --help`) # Native legs only. The aarch64-linux leg cross-compiles on an x64 # host so the runner's interpreter cannot execute the binary. if: matrix.target != 'aarch64-unknown-linux-gnu' run: | packages/relayburn/npm/${{ matrix.short }}/bin/burn --help packages/relayburn/npm/${{ matrix.short }}/bin/burn --version + npm install --no-save ./packages/relayburn/npm/${{ matrix.short }} + node packages/relayburn/bin/burn.js --help + node packages/relayburn/bin/burn.js --version🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/cli-build.yml around lines 149 - 155, Replace the direct-exec smoke test with one that installs and exercises the staged platform package so the published package metadata and bin resolution are validated: in the native-leg block that currently runs packages/relayburn/npm/${{ matrix.short }}/bin/burn --help/--version, first run an install of the staged package (e.g., npm ci / npm install ./packages/relayburn/npm/${{ matrix.short }} or npm pack + npm install the tarball) and then invoke the installed umbrella launcher (npx burn --help and npx burn --version) so that package.json "bin" resolution and require.resolve paths in packages/relayburn/bin/burn.js are exercised. Ensure this only runs for native matrix legs (keep the existing if: matrix.target != 'aarch64-unknown-linux-gnu').
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/relayburn/bin/burn.js`:
- Around line 58-84: The current startup hard-fails when the platform-specific
package (pkg from const pkg = `@relayburn/cli-${short}`) is missing; instead,
try falling back to the generic TypeScript CLI package `@relayburn/cli` before
exiting: after the require.resolve(binSpecifier) catch, attempt
require.resolve('@relayburn/cli/bin/burn' + binSuffix()) (or the appropriate
entry inside `@relayburn/cli`) and set binPath to that if it resolves; only
write the error and process.exit(1) if both resolution attempts (the
platform-specific pkg and the generic `@relayburn/cli`) fail. Keep detectShort()
logic unchanged but ensure the error message distinguishes the two resolution
failures so it's clear whether the generic fallback was attempted.
---
Nitpick comments:
In @.github/workflows/cli-build.yml:
- Around line 149-155: Replace the direct-exec smoke test with one that installs
and exercises the staged platform package so the published package metadata and
bin resolution are validated: in the native-leg block that currently runs
packages/relayburn/npm/${{ matrix.short }}/bin/burn --help/--version, first run
an install of the staged package (e.g., npm ci / npm install
./packages/relayburn/npm/${{ matrix.short }} or npm pack + npm install the
tarball) and then invoke the installed umbrella launcher (npx burn --help and
npx burn --version) so that package.json "bin" resolution and require.resolve
paths in packages/relayburn/bin/burn.js are exercised. Ensure this only runs for
native matrix legs (keep the existing if: matrix.target !=
'aarch64-unknown-linux-gnu').
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 8563599b-f523-4b0d-8bf5-907dccb3f059
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (15)
.github/workflows/cli-build.yml.gitignorepackages/relayburn/CHANGELOG.mdpackages/relayburn/README.mdpackages/relayburn/bin/burn.jspackages/relayburn/npm/darwin-arm64/README.mdpackages/relayburn/npm/darwin-arm64/package.jsonpackages/relayburn/npm/darwin-x64/README.mdpackages/relayburn/npm/darwin-x64/package.jsonpackages/relayburn/npm/linux-arm64-gnu/README.mdpackages/relayburn/npm/linux-arm64-gnu/package.jsonpackages/relayburn/npm/linux-x64-gnu/README.mdpackages/relayburn/npm/linux-x64-gnu/package.jsonpackages/relayburn/package.jsonpnpm-workspace.yaml
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/publish.yml (1)
715-745:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftSwitch relayburn and platform packages to artifact-based publishing.
The current pack/publish loop cannot handle
relayburnbecause it's excluded frompnpm-workspace.yaml(line 101), andpnpm --filteronly matches workspace members. Additionally, the platform packages (@relayburn/cli-darwin-arm64, etc.) are not listed insteps.targets.outputs.packages(line 107), so they're never packed or published. The artifacts fromcli-build.ymlare never downloaded, leavingpackages/relayburn/npm/*/bin/burnempty.Add a step before pack/publish to download artifacts from the cli-build matrix into
packages/relayburn/npm/*/bin/burn, then iterate over the platform packages inpackages/relayburn/npm/*/package.jsonto pack and publish them before publishing the umbrellarelayburnpackage.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/publish.yml around lines 715 - 745, The pack/publish loop (variables PACK_DIR, COMMON_FLAGS and the for pkg in ${{ steps.targets.outputs.packages }}) fails for non-workspace `relayburn` and missing platform artifacts; add a new step before the existing pack/publish block that downloads the cli-build matrix artifacts into packages/relayburn/npm/*/bin/burn, then modify the workflow to first iterate over platform packages discovered by reading packages/relayburn/npm/*/package.json (use their name/version to compute TARBALL_BASENAME as done in the loop) to pnpm pack (or pack existing tarballs) and npm publish them with COMMON_FLAGS, and only after those platform packages are published, proceed to package and publish the umbrella relayburn package using the existing TARBALL creation and npm publish flow so ordering and artifact availability are ensured.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In @.github/workflows/publish.yml:
- Around line 715-745: The pack/publish loop (variables PACK_DIR, COMMON_FLAGS
and the for pkg in ${{ steps.targets.outputs.packages }}) fails for
non-workspace `relayburn` and missing platform artifacts; add a new step before
the existing pack/publish block that downloads the cli-build matrix artifacts
into packages/relayburn/npm/*/bin/burn, then modify the workflow to first
iterate over platform packages discovered by reading
packages/relayburn/npm/*/package.json (use their name/version to compute
TARBALL_BASENAME as done in the loop) to pnpm pack (or pack existing tarballs)
and npm publish them with COMMON_FLAGS, and only after those platform packages
are published, proceed to package and publish the umbrella relayburn package
using the existing TARBALL creation and npm publish flow so ordering and
artifact availability are ensured.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 42a1a4d1-a16b-4eaa-9853-58e4b465925c
📒 Files selected for processing (7)
.github/workflows/cli-build.yml.github/workflows/publish.ymlpackages/relayburn/CHANGELOG.mdpackages/relayburn/README.mdpackages/relayburn/bin/burn.jspackages/relayburn/package.jsonpnpm-workspace.yaml
✅ Files skipped from review due to trivial changes (1)
- packages/relayburn/CHANGELOG.md
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/relayburn/README.md
- packages/relayburn/package.json
Summary
Switches
npm i -g relayburnto install the prebuilt Rustburnbinary instead of dispatching through the TS@relayburn/cli. Same shape the napi-rs@relayburn/sdkumbrella already uses for@relayburn/sdk-<platform>packages — except we ship native executables instead of.nodefiles.packages/relayburn/npm/<short>/:@relayburn/cli-darwin-arm64,@relayburn/cli-darwin-x64,@relayburn/cli-linux-arm64-gnu,@relayburn/cli-linux-x64-gnu. Each carriesos/cpu(andlibcfor linux glibc) filters, version-pinned at1.10.0to match the workspace.relayburnpackage drops its@relayburn/cliworkspace dep and adds the four platform packages asoptionalDependencies. npm's filters install only the matching one; theburnshimrequire.resolves@relayburn/cli-<platform>/bin/burnandspawnSyncs it with the user's argv. Exit codes propagate; signal exits map to128 + signo.process.platform === 'win32'already maps towin32-x64and appends.exe, so Add Windows targets to napi sdk-node + CLI binary distribution #359 only needs to add a matrix leg +optionalDependenciesentry..github/workflows/cli-build.ymlbuilds the four-platform matrix on PR / push (mirroringnapi-build.yml): darwin-x64 onmacos-15-intel, darwin-arm64 onmacos-14, linux-x64-gnu and linux-arm64-gnu onubuntu-latestwith the aarch64 cross-compiler. Each leg strips the binary, stages it underpackages/relayburn/npm/<short>/bin/burn, runs a--helpsmoke test (skipped on aarch64-linux because cross-compile), and uploads it as a build artifact. Thepublish:job is a stub — full publish.yml integration is the follow-up PR.bin/under each platform package is gitignored at rest; onlypackage.json+README.mdare committed.Naming
Settled on
@relayburn/cli-<platform>to be parallel with@relayburn/sdk-<platform>. No collision with the existing@relayburn/cli(the TS CLI package keeps that name without a platform suffix).End-to-end manual probe (darwin-arm64)
Built
cargo build --release --target aarch64-apple-darwin --bin burn -p relayburn-cli, staged intopackages/relayburn/npm/darwin-arm64/bin/burn,npm packed both the platform package and the umbrella, thennpm install --global --prefix $TESTDIRof both tarballs into a tmpdir.$TESTDIR/bin/burn --helpprints the Rust CLI's help,$TESTDIR/bin/burn summary --helpworks,$TESTDIR/bin/burn --versionprintsburn 1.10.0.diff <(installed-burn --help) <(cargo-built-burn --help)produces zero output (identical). No surprises.Out of scope
.github/workflows/publish.yml— cutover integration is the next PR.packages/cli/— TS CLI is still source of truth for@relayburn/cli@1.xuntil 2.0 promotes.Refs #240, forward-compat for #359.
Test plan
cli-buildmatrix passes on all four legs (darwin-arm64, darwin-x64, linux-x64-gnu, linux-arm64-gnu).build-and-test+cargo-build-and-testjobs still pass.burn --helpandburn --version).