Skip to content

Conversation

@monadoid
Copy link
Contributor

@monadoid monadoid commented Dec 19, 2025

why

We want a standalone stagehand server executable so client SDKs can spin up a local server without needing Node + the repo setup.

what changed

Adds a pnpm build:binary pipeline in packages/server that bundles + generates a SEA blob + injects it into a Node binary, and a GitHub Actions matrix workflow that builds one binary per platform and uploads them as artifacts after merges to main.

test plan

None


Summary by cubic

Adds a SEA-based standalone Stagehand server binary and a CI workflow to build per-platform executables. This lets client SDKs run a local server without installing Node or checking out the repo.

  • New Features
    • Local build: pnpm build:binary bundles the server with esbuild, creates a SEA blob, and injects it into Node to produce dist/sea/stagehand-[.exe].
    • CI: GitHub Actions matrix builds binaries for linux-x64, darwin-arm64, darwin-x64, and win32-x64 on pushes to main and uploads artifacts.
    • Added helper scripts (scripts/build.sh, scripts/create-binary.sh) and sea-config.json to support the build.

Written for commit 34bbd82. Summary will update automatically on new commits.

@changeset-bot
Copy link

changeset-bot bot commented Dec 19, 2025

⚠️ No Changeset found

Latest commit: 34bbd82

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Dec 19, 2025

Greptile Summary

Adds Single Executable Application (SEA) binary build capability for the Stagehand server, enabling client SDKs to spin up a local server without requiring Node.js or repository setup.

  • Created GitHub Actions matrix workflow that builds binaries for Linux x64, macOS ARM64/x64, and Windows x64 on every push to main
  • Added build:binary npm script that orchestrates: dependency installation, core build, esbuild bundling, SEA blob generation, and platform-specific binary creation
  • Implemented bash scripts with proper error handling, platform auto-detection, and appropriate macOS code signing
  • Added esbuild 0.27.2 and postject 1.0.0-alpha.6 as devDependencies

Critical issue: Windows workflow builds wrong package (@browserbasehq/stagehand instead of @browserbasehq/stagehand-server), which will cause the Windows binary build to fail.

Minor issue: Error message in create-binary.sh references non-existent pnpm sea:build command instead of the correct pnpm build:binary.

Confidence Score: 3/5

  • This PR has one critical logic error that will break Windows builds and one minor documentation issue
  • The Windows workflow uses the wrong package filter which will cause builds to fail. The Linux/macOS build path is solid, but this critical error in the Windows path prevents a higher score. The bash scripts are well-structured with proper error handling and platform detection.
  • .github/workflows/build-sea-server.yml requires immediate attention to fix the Windows build package filter

Important Files Changed

Filename Overview
.github/workflows/build-sea-server.yml Added workflow to build SEA binaries for multiple platforms; Windows build uses wrong package filter
packages/server/scripts/create-binary.sh Platform-specific binary creation with auto-detection; error message references non-existent command

Sequence Diagram

sequenceDiagram
    participant GHA as GitHub Actions
    participant Deps as Monorepo Dependencies
    participant Core as Stagehand Core
    participant ESBuild as esbuild
    participant Node as Node SEA
    participant Postject as postject
    participant Binary as Final Binary

    GHA->>GHA: Checkout & Setup Node 23
    GHA->>Deps: pnpm install --frozen-lockfile
    
    alt Linux/macOS
        GHA->>Core: pnpm build:binary (scripts/build.sh)
        Core->>Deps: pnpm install
        Core->>Core: pnpm --filter @browserbasehq/stagehand build
        Core->>ESBuild: Bundle src/server.ts → dist/sea/bundle.cjs
        ESBuild-->>Core: bundle.cjs created
        Core->>Node: node --experimental-sea-config sea-config.json
        Node-->>Core: sea-prep.blob generated
        Core->>Postject: scripts/create-binary.sh
        Postject->>Postject: Copy node binary
        Postject->>Postject: Inject SEA blob (platform-specific)
        alt macOS
            Postject->>Postject: codesign --remove-signature
            Postject->>Postject: Inject with --macho-segment-name
            Postject->>Postject: codesign --sign -
        else Linux
            Postject->>Postject: Inject with sentinel fuse
        end
        Postject-->>Binary: stagehand-{platform}-{arch}
    else Windows
        GHA->>Core: pnpm --filter @browserbasehq/stagehand build
        GHA->>ESBuild: Bundle src/server.ts → dist/sea/bundle.cjs
        ESBuild-->>GHA: bundle.cjs created
        GHA->>Node: node --experimental-sea-config sea-config.json
        Node-->>GHA: sea-prep.blob generated
        GHA->>Postject: Inject blob into node.exe copy
        Postject-->>Binary: stagehand-win32-x64.exe
    end
    
    GHA->>GHA: Upload artifact (30 day retention)
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 6 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="packages/server/scripts/create-binary.sh">

<violation number="1" location="packages/server/scripts/create-binary.sh:83">
P1: Cross-compilation is broken: the script accepts a target platform argument but always copies the local `node` binary regardless of the specified platform. Running `./create-binary.sh linux-x64` on macOS would produce a macOS binary incorrectly named for Linux.

Consider either:
1. Removing cross-compilation support and validating the platform matches the host
2. Downloading the correct Node.js binary for the target platform from nodejs.org</violation>
</file>
Architecture diagram
sequenceDiagram
    participant CI as "GitHub Actions\n(Matrix Strategy)"
    participant Script as "Build Scripts\n(Bash/PowerShell)"
    participant Bundler as "esbuild / Node\n(Compiler)"
    participant Injector as "postject / codesign\n(Packager)"
    participant Artifacts as "GitHub Artifacts"

    Note over CI, Artifacts: NEW: Build process triggers on push to main

    loop Per Platform (Linux, Win, Mac-x64, Mac-ARM)
        CI->>Script: Run Build Step

        Note right of CI: Matrix injects variables\n(os, arch, binary_name)

        %% Dependency Phase
        Script->>Script: Install Deps & Build Core (@browserbasehq/stagehand)

        %% Bundling Phase
        Script->>Bundler: NEW: Run esbuild (src/server.ts)
        Bundler-->>Script: Generate dist/sea/bundle.cjs

        Script->>Bundler: NEW: Node --experimental-sea-config
        Note right of Bundler: Reads sea-config.json
        Bundler-->>Script: Generate dist/sea/sea-prep.blob

        %% Binary Creation Phase
        Script->>Script: Copy local 'node' executable to dist/

        alt Platform is MacOS
            Script->>Injector: codesign --remove-signature
        end

        Script->>Injector: NEW: Inject Blob into Node Binary
        Note right of Injector: Uses "postject" to write\nblob into binary segment

        Script->>Injector: Set Sentinel Fuse
        Note right of Injector: NODE_SEA_FUSE_...

        alt Platform is MacOS
            Script->>Injector: codesign --sign - (Re-sign)
        end

        %% Validation Phase
        alt Blob or Binary Missing
            Script-->>CI: Exit Code 1 (Failure)
        else Success
            Script-->>CI: Binary Created (stagehand-platform-arch)
        end

        %% Upload Phase
        CI->>Artifacts: Upload Release Artifact
    end
Loading

Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR

Comment on lines +14 to +32
- os: ubuntu-latest
platform: linux
arch: x64
binary_name: stagehand-linux-x64

- os: macos-latest
platform: darwin
arch: arm64
binary_name: stagehand-darwin-arm64

- os: macos-13
platform: darwin
arch: x64
binary_name: stagehand-darwin-x64

- os: windows-latest
platform: win32
arch: x64
binary_name: stagehand-win32-x64.exe
Copy link
Member

@pirate pirate Dec 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need both arm64 and amd64 for windows and linux too

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.

3 participants