Skip to content

feat: add minimal Windows bootstrap installer#3744

Merged
ericksoa merged 4 commits into
mainfrom
feat/windows-install-bootstrap
May 19, 2026
Merged

feat: add minimal Windows bootstrap installer#3744
ericksoa merged 4 commits into
mainfrom
feat/windows-install-bootstrap

Conversation

@zyang-dev

@zyang-dev zyang-dev commented May 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a minimal Windows bootstrap installer that prepares WSL 2, Ubuntu, and Docker Desktop before handing users off to the standard NemoClaw curl | bash installer.

Changes

  • Added scripts/bootstrap-windows.ps1.
  • Enables required WSL 2 Windows optional features and handles reboot continuation.
  • Detects existing Ubuntu WSL distro and checks its WSL version before converting only when needed.
  • Installs/starts Docker Desktop and verifies Docker availability from WSL when Ubuntu is already configured.
  • Opens Ubuntu for the final standard NemoClaw install command instead of duplicating install/onboard logic in PowerShell.

Type of Change

  • Code change (feature, bug fix, or refactor)
  • Code change with doc updates
  • Doc only (prose changes, no code sample modifications)
  • Doc only (includes code sample changes)

Verification

  • npx prek run --all-files passes
  • npm test passes
  • Tests added or updated for new or changed behavior
  • No secrets, API keys, or credentials committed
  • Docs updated for user-facing behavior changes
  • make docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: zyang-dev 267119621+zyang-dev@users.noreply.github.com

Summary by CodeRabbit

  • New Features
    • Added a Windows bootstrap that prepares the host for WSL2, including optional self-elevation and automatic reboot/resume.
    • Automatically detects/installs/configures the selected WSL distro and upgrades it to WSL2 if needed.
    • Optionally installs and integrates Docker Desktop with WSL and verifies engine connectivity.
    • Opens the Ubuntu environment and initiates the NemoClaw installer handoff.

Review Change Stack

Signed-off-by: zyang-dev <267119621+zyang-dev@users.noreply.github.com>
@zyang-dev zyang-dev self-assigned this May 18, 2026
@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

PowerShell bootstrap that elevates, enables WSL2 features (with reboot/resume), ensures an Ubuntu WSL distro (install/convert/set-default), optionally installs and verifies Docker Desktop integration, and hands off a curl-based NemoClaw installer command into Ubuntu.

Changes

Windows NemoClaw Bootstrap

Layer / File(s) Summary
Script header, parameters, and invocation args
scripts/bootstrap-windows.ps1
Adds SPDX header, help text, param(...) options (DistroName, InstallerUrl, InstallerArgs, InstallDockerDesktop, AutoReboot, Resume), strict/stop error handling, and RunOnce/resume argument construction.
Core utilities, window interop, and resolvers
scripts/bootstrap-windows.ps1
Win32/COM console interop, installer window title helpers, foreground/minimize behavior, resolvers for wsl.exe, Ubuntu launcher, winget.exe, optional-feature state queries, and native command wrappers.
Docker Desktop lifecycle management
scripts/bootstrap-windows.ps1
Conditional winget install of Docker Desktop, start/restart flow, engine readiness waiting (docker.exe info), and post-restart window handling.
Docker-in-WSL verification
scripts/bootstrap-windows.ps1
From the selected WSL distro runs docker info with polling and guidance; fails with instructions if Docker integration is unavailable.
RunOnce resume and reboot handling
scripts/bootstrap-windows.ps1
Registers/unregisters RunOnce resume entries, requests auto or interactive reboot when enabling WSL-related features, and manages resume bookkeeping.
Enable WSL2 Windows features
scripts/bootstrap-windows.ps1
Enables VirtualMachinePlatform and Microsoft-Windows-Subsystem-Linux, tracks restart requirement, and triggers reboot flow when needed.
WSL distro discovery and provisioning
scripts/bootstrap-windows.ps1
Lists/parses wsl -l -v, converts WSL1 to WSL2 if necessary, sets default distro, verifies distro can start, and decides if Ubuntu must be installed during handoff.
Notices, escaping, and URL validation
scripts/bootstrap-windows.ps1
User notices (WSL missing, Docker notes), argument escaping/splitting utilities, and installer URL validation to safely build the Linux installer command.
Installer command construction and Ubuntu launch
scripts/bootstrap-windows.ps1
Builds final `curl -fsSL
Handoff messaging and orchestration
scripts/bootstrap-windows.ps1
Prints handoff messages, triggers Ubuntu launch/install, and Invoke-Main sequences elevation, feature enablement, distro readiness, Docker flows, RunOnce cleanup, and final handoff.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐇 A little rabbit taps the keys tonight,
Elevates, enables, then sets things right,
Distros convert and Docker starts to hum,
Ubuntu opens — the installer will run,
NemoClaw hops in, the bootstrap’s done!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: addition of a Windows bootstrap installer script (scripts/bootstrap-windows.ps1).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/windows-install-bootstrap

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented May 18, 2026

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: wsl-e2e
Optional E2E: wsl-repo-cloud-openclaw

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • wsl-e2e (high): Best existing coverage for Windows-hosted WSL behavior. It runs on windows-latest, provisions Ubuntu WSL, builds NemoClaw inside WSL, checks Docker availability, and runs the full E2E flow when Docker is reachable. This is required because the PR changes the Windows/WSL install path and sandbox prerequisites.

Optional E2E

  • wsl-repo-cloud-openclaw (high): Scenario-runner coverage for the WSL platform path with smoke and platform-wsl validation. Useful as an additional confirmation of the WSL repo install/onboard scenario, but it is largely adjacent because it does not exercise the new PowerShell bootstrap directly.

New E2E recommendations

  • windows-bootstrap (high): No existing E2E appears to execute scripts/bootstrap-windows.ps1 itself, including elevation handling, RunOnce resume registration, WSL feature checks, Docker Desktop winget/start/restart behavior, Docker-from-WSL verification, and installer handoff command quoting. The required WSL E2E validates the downstream WSL flow but not this new bootstrap entrypoint.
    • Suggested test: windows-bootstrap-e2e

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/bootstrap-windows.ps1`:
- Around line 695-698: The installer command currently interpolates
$InstallerUrl and $InstallerArgs directly into $installerCommand, allowing
broken URLs and shell injection; fix by validating $InstallerUrl with
[System.Uri]::IsWellFormedUriString(...) and erroring on invalid input, and
safely shell-escape $InstallerUrl and each token in $InstallerArgs before
concatenation (implement a small helper like Escape-BashArg that wraps values in
single quotes and encodes embedded single quotes as '\''), then build
$installerCommand using the escaped values (e.g., $escapedUrl and $escapedArgs)
instead of raw variables so the curl ... | bash command is safe.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 457eeb14-12ec-4ad2-b482-92092aaed515

