#12804: fix(daemon): use wrapper script for pnpm global installs in service config
gateway
stale
Cluster:
Node and macOS Enhancements
## Summary
When installing the gateway service via `openclaw gateway install` from a pnpm global install, the CLI was writing the full pnpm store path into the systemd/launchd service config:
```
ExecStart="/home/user/.local/share/pnpm/5/.pnpm/openclaw@2026.2.6-3_abc123.../node_modules/openclaw/openclaw.mjs" gateway --port 18789
```
This path contains version-specific directories (including a content hash) that change with every pnpm update. After running `pnpm add -g openclaw@latest`, the old path no longer exists, and the service fails to start.
## Problem
PR #1505 attempted to fix this by preferring symlinked paths over realpath-resolved paths. However, this doesn't help pnpm global installs because:
1. The wrapper script at `~/.local/bin/openclaw` runs `exec node /full/pnpm/store/path/openclaw.mjs`
2. `process.argv[1]` is already the full versioned path (no symlink involved)
3. `normalized === resolvedPath`, so the symlink preservation logic doesn't trigger
## Solution
1. **Detect pnpm global store paths** - Check if the path contains `/.pnpm/` combined with `/.local/share/pnpm/`
2. **Prefer the wrapper script** - Look for the CLI wrapper at `~/.local/bin/openclaw` (or platform-specific equivalents)
3. **Fall back gracefully** - If the wrapper isn't found, use the original path
The wrapper script is the correct choice because pnpm automatically regenerates it with updated paths during package updates.
## Changes
- `src/daemon/program-args.ts`: Add `isPnpmGlobalStorePath()` and `resolvePnpmGlobalWrapperPath()` functions
- `src/daemon/runtime-paths.ts`: Add `/.pnpm/` to `VERSION_MANAGER_MARKERS` so doctor can warn about it
- `src/daemon/program-args.test.ts`: Add test coverage for pnpm global path detection
## Test plan
- [x] All existing tests pass
- [x] New tests for pnpm global path detection
- [x] Lint passes
## Related
- PR #1505 - Original symlink preservation fix (works for local pnpm installs, not global)
- Issue #6318 - Windows npm upgrade path fragility (similar problem domain)
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR updates daemon service argument resolution to avoid embedding pnpm global store paths (which include version/hash segments) into systemd/launchd configs. It adds pnpm-store path detection, attempts to prefer the pnpm-generated wrapper script for global installs, and expands `VERSION_MANAGER_MARKERS` so doctor can warn on `/.pnpm/` paths. Tests were added to cover wrapper preference and fallback behavior.
<h3>Confidence Score: 3/5</h3>
- This PR is close, but has a likely runtime crash and a Windows-specific parsing bug to address before merge.
- The overall approach is reasonable and covered by new tests, but `fs.constants.X_OK` is used off `node:fs/promises` (likely undefined at runtime), and Windows path parsing for extracting the CLI name is unreliable when the path contains `/` separators; both can break wrapper resolution in real installs.
- src/daemon/program-args.ts
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#6064: fix(daemon): prefer bundled node from install-cli.sh over system node
by joyshmitz · 2026-02-01
83.5%
#18961: fix: detect pnpm package manager in openclaw update
by norci · 2026-02-17
82.3%
#18112: fix(daemon): gateway install on macOS ignores fnm/nvm node (#18090)
by yinghaosang · 2026-02-16
81.2%
#4709: fix(daemon): include user bin dirs in macOS LaunchAgent PATH
by ekson73 · 2026-01-30
80.1%
#17815: fix: use $HOME as cwd for global update to prevent path-dedot panic
by frankekn · 2026-02-16
79.9%
#15345: fix(daemon): doctor --fix pollutes service PATH with dirs that don'...
by yinghaosang · 2026-02-13
79.6%
#17237: fix(update): guard post-install imports after npm global update
by tdjackey · 2026-02-15
79.5%
#11951: Prepending Windows Node to PATH didn’t help
by tranhoangtu-it · 2026-02-08
79.4%
#5496: Fix: Windows path separators stripped in Gateway scheduled task
by giuliozelante · 2026-01-31
79.3%
#22406: Fix update detection for Companion App npm-prefix installs
by graysurf · 2026-02-21
79.2%