Skip to content

fix(build): make bundle-a2ui.sh work on Windows with WSL#26070

Closed
BinHPdev wants to merge 2 commits intoopenclaw:mainfrom
BinHPdev:fix/windows-wsl-bundle-build
Closed

fix(build): make bundle-a2ui.sh work on Windows with WSL#26070
BinHPdev wants to merge 2 commits intoopenclaw:mainfrom
BinHPdev:fix/windows-wsl-bundle-build

Conversation

@BinHPdev
Copy link
Copy Markdown
Contributor

@BinHPdev BinHPdev commented Feb 25, 2026

Summary

  • Replace the Node.js inline script in compute_hash with a portable pure-bash sha256sum implementation, removing the node dependency from hash computation
  • Add WSL detection to exit early using the prebuilt bundle (mirroring the existing Docker fallback pattern), avoiding pnpm-wrapped tsc/rolldown calls that also require node
  • Fix a TypeScript parameter-shadowing bug in maybeMarkAuthProfileFailure that caused TS2339 errors during build:plugin-sdk:dts

Closes #26065

Root cause

On Windows, pnpm canvas:a2ui:bundle executes bash scripts/bundle-a2ui.sh. Windows resolves bash to C:\Windows\System32\bash.exe (WSL), not Git Bash. WSL typically has no native Node.js installed, so two failure points arise:

  1. compute_hash calls node --input-type=module inline → node: command not found
  2. Even after patching (1), pnpm -s exec tsc and pnpm -s dlx rolldown invoke pnpm's own shell wrapper which also does exec node internally → same failure

A third unrelated failure also blocked the full build:

  1. maybeMarkAuthProfileFailure named its inner parameter params, shadowing RunEmbeddedPiAgentParams params. The body then accessed params.config / params.agentDir which don't exist on the inner type, causing TS2339 during build:plugin-sdk:dts.

Test plan

  • pnpm build completes without error on Windows 11 with WSL2 installed (WSL bash invoked by pnpm detects WSL, uses prebuilt bundle, exits 0)
  • pnpm canvas:a2ui:bundle completes in Git Bash / macOS / Linux (normal hash + build path via sha256sum)
  • Hash cache works correctly: running pnpm canvas:a2ui:bundle twice in Git Bash skips the second build with "A2UI bundle up to date; skipping."
  • pnpm build passes TypeScript check (build:plugin-sdk:dts step) with no TS2339 errors

🤖 Generated with Claude Code

Greptile Summary

Fixed two distinct issues: (1) WSL compatibility for bundle-a2ui.sh by adding early-exit for WSL environments and replacing Node.js hash computation with bash-native SHA256, and (2) TypeScript parameter shadowing in maybeMarkAuthProfileFailure that caused TS2339 errors.

Major changes:

  • Added WSL detection that exits early with prebuilt bundle (mirrors Docker pattern)
  • Replaced Node.js inline script with portable bash sha256sum/shasum implementation
  • Fixed parameter shadowing: renamed inner params to failureParams and corrected closure variable access (agentDir)

Issues found:

  • Hash algorithm implementation differs from original—uses hash-of-hashes instead of hashing raw file contents, which will invalidate all existing cache files

Confidence Score: 3/5

  • Safe to merge with one cache-invalidation caveat that will force a one-time rebuild for all users
  • TypeScript fix is correct and necessary. WSL detection pattern matches existing Docker fallback logic. The hash algorithm change breaks cache compatibility (one-time rebuild impact) but doesn't affect correctness—it will still detect changes properly going forward
  • Review scripts/bundle-a2ui.sh hash implementation if preserving existing cache files is important

Last reviewed commit: d565656

On Windows, pnpm resolves 'bash' to WSL (System32/bash.exe) rather than
Git Bash. WSL typically has no native Node.js, so every node-dependent
call in bundle-a2ui.sh fails (compute_hash inline script, pnpm-wrapped
tsc/rolldown).

Two fixes:
1. Replace the Node.js inline script in compute_hash with a pure-bash
   sha256sum/_sha256 implementation. sha256sum is available natively in
   WSL, Git Bash (Git for Windows), and Linux; shasum -a 256 covers macOS.
   This removes the node dependency from hash computation entirely.

2. Detect WSL via /proc/version and exit early using the prebuilt bundle
   when present, mirroring the existing Docker fallback pattern. If no
   prebuilt bundle exists in WSL, print a clear actionable error guiding
   the developer to run the script outside WSL (Git Bash or cmd).

Fixes openclaw#26065
The inner function named its parameter 'params', shadowing the outer
runEmbeddedPiAgent 'params: RunEmbeddedPiAgentParams'. The function body
then accessed 'params.config' and 'params.agentDir', which don't exist
on the inner type and caused TS2339 errors during build:plugin-sdk:dts.

Rename the inner parameter to 'failureParams' so the function body
correctly reads 'params.config' (outer RunEmbeddedPiAgentParams.config)
and 'agentDir' (the local variable resolved at line 230), matching the
signature of markAuthProfileFailure({ cfg, agentDir }).
@openclaw-barnacle openclaw-barnacle bot added scripts Repository scripts agents Agent runtime and tooling size: S labels Feb 25, 2026
Copy link
Copy Markdown
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.

2 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines +62 to +76
(
for input_path in "${INPUT_PATHS[@]}"; do
if [[ -d "$input_path" ]]; then
while IFS= read -r -d '' f; do
printf '%s\0' "${f#"$ROOT_DIR/"}"
_sha256 < "$f" | cut -d' ' -f1
printf '\0'
done < <(find "$input_path" -type f -print0 2>/dev/null | sort -z)
elif [[ -f "$input_path" ]]; then
printf '%s\0' "${input_path#"$ROOT_DIR/"}"
_sha256 < "$input_path" | cut -d' ' -f1
printf '\0'
fi
done
) | _sha256 | cut -d' ' -f1
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hash algorithm changed: old version hashed raw file contents, new version hashes the SHA256 of each file then hashes those hashes together. This breaks cache compatibility—any existing .bundle.hash will never match, forcing a rebuild on first run after this change.

Suggested change
(
for input_path in "${INPUT_PATHS[@]}"; do
if [[ -d "$input_path" ]]; then
while IFS= read -r -d '' f; do
printf '%s\0' "${f#"$ROOT_DIR/"}"
_sha256 < "$f" | cut -d' ' -f1
printf '\0'
done < <(find "$input_path" -type f -print0 2>/dev/null | sort -z)
elif [[ -f "$input_path" ]]; then
printf '%s\0' "${input_path#"$ROOT_DIR/"}"
_sha256 < "$input_path" | cut -d' ' -f1
printf '\0'
fi
done
) | _sha256 | cut -d' ' -f1
compute_hash() {
# Pure-bash hash using _sha256 — avoids Node.js, which is absent in WSL
# when bash is invoked from Windows (pnpm uses WSL bash via System32/bash.exe).
# Hashes sorted relative paths + file contents for stable cache detection.
(
for input_path in "${INPUT_PATHS[@]}"; do
if [[ -d "$input_path" ]]; then
while IFS= read -r -d '' f; do
printf '%s\0' "${f#"$ROOT_DIR/"}"
cat "$f"
printf '\0'
done < <(find "$input_path" -type f -print0 2>/dev/null | sort -z)
elif [[ -f "$input_path" ]]; then
printf '%s\0' "${input_path#"$ROOT_DIR/"}"
cat "$input_path"
printf '\0'
fi
done
) | _sha256 | cut -d' ' -f1
}
Prompt To Fix With AI
This is a comment left during a code review.
Path: scripts/bundle-a2ui.sh
Line: 62-76

Comment:
Hash algorithm changed: old version hashed raw file contents, new version hashes the SHA256 of each file then hashes those hashes together. This breaks cache compatibility—any existing `.bundle.hash` will never match, forcing a rebuild on first run after this change.

```suggestion
compute_hash() {
  # Pure-bash hash using _sha256 — avoids Node.js, which is absent in WSL
  # when bash is invoked from Windows (pnpm uses WSL bash via System32/bash.exe).
  # Hashes sorted relative paths + file contents for stable cache detection.
  (
    for input_path in "${INPUT_PATHS[@]}"; do
      if [[ -d "$input_path" ]]; then
        while IFS= read -r -d '' f; do
          printf '%s\0' "${f#"$ROOT_DIR/"}"
          cat "$f"
          printf '\0'
        done < <(find "$input_path" -type f -print0 2>/dev/null | sort -z)
      elif [[ -f "$input_path" ]]; then
        printf '%s\0' "${input_path#"$ROOT_DIR/"}"
        cat "$input_path"
        printf '\0'
      fi
    done
  ) | _sha256 | cut -d' ' -f1
}
```

How can I resolve this? If you propose a fix, please make it concise.

@BinHPdev
Copy link
Copy Markdown
Contributor Author

I finally choose to run the whole openclaw to WSL.

@Takhoffman
Copy link
Copy Markdown
Contributor

Not merged because branch is currently conflicting against main (DIRTY + CONFLICTING).

This is not doc-only and contains a real runtime fix (bundle-a2ui.sh + WSL handling), but it also changes cache semantics (hash regeneration behavior). Keep this open only if we want to keep both the WSL bypass and the TypeScript shadow fix in this PR. If this stays blocked, I recommend reopening as a clean, minimal follow-up PR from current main to avoid merge conflicts.

@BinHPdev
Copy link
Copy Markdown
Contributor Author

BinHPdev commented Mar 3, 2026

Thanks for the review @Takhoffman — good call on splitting this up.

TypeScript shadow fix: already landed on main via 6268ed5 (fix(agents): stop param shadowing in auth failure marker), so that part is no longer needed.

WSL detection: reopened as a clean, minimal PR from current main#33321. Only adds the WSL early-exit guard (mirrors the existing Docker fallback pattern). No hash algorithm changes — preserves existing cache semantics entirely.

Closing this PR in favor of #33321.

@BinHPdev BinHPdev closed this Mar 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling scripts Repository scripts size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: pnpm build fails on Windows — WSL bash invoked by pnpm cannot find node (scripts/bundle-a2ui.sh)

3 participants