Skip to content

Fix/compatible with native windows#48613

Open
WJX20 wants to merge 14 commits intoopenclaw:mainfrom
WJX20:fix/compatible-with-native-Windows
Open

Fix/compatible with native windows#48613
WJX20 wants to merge 14 commits intoopenclaw:mainfrom
WJX20:fix/compatible-with-native-Windows

Conversation

@WJX20
Copy link
Copy Markdown

@WJX20 WJX20 commented Mar 17, 2026

Summary

  • Problem:
  • Why it matters: Approximately 70% of the world's population uses the Windows system. If we want to promote the project, I believe it is necessary to support the native Windows system operation.The current project only supports the mac/linux and windows WSL environments, but does not support the native Windows environment.

Change Type (select all)

  • Bug fix
  • [√] Feature
  • Refactor
  • Docs
  • Security hardening
  • Chore/infra

Linked Issue/PR

Feature #48613

Changes

###package.json
update:
"canvas:a2ui:bundle": "node --import tsx scripts/bundle-a2ui.mts",

###openclaw\scripts\bundle-a2ui.mts***
create:
bundle-a2ui.mts

Security Impact (required)

If there is any risk, all you need to do is change "canvas:a2ui:bundle": "bash scripts/bundle-a2ui.sh", to "canvas:a2ui:bundle": "node --import tsx scripts/bundle-a2ui.mts",

  • OS:

  • Runtime/container: windows/Mac/Linux

  • Model/provider: zai

  • Verified scenarios: windows

Testing

All 39 unit tests in app-render.helpers.node.test.ts pass (36 existing + 3 new)

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

greptile-apps bot commented Mar 17, 2026

Greptile Summary

This PR improves cross-platform compatibility by replacing the bash-only bundle-a2ui.sh script with a cross-platform TypeScript equivalent (bundle-a2ui.mts) and updating the package.json invocation accordingly. Previously flagged issues (Chinese comments, missing error handler, mixed path separators, retained shell script) have all been addressed in this version.

Key changes:

  • package.json: canvas:a2ui:bundle now uses node --import tsx scripts/bundle-a2ui.mts instead of bash scripts/bundle-a2ui.sh, enabling native Windows support.
  • scripts/bundle-a2ui.mts: New TypeScript script that re-implements all bash logic (directory existence checks, SHA-256 hash-based cache invalidation, tsc compilation, rolldown bundling) using Node.js built-ins and pnpm exec/pnpm dlx for binary resolution.
  • scripts/bundle-a2ui.sh: Correctly deleted as dead code.
  • .github/workflows/ci.yml: Incidental indentation fix to the Python heredoc in the zizmor audit step — the new indentation correctly aligns the PY terminator at column 0 after YAML block-scalar processing, which is required for <<'PY' heredoc termination in bash.

Remaining concern: The inner try/catch around pnpm -s exec rolldown (lines 78–82) catches all non-zero exits, including genuine rolldown build errors (bad config, missing source file, etc.). This causes an unnecessary pnpm dlx rolldown download before the real error is surfaced, producing confusing duplicate error output. Checking for the binary's existence before choosing the invocation path would be cleaner and more deterministic.

Confidence Score: 3/5

  • Safe to merge with one logic concern in the rolldown error handling that may produce confusing output on build failures.
  • The core goal (replacing bash with Node.js for Windows compatibility) is well-implemented and all previous review comments have been addressed. The main remaining issue is the overly broad catch block around pnpm -s exec rolldown, which silently swallows genuine rolldown build errors and triggers an unnecessary pnpm dlx re-download before the real error is surfaced. This is a developer-experience bug rather than a correctness or security issue, but it could cause meaningful confusion during development. The incidental CI YAML fix is a net positive.
  • scripts/bundle-a2ui.mts lines 78–82 (rolldown error handling)
Prompt To Fix All With AI
This is a comment left during a code review.
Path: scripts/bundle-a2ui.mts
Line: 78-82

Comment:
**Catch-all swallows genuine build errors from rolldown**

The inner `catch` at line 80 catches **any** non-zero exit from `pnpm -s exec rolldown`, not only "rolldown binary not found in local node_modules." This means:

1. If rolldown is installed locally but the bundler config or source files have an error (syntax mistake, missing import, etc.), the first `exec` throws.
2. The `catch` silently falls back to `pnpm -s dlx rolldown`, potentially re-downloading rolldown.
3. `pnpm dlx rolldown` runs with the **same broken config**, fails again, and the outer `catch` finally surfaces the error.

Users see two sets of rolldown error output and a misleading "downloading rolldown" phase, making it look like the failure is a missing binary rather than a build problem.

A safer pattern is to probe for the binary's existence first, then choose the invocation path, rather than relying on a broad catch:

```typescript
import { existsSync } from "node:fs";

const rolldownLocalBin = path.join(ROOT_DIR, "node_modules/.bin/rolldown");
const rolldownCmd = existsSync(rolldownLocalBin)
  ? `"${rolldownLocalBin}"`
  : `pnpm -s dlx rolldown`;

exec(`${rolldownCmd} -c "${path.join(A2UI_APP_DIR, "rolldown.config.mjs")}"`);
```

This way, rolldown build errors are always surfaced immediately without the confusing re-download detour.

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

Last reviewed commit: 5dc8633

@WJX20 WJX20 closed this Mar 17, 2026
@WJX20 WJX20 reopened this Mar 17, 2026
WJX20 and others added 2 commits March 17, 2026 10:21
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
@WJX20 WJX20 closed this Mar 17, 2026
@WJX20 WJX20 reopened this Mar 17, 2026
Comment on lines +78 to +82
try {
exec(`pnpm -s exec rolldown -c "${path.join(A2UI_APP_DIR, "rolldown.config.mjs")}"`);
} catch {
exec(`pnpm -s dlx rolldown -c "${path.join(A2UI_APP_DIR, "rolldown.config.mjs")}"`);
}
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.

P1 Catch-all swallows genuine build errors from rolldown

The inner catch at line 80 catches any non-zero exit from pnpm -s exec rolldown, not only "rolldown binary not found in local node_modules." This means:

  1. If rolldown is installed locally but the bundler config or source files have an error (syntax mistake, missing import, etc.), the first exec throws.
  2. The catch silently falls back to pnpm -s dlx rolldown, potentially re-downloading rolldown.
  3. pnpm dlx rolldown runs with the same broken config, fails again, and the outer catch finally surfaces the error.

Users see two sets of rolldown error output and a misleading "downloading rolldown" phase, making it look like the failure is a missing binary rather than a build problem.

A safer pattern is to probe for the binary's existence first, then choose the invocation path, rather than relying on a broad catch:

import { existsSync } from "node:fs";

const rolldownLocalBin = path.join(ROOT_DIR, "node_modules/.bin/rolldown");
const rolldownCmd = existsSync(rolldownLocalBin)
  ? `"${rolldownLocalBin}"`
  : `pnpm -s dlx rolldown`;

exec(`${rolldownCmd} -c "${path.join(A2UI_APP_DIR, "rolldown.config.mjs")}"`);

This way, rolldown build errors are always surfaced immediately without the confusing re-download detour.

Prompt To Fix With AI
This is a comment left during a code review.
Path: scripts/bundle-a2ui.mts
Line: 78-82

Comment:
**Catch-all swallows genuine build errors from rolldown**

The inner `catch` at line 80 catches **any** non-zero exit from `pnpm -s exec rolldown`, not only "rolldown binary not found in local node_modules." This means:

1. If rolldown is installed locally but the bundler config or source files have an error (syntax mistake, missing import, etc.), the first `exec` throws.
2. The `catch` silently falls back to `pnpm -s dlx rolldown`, potentially re-downloading rolldown.
3. `pnpm dlx rolldown` runs with the **same broken config**, fails again, and the outer `catch` finally surfaces the error.

Users see two sets of rolldown error output and a misleading "downloading rolldown" phase, making it look like the failure is a missing binary rather than a build problem.

A safer pattern is to probe for the binary's existence first, then choose the invocation path, rather than relying on a broad catch:

```typescript
import { existsSync } from "node:fs";

const rolldownLocalBin = path.join(ROOT_DIR, "node_modules/.bin/rolldown");
const rolldownCmd = existsSync(rolldownLocalBin)
  ? `"${rolldownLocalBin}"`
  : `pnpm -s dlx rolldown`;

exec(`${rolldownCmd} -c "${path.join(A2UI_APP_DIR, "rolldown.config.mjs")}"`);
```

This way, rolldown build errors are always surfaced immediately without the confusing re-download detour.

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

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

Labels

scripts Repository scripts size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant