#6064: fix(daemon): prefer bundled node from install-cli.sh over system node
gateway
Cluster:
Node and macOS Enhancements
## Summary
The gateway install command now checks for bundled Node.js at `~/.openclaw/tools/node/bin/node` (installed by `install-cli.sh`) before falling back to system node paths like `/opt/homebrew/bin/node`.
## Problem
There was a disconnect between different components:
| Component | Knows about bundled node? |
|-----------|---------------------------|
| `install-cli.sh` | ✅ Installs and uses it |
| macOS app (`CommandResolver.swift:109`) | ✅ Adds to PATH |
| CLI `resolvePreferredNodePath()` | ❌ Only checked system paths |
This caused `openclaw gateway install` to generate LaunchAgent with Homebrew node instead of the bundled node that `install-cli.sh` installed.
## Changes
- Added `resolveBundledNodePath()` to resolve `~/.openclaw/tools/node/bin/node`
- Added `resolveBundledNodeInfo()` to check if bundled node exists and is supported
- Modified `resolvePreferredNodePath()` to check bundled node first, then fall back to system node
- Added tests for all new functionality
## Testing
- [x] All existing tests pass
- [x] New tests for bundled node resolution
- [x] `pnpm tsgo && pnpm format && pnpm lint && pnpm build && pnpm test` passes
## AI Disclosure
🤖 AI-assisted (Claude Code). Fully tested locally. Changes are understood.
Fixes #6061
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR updates the daemon’s Node runtime selection (`src/daemon/runtime-paths.ts`) to prefer a bundled Node installed by `install-cli.sh` at `~/.openclaw/tools/node/bin/node` before falling back to system Node locations, and adds coverage in `src/daemon/runtime-paths.test.ts` for the new bundled-resolution behavior.
Net effect: `openclaw gateway install` should now generate launch configuration that targets the bundled Node (when present + supported), aligning CLI behavior with the installer and macOS app PATH handling.
<h3>Confidence Score: 4/5</h3>
- This PR is generally safe to merge and matches the intended behavior change, with a small platform edge case to consider.
- The changes are localized to runtime path resolution, are covered by new tests, and preserve the existing system-node fallback behavior. The main remaining concern is a win32 edge case where `os.homedir()` may not match win32 path semantics when env vars are missing, potentially producing an invalid bundled-node candidate path.
- src/daemon/runtime-paths.ts (win32 home directory fallback behavior)
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
**Context used:**
- Context from `dashboard` - CLAUDE.md ([source](https://app.greptile.com/review/custom-context?memory=fd949e91-5c3a-4ab5-90a1-cbe184fd6ce8))
- Context from `dashboard` - AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=0d0c8278-ef8e-4d6c-ab21-f5527e322f13))
<!-- /greptile_comment -->
Most Similar PRs
#18112: fix(daemon): gateway install on macOS ignores fnm/nvm node (#18090)
by yinghaosang · 2026-02-16
86.1%
#12804: fix(daemon): use wrapper script for pnpm global installs in service...
by odinho · 2026-02-09
83.5%
#11951: Prepending Windows Node to PATH didn’t help
by tranhoangtu-it · 2026-02-08
82.5%
#22341: fix(status): detect node-only mode and show remote gateway info
by therk · 2026-02-21
80.2%
#4709: fix(daemon): include user bin dirs in macOS LaunchAgent PATH
by ekson73 · 2026-01-30
78.8%
#9200: Fix: Strip dangerous env vars from baseEnv in host execution
by vishaltandale00 · 2026-02-05
78.5%
#15475: fix(update): Handle Homebrew+Node Cellar path mismatch
by brandonwise · 2026-02-13
78.3%
#22929: Fix NODE_EXTRA_CA_CERTS missing from LaunchAgent environment on macOS
by Clawborn · 2026-02-21
78.0%
#6235: fix: from source development command
by witcxc · 2026-02-01
77.8%
#5496: Fix: Windows path separators stripped in Gateway scheduled task
by giuliozelante · 2026-01-31
77.7%