From aeeacf17d567b4128afd4c5f207d42700602cf30 Mon Sep 17 00:00:00 2001 From: Spooks444 <193448029+Spooks444@users.noreply.github.com> Date: Tue, 14 Jul 2026 04:39:21 -0500 Subject: [PATCH 1/3] fix(build): externalize socks + sharp in node-server bundle Bun's bundler refused to inline socks and sharp (both ship .node native addons), so the Windows node-server build failed with 'Could not resolve: socks / sharp'. Added --external socks and --external sharp to browse/scripts/build-node-server.sh, matching the script's own documented rule for .node-addon deps. Verified: bash build-node-server.sh -> exit 0, emits server-node.mjs; bun run build -> exit 0 (all 6 artifacts compile). --- browse/scripts/build-node-server.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/browse/scripts/build-node-server.sh b/browse/scripts/build-node-server.sh index 3ab652ac0..7141ae477 100755 --- a/browse/scripts/build-node-server.sh +++ b/browse/scripts/build-node-server.sh @@ -26,7 +26,9 @@ bun build "$SRC_DIR/server.ts" \ --external playwright-core \ --external diff \ --external "bun:sqlite" \ - --external "@ngrok/ngrok" + --external "@ngrok/ngrok" \ + --external socks \ + --external sharp # Step 2: Post-process # Replace import.meta.dir with a resolvable reference From f56f36d083af8eabb87e828d9d2b3cd73f06c487 Mon Sep 17 00:00:00 2001 From: Spooks444 <193448029+Spooks444@users.noreply.github.com> Date: Tue, 14 Jul 2026 06:59:56 -0500 Subject: [PATCH 2/3] fix(build): windows node pathconv + idempotent compat header - convert bun build paths to Windows-native via cygpath so the bundle actually lands on disk when MSYS_NO_PATHCONV is set - make Step 3 compat-header injection idempotent (no re-duplicate on rebuild) - drop the duplicate createRequire import (reuse bundle's own) to fix 'Identifier createRequire has already been declared' on Node 25 --- browse/scripts/build-node-server.sh | 53 ++++++++++++++++++----------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/browse/scripts/build-node-server.sh b/browse/scripts/build-node-server.sh index 7141ae477..ddd283caf 100755 --- a/browse/scripts/build-node-server.sh +++ b/browse/scripts/build-node-server.sh @@ -11,17 +11,31 @@ GSTACK_DIR="$(cd "$(dirname "$0")/../.." && pwd)" SRC_DIR="$GSTACK_DIR/browse/src" DIST_DIR="$GSTACK_DIR/browse/dist" +mkdir -p "$DIST_DIR" + +# On MSYS2/git-bash, native binaries (bun) fail to write when given a POSIX +# /c/Users/... path if MSYS_NO_PATHCONV=1 is set (bun reports "Bundled" but +# writes nothing). Always hand bun a Windows-native path. MSYS tools +# (perl/cat/cp) keep using the POSIX path, which resolves to the same file via +# the /c -> C: mount, so the two never diverge. +if command -v cygpath >/dev/null 2>&1; then + SRC_W="$(cygpath -w -a "$SRC_DIR")\\server.ts" + DIST_W="$(cygpath -w -a "$DIST_DIR")" + RAW_W="$DIST_W\\server-node.raw.mjs" +else + SRC_W="$SRC_DIR/server.ts" + DIST_W="$DIST_DIR" + RAW_W="$DIST_DIR/server-node.raw.mjs" +fi +RAW="$DIST_DIR/server-node.raw.mjs" +FINAL="$DIST_DIR/server-node.mjs" + echo "Building Node-compatible server bundle..." -# Step 1: Transpile server.ts to a single .mjs bundle (externalize runtime deps) -# -# Externalize packages with native addons, dynamic imports, or runtime resolution. -# If you add a new dependency that uses `await import()` or has a .node addon, -# add it here. Otherwise `bun build --outfile` will fail with -# "cannot write multiple output files without an output directory". -bun build "$SRC_DIR/server.ts" \ +# Step 1: bundle to a fresh raw file (no compat header yet) +bun build "$SRC_W" \ --target=node \ - --outfile "$DIST_DIR/server-node.mjs" \ + --outfile "$RAW_W" \ --external playwright \ --external playwright-core \ --external diff \ @@ -30,27 +44,26 @@ bun build "$SRC_DIR/server.ts" \ --external socks \ --external sharp -# Step 2: Post-process -# Replace import.meta.dir with a resolvable reference -perl -pi -e 's/import\.meta\.dir/__browseNodeSrcDir/g' "$DIST_DIR/server-node.mjs" -# Stub out bun:sqlite (macOS-only cookie import, not needed on Windows) -perl -pi -e 's|import { Database } from "bun:sqlite";|const Database = null; // bun:sqlite stubbed on Node|g' "$DIST_DIR/server-node.mjs" +# Step 2: post-process the raw bundle +perl -pi -e 's/import\.meta\.dir/__browseNodeSrcDir/g' "$RAW" +perl -pi -e 's|import { Database } from "bun:sqlite";|const Database = null; // bun:sqlite stubbed on Node|g' "$RAW" -# Step 3: Create the final file with polyfill header injected after the first line +# Step 3: prepend the Windows compat header. Idempotent by construction: the +# raw bundle is rebuilt from source every run (0 headers), so the header is +# added exactly once — no duplicate-identifier errors on re-runs. { - head -1 "$DIST_DIR/server-node.mjs" echo '// ── Windows Node.js compatibility (auto-generated) ──' echo 'import { fileURLToPath as _ftp } from "node:url";' echo 'import { dirname as _dn } from "node:path";' echo 'const __browseNodeSrcDir = _dn(_dn(_ftp(import.meta.url))) + "/src";' echo '{ const _r = createRequire(import.meta.url); _r("./bun-polyfill.cjs"); }' echo '// ── end compatibility ──' - tail -n +2 "$DIST_DIR/server-node.mjs" -} > "$DIST_DIR/server-node.tmp.mjs" + cat "$RAW" +} > "$FINAL" -mv "$DIST_DIR/server-node.tmp.mjs" "$DIST_DIR/server-node.mjs" +rm -f "$RAW" -# Step 4: Copy polyfill to dist/ +# Step 4: copy polyfill to dist/ cp "$SRC_DIR/bun-polyfill.cjs" "$DIST_DIR/bun-polyfill.cjs" -echo "Node server bundle ready: $DIST_DIR/server-node.mjs" +echo "Node server bundle ready: $FINAL" From 9abf03631f7a09aab751bed9b1a0179a9f953f94 Mon Sep 17 00:00:00 2001 From: Spooks444 <193448029+Spooks444@users.noreply.github.com> Date: Tue, 14 Jul 2026 07:31:35 -0500 Subject: [PATCH 3/3] fix(build): warn when compiled 'browse' CLI binary is missing build-node-server.sh only produces server-node.mjs (the Node.js server bundle). The runnable 'browse' executable is a *compiled* artifact from scripts/build.sh (bun build --compile) and is gitignored, so a bare 'rm -rf browse/dist' can leave a valid server bundle with no CLI binary. Add a Step 5 that detects the missing binary and prints remediation instead of failing later with a cryptic ENOENT. --- browse/scripts/build-node-server.sh | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/browse/scripts/build-node-server.sh b/browse/scripts/build-node-server.sh index ddd283caf..2d6ecbe29 100755 --- a/browse/scripts/build-node-server.sh +++ b/browse/scripts/build-node-server.sh @@ -66,4 +66,24 @@ rm -f "$RAW" # Step 4: copy polyfill to dist/ cp "$SRC_DIR/bun-polyfill.cjs" "$DIST_DIR/bun-polyfill.cjs" +# Step 5: guard — this script only builds the Node.js server bundle. The +# runnable `browse` CLI binary (plus find-browse/design/pdf) are *compiled* +# artifacts produced by scripts/build.sh (bun build --compile ...). They are +# gitignored and deleted by a bare `rm -rf browse/dist`, so a standalone run +# of this script can leave a working server-node.mjs with no `browse` binary. +# Warn clearly instead of letting the next `./browse/dist/browse` fail with a +# cryptic ENOENT. +BROWSE_BIN="" +for _cand in "$DIST_DIR/browse" "$DIST_DIR/browse.exe"; do + [ -f "$_cand" ] && BROWSE_BIN="$_cand" && break +done +if [ -z "$BROWSE_BIN" ]; then + echo "WARNING: compiled CLI binary 'browse' is missing from $DIST_DIR." >&2 + echo " This script only produces server-node.mjs (the Node.js server" >&2 + echo " bundle). To build the runnable 'browse' executable, run:" >&2 + echo " bash scripts/build.sh" >&2 + echo " or compile it directly:" >&2 + echo " bun build --compile browse/src/cli.ts --outfile browse/dist/browse" >&2 +fi + echo "Node server bundle ready: $FINAL"