📥 Commits

Reviewing files that changed from the base of the PR and between d7bae57 and 8f55895.

📒 Files selected for processing (1)
  • scripts/bootstrap-windows.ps1

Comment thread scripts/bootstrap-windows.ps1 Outdated

@coderabbitai coderabbitai Bot left a comment

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.

🧹 Nitpick comments (2)
scripts/bootstrap-windows.ps1 (2)

87-113: ⚡ Quick win

Rename $args to avoid shadowing PowerShell's automatic variable.

$args is a built-in automatic variable containing unbound positional arguments. Assigning to it shadows this behavior and can cause subtle bugs if the function ever needs to access actual unbound arguments.

Proposed fix
 function Get-ScriptInvocationArguments {
     param([switch]$ResumeRun)

-    $args = @(
+    $scriptArgs = @(
         '-NoLogo',
         '-NoProfile',
         '-ExecutionPolicy',
         'Bypass',
         '-File',
         $PSCommandPath,
         '-DistroName',
         $DistroName,
         '-InstallerUrl',
         $InstallerUrl
     )
     if ($InstallerArgs) {
-        $args += @('-InstallerArgs', $InstallerArgs)
+        $scriptArgs += @('-InstallerArgs', $InstallerArgs)
     }
-    $args += ('-InstallDockerDesktop:{0}' -f ([bool]$InstallDockerDesktop).ToString().ToLowerInvariant())
+    $scriptArgs += ('-InstallDockerDesktop:{0}' -f ([bool]$InstallDockerDesktop).ToString().ToLowerInvariant())
     if ($AutoReboot) {
-        $args += '-AutoReboot'
+        $scriptArgs += '-AutoReboot'
     }
     if ($ResumeRun) {
-        $args += '-Resume'
+        $scriptArgs += '-Resume'
     }
-    return $args
+    return $scriptArgs
 }

Also update references in Invoke-SelfElevation (lines 127, 129).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/bootstrap-windows.ps1` around lines 87 - 113, Rename the local
variable $args in Get-ScriptInvocationArguments to a non-automatic name (e.g.
$scriptArgs) to avoid shadowing PowerShell's automatic $args; update every use
inside Get-ScriptInvocationArguments (building, appending, and returning the
array) to the new name, and then update the corresponding callers in
Invoke-SelfElevation (the places that currently reference the
returned/constructed $args at the Invoke-SelfElevation spots referenced in the
review) to use the renamed variable/return value so the function still supplies
the same argument array without clobbering the automatic variable.

676-685: 💤 Low value

Write-WslSubsystemMissingNotice is defined but never called.

This function is not invoked anywhere in the script. Consider removing it or adding the intended call site.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/bootstrap-windows.ps1` around lines 676 - 685, The function
Write-WslSubsystemMissingNotice is defined but never used; either remove it or
call it from the WSL availability check. Fix by locating the place where the
script verifies WSL state (the block that checks Windows optional features or
the routine that detects whether a distro can be installed/run) and invoke
Write-WslSubsystemMissingNotice $Name when features are enabled but the distro
failed to install/run; alternatively, delete the Write-WslSubsystemMissingNotice
function if no notice is needed. Ensure the chosen fix references the existing
Write-WslSubsystemMissingNotice symbol so the codebase no longer contains an
unused function.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@scripts/bootstrap-windows.ps1`:
- Around line 87-113: Rename the local variable $args in
Get-ScriptInvocationArguments to a non-automatic name (e.g. $scriptArgs) to
avoid shadowing PowerShell's automatic $args; update every use inside
Get-ScriptInvocationArguments (building, appending, and returning the array) to
the new name, and then update the corresponding callers in Invoke-SelfElevation
(the places that currently reference the returned/constructed $args at the
Invoke-SelfElevation spots referenced in the review) to use the renamed
variable/return value so the function still supplies the same argument array
without clobbering the automatic variable.
- Around line 676-685: The function Write-WslSubsystemMissingNotice is defined
but never used; either remove it or call it from the WSL availability check. Fix
by locating the place where the script verifies WSL state (the block that checks
Windows optional features or the routine that detects whether a distro can be
installed/run) and invoke Write-WslSubsystemMissingNotice $Name when features
are enabled but the distro failed to install/run; alternatively, delete the
Write-WslSubsystemMissingNotice function if no notice is needed. Ensure the
chosen fix references the existing Write-WslSubsystemMissingNotice symbol so the
codebase no longer contains an unused function.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: a2b2cf21-4ac0-4c72-a660-186b97a0276e

📥 Commits

Reviewing files that changed from the base of the PR and between 8f55895 and 2ea9e33.

📒 Files selected for processing (1)
  • scripts/bootstrap-windows.ps1

@ericksoa ericksoa left a comment

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.

Reviewed the current head against main. The Windows bootstrap is isolated to a new script, the installer handoff quoting issue is fixed, and the required WSL plus CI/security/self-hosted checks are green. Regression risk is mainly limited to the new bootstrap path itself.

@ericksoa ericksoa merged commit bd40d40 into main May 19, 2026
24 checks passed
@ericksoa ericksoa deleted the feat/windows-install-bootstrap branch May 19, 2026 17:52
@miyoungc miyoungc mentioned this pull request May 20, 2026
12 tasks
miyoungc added a commit that referenced this pull request May 20, 2026
## Summary
Refreshes the NemoClaw docs for v0.0.46 by updating version metadata,
release notes, and generated user skills. The refresh also keeps public
docs aligned with the docs skip list by removing non-public experimental
references from the generated output.

## Related Issue
None.

## Changes
- #3744 and #3824 -> `docs/about/release-notes.mdx`: Added Windows
bootstrap and WSL express install coverage for v0.0.46.
- #3392 -> `docs/manage-sandboxes/messaging-channels.mdx`,
`docs/reference/commands.mdx`, `docs/reference/network-policies.mdx`,
and policy examples: Refreshed public messaging channel docs around
WhatsApp and matching policy presets.
- #3742, #3767, #3732, #3786, #3777, and #3808 ->
`docs/about/release-notes.mdx`: Added release-note coverage for Hermes
managed tools, Bedrock Runtime endpoint detection, WSL Ollama proxying,
Model Router Python fallback, plugin command registration, and
tool-catalog latency improvements.
- #3124 -> `docs/about/release-notes.mdx`: Added release-note coverage
for hosted uninstall flag guidance.
- Generated `nemoclaw-user-*` skills from the updated MDX docs for the
v0.0.46 release.

## Type of Change
- [ ] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [x] Doc only (prose changes, no code sample modifications)
- [ ] Doc only (includes code sample changes)

## Verification
- [ ] `npx prek run --all-files` passes
- [ ] `npm test` passes
- [ ] Tests added or updated for new or changed behavior
- [x] No secrets, API keys, or credentials committed
- [x] Docs updated for user-facing behavior changes
- [ ] `make docs` builds without warnings (doc changes only)
- [x] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

Verification notes:
- Commit hooks passed, including markdownlint, gitleaks, docs-to-skills
verification, env-var docs, and skills YAML checks.
- `python3 scripts/docs-to-skills.py docs/ .agents/skills/ --prefix
nemoclaw-user --doc-platform fern-mdx` passed.
- `bash test/e2e/e2e-cloud-experimental/check-docs.sh --only-links
--local-only --with-skills` passed.
- `git diff --check` passed.
- `make docs` was attempted but blocked before MDX validation because
`npx` received HTTP 403 fetching `fern-api` from npm.

---
Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Released v0.0.46: improved Windows setup, WhatsApp messaging support,
Hermes sandbox/tool routing, Anthropic endpoint compatibility, Ollama
proxy routing, model-router fallback, OpenClaw plugin/backup
compatibility, sandbox build tooling fixes, and updated uninstall flag
behavior.

* **Documentation**
* Removed WeChat from messaging flows and presets across guides and CLI
docs; clarified onboarding and channel setup for WhatsApp. Clarified
runtime mutability and filesystem (Landlock) behavior — some changes
require sandbox rebuilds; prefer host-side commands for durable config.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/NVIDIA/NemoClaw/pull/3911?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@wscurran wscurran added platform: windows Affects native Windows environments platform: wsl Affects Windows Subsystem for Linux feature PR adds or expands user-visible functionality and removed Platform: Windows/WSL labels Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature PR adds or expands user-visible functionality platform: windows Affects native Windows environments platform: wsl Affects Windows Subsystem for Linux v0.0.46 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants