Skip to content

fix(ui): make ui:build work on Windows#52291

Open
xiwuqi wants to merge 1 commit intoopenclaw:mainfrom
xiwuqi:wuxi/fix-ui-build-windows-shell
Open

fix(ui): make ui:build work on Windows#52291
xiwuqi wants to merge 1 commit intoopenclaw:mainfrom
xiwuqi:wuxi/fix-ui-build-windows-shell

Conversation

@xiwuqi
Copy link
Copy Markdown

@xiwuqi xiwuqi commented Mar 22, 2026

Summary

  • Problem: pnpm ui:build can fail on Windows when the resolved pnpm.cmd path contains spaces, because scripts/ui.js launches shell-backed commands without quoting the executable path.
  • Additional issue found while reproducing on a clean checkout: the build auto-install path used pnpm install --prod, which skips vite and leaves the UI build unable to start.
  • What changed: quote Windows shell launcher paths before spawn/spawnSync, and make the build auto-install path install the full UI dependency set instead of production-only deps.
  • Scope boundary: no UI app code changed; this only touches the build wrapper script and its tests.

Change Type

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • Security hardening
  • Chore/infra

Scope

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

User-visible / Behavior Changes

On Windows, pnpm ui:build now works when the package manager lives under a path with spaces (for example C:\Program Files\...). On clean checkouts, the command also installs the build-time UI dependencies it needs before invoking Vite.

Security Impact

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No

Repro + Verification

Environment

  • OS: Windows 11
  • Runtime/container: Node v20.19.0 / pnpm v10.32.1
  • Relevant command: pnpm ui:build

Expected

  • pnpm ui:build should launch the resolved package-manager command correctly on Windows.
  • The command should be able to install the UI dependencies required for the build and complete successfully.

Actual before fix

  • On affected Windows setups, shell-backed launchers under paths with spaces fail before running: 'D:\Program' is not recognized ...
  • On a clean checkout in my local reproduction, the same code path also installed with --prod, so vite build failed because vite was absent.

Evidence

  • Failing repro before + passing after
  • Screenshot/recording
  • Perf numbers

Commands run:

  • pnpm exec vitest run --config vitest.config.ts test/scripts/ui.test.ts
  • pnpm ui:build

Observed after fix:

  • test/scripts/ui.test.ts: 1 passed, 6 passed tests
  • pnpm ui:build: completed successfully and emitted dist/control-ui/*

Human Verification

What I personally verified:

  • The Windows shell launcher path is now quoted when needed.
  • pnpm ui:build succeeds locally on a fresh worktree after the script changes.
  • Non-shell launchers remain unquoted.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No

Failure Recovery

  • How to disable/revert this change quickly: revert this commit
  • Known bad symptoms reviewers should watch for: none beyond the previous ui:build failures returning

Risks and Mitigations

  • Risk: quoting shell launchers on Windows could affect commands that were already quoted.
    • Mitigation: the helper preserves already-quoted commands and only touches shell-backed launchers with whitespace in the path.
  • Risk: installing full deps for build may do more work than the previous production-only install.
    • Mitigation: this is only used when UI deps are missing, and the build already requires vite/other dev-time tooling to succeed.

@openclaw-barnacle openclaw-barnacle bot added scripts Repository scripts size: XS labels Mar 22, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 22, 2026

Greptile Summary

This PR fixes two related issues that caused pnpm ui:build to fail on Windows: shell-backed launcher paths containing spaces were passed unquoted to spawn/spawnSync, causing cmd.exe to misparse the executable token; and the auto-install code path used pnpm install --prod, which excluded devDependencies such as vite, causing the build to fail on a clean checkout.

Changes:

  • Adds quoteWindowsShellCommand(cmd, platform): wraps .cmd/.bat/.com paths in double-quotes when whitespace is present; is a no-op for already-quoted commands, non-shell executables, and non-Windows platforms.
  • run and runSync now apply quoteWindowsShellCommand to the command before passing it to spawn/spawnSync, while still using the original path for createSpawnOptions so shell-mode detection (based on file extension) works correctly.
  • Removes the --prod flag and NODE_ENV=production override from the dependency auto-install path, ensuring devDependencies like vite are available for build.
  • New unit test covers the quoting helper for the three expected cases: spaced shell path → quoted; non-spaced shell path → unchanged; non-shell .exe with spaces → unchanged.

The implementation is clean and well-scoped. The logic in quoteWindowsShellCommand correctly guards against double-quoting through the startsWith('"') && endsWith('"') check. The only minor omission is a test for the already-quoted guard branch, but that path is never reached in normal operation since which() never returns a pre-quoted result.

Confidence Score: 5/5

  • Safe to merge — targeted Windows-only fix with no changes to non-Windows behaviour, UI app code, or security surface.
  • Both fixes are narrowly scoped and correct: quoting shell-backed paths only when whitespace is present and the path is not already quoted is the standard cmd.exe workaround, and removing --prod from the auto-install path is a clear correctness fix. createSpawnOptions continues to receive the original unquoted path for extension-based shell-mode detection. Tests cover the key cases. No production-path behaviour changes on Linux/macOS.
  • No files require special attention.

Reviews (1): Last reviewed commit: "fix(ui): make ui build work on Windows" | Re-trigger Greptile

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 05a293af24

ℹ️ 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".

action === "build" ? { ...process.env, NODE_ENV: "production" } : process.env;
const installArgs = action === "build" ? ["install", "--prod"] : ["install"];
runSync(runner.cmd, installArgs, installEnv);
runSync(runner.cmd, ["install"]);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Limit the fallback install to the UI package

At this line, the missing-deps fallback switched from pnpm install --prod to a bare pnpm install while createSpawnOptions() still runs it from ui/. I checked pnpm install --help, and inside a workspace that command installs dependencies for all workspace projects, not just the current package. Because depsInstalled("build") only requires vite and dompurify, pnpm ui:build now turns a clean checkout into a full workspace dev install, pulling unrelated dev/test tooling just to build the UI. That is a regression in scope and can make ui:build unexpectedly slow or fail on hosts that intentionally do not have the full repo toolchain available.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scripts Repository scripts size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Windows 下执行 pnpm ui:build 失败,报错 'D:\Program' 不是内部或外部命令

1 participant