Openclaw openclaw-parallels-smoke
End-to-end Parallels smoke, upgrade, and rerun workflow for OpenClaw across macOS, Windows, and Linux guests. Use when Codex needs to run, rerun, debug, or interpret VM-based install, onboarding, gateway smoke tests, latest-release-to-main upgrade checks, fresh snapshot retests, or optional Discord roundtrip verification under Parallels.
install
source · Clone the upstream repo
git clone https://github.com/openclaw/openclaw
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/openclaw "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.agents/skills/openclaw-parallels-smoke" ~/.claude/skills/openclaw-openclaw-openclaw-parallels-smoke && rm -rf "$T"
OpenClaw · Install into ~/.openclaw/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/openclaw "$T" && mkdir -p ~/.openclaw/skills && cp -r "$T/.agents/skills/openclaw-parallels-smoke" ~/.openclaw/skills/openclaw-openclaw-openclaw-parallels-smoke && rm -rf "$T"
manifest:
.agents/skills/openclaw-parallels-smoke/SKILL.mdsource content
OpenClaw Parallels Smoke
Use this skill for Parallels guest workflows and smoke interpretation. Do not load it for normal repo work.
Global rules
- Use the snapshot most closely matching the requested fresh baseline.
- Gateway verification in smoke runs should use
unless the stable version being checked does not support it yet.openclaw gateway status --deep --require-rpc - Stable
pre-upgrade diagnostics may require a plain2026.3.12
fallback.gateway status --deep - Treat
on that stable pre-upgrade lane as baseline, not automatically a regression.precheck=latest-ref-fail - Pass
for machine-readable summaries.--json - Per-phase logs land under
./tmp/openclaw-parallels-* - Do not run local and gateway agent turns in parallel on the same fresh workspace or session.
- Hard-cap every top-level Parallels lane with host
(ortimeout --foreground
if that is the available binary) so a stalled install, snapshot switch, orgtimeout --foreground
transport cannot consume the rest of the testing window. Defaults:prlctl exec- macOS:
75m - Linux:
75m - Windows:
90m - aggregate npm-update wrapper:
If a lane hits the cap, stop there, inspect the newest150m
run directory and phase log, then fix or rerun the smallest affected lane. Do not keep waiting on a capped lane./tmp/openclaw-parallels-*
- macOS:
- Actual OpenClaw npm install/update phases are a stricter budget than whole lanes: install phases should finish within 7 minutes, and update phases should finish within 5 minutes. If a phase named
,install-main
,install-latest
, orinstall-baseline
exceeds 420s, or a phase namedinstall-baseline-package
/ same-guestupdate-dev
exceeds 300s, treat it as a failure/harness bug and start diagnosis from that phase log. Do not wait for a longer lane cap.openclaw update - For a full OS matrix, prefer running independent guest-family lanes in parallel when host capacity allows:
timeout --foreground 75m pnpm test:parallels:macos -- --jsontimeout --foreground 90m pnpm test:parallels:windows -- --json
Keep each lane in its own shell/session and track the run directory for each one.timeout --foreground 75m pnpm test:parallels:linux -- --json
- Do not run multiple smoke lanes against the same guest family at once. Tahoe lanes share the host HTTP port, and Windows/Linux lanes can collide on snapshot restore/start state if two jobs touch the same VM concurrently.
- Do not run the aggregate
wrapper in parallel with individual macOS/Windows/Linux smoke lanes; it touches the same guest families and snapshots.pnpm test:parallels:npm-update - Do not start Parallels lanes while any host command may rebuild, clean, or restage
(dist
,pnpm build
,pnpm ui:build
,pnpm release:check
, npm pack/install smoke, or Docker lanes that run package/build prep). Run the build/package gates first, let them finish, then start the VM matrix. Concurrentpnpm test:install:smoke
mutation can make hostdist
fail with missing files and wastes a full VM cycle.npm pack - While running or optimizing the matrix, record wall-clock duration per lane and the slowest phase from
logs. Use that timing before changing smoke order, timeouts, or helper behavior./tmp/openclaw-parallels-* - If
is moving under active multi-agent work, prefer a detached worktree pinned to one commit for long Parallels suites. The smoke scripts now verify the packed tgz commit instead of livemain
, but a pinned worktree still avoids noisy rebuild/version drift during reruns.git rev-parse HEAD - For
lanes, remember the guest clones GitHubopenclaw update --channel dev
, not your local worktree. If a local fix exists but the rerun still fails inside the cloned dev checkout, do not treat that as disproof of the fix until the branch has been pushed.main - For
, pass the VM name beforeprlctl exec
(--current-user
), not the other way around.prlctl exec "$VM" --current-user ... - If the workflow installs OpenClaw from a repo checkout instead of the site installer/npm release, finish by installing a real guest CLI shim and verifying it in a fresh guest shell.
inside the repo is not enough for handoff parity.pnpm openclaw ... - On macOS guests, prefer a user-global install plus a stable PATH-visible shim:
- install with
NPM_CONFIG_PREFIX="$HOME/.npm-global" npm install -g . - make sure
exists or~/.local/bin/openclaw
is on PATH~/.npm-global/bin - verify from a brand-new guest shell with
andwhich openclawopenclaw --version
- install with
npm install then update
- Preferred entrypoint:
pnpm test:parallels:npm-update - Required coverage: every release/update regression run must include both lanes:
- fresh snapshot -> install requested package/baseline -> smoke
- same guest baseline -> run the guest's installed
command -> smoke againopenclaw update ...
- The update lane must exercise OpenClaw's internal updater. Do not count a direct
or harness-side package swap as update-flow coverage; those are install smokes only.npm install -g <tgz-or-spec> - For published targets, install the old baseline package first (for example
), then run the installed guest CLI with the intended channel/tag (for exampleopenclaw@2026.4.9
) and verifyopenclaw update --channel beta --yes --json
,openclaw --version
, gateway RPC, and an agent turn after the command.openclaw update status --json - For unpublished targets, pack the candidate on the host, serve the
over the harness HTTP server, and point the guest updater at that served package. Prefer.tgz
; when channel persistence also matters, passopenclaw update --tag http://<host-ip>:<port>/openclaw-<version>.tgz --yes --json
and set--channel <stable|beta>
to the same served URL in the guest update environment. The command under test must still beOPENCLAW_UPDATE_PACKAGE_SPEC
, not direct npm.openclaw update - For unpublished local-fix validation, remember the old baseline updater code still controls the first hop. A fix that lives only in the new updater code cannot change that already-running old process; the served candidate must either keep package/plugin metadata compatible with the baseline host or the baseline itself must include the updater fix.
- For beta/stable verification, resolve the tag immediately before the run (
ornpm view openclaw@beta version dist.tarball
). Tags can move while a long VM matrix is already running; restart the matrix when the intended prerelease appears after an earlier registry 404/tag-lag check.npm view openclaw@latest ... - Source Peter's profile in the host shell (
) before OpenAI/Anthropic lanes. Do not print profile contents or env dumps; pass provider secrets through the guest exec environment.set -a; source "$HOME/.profile"; set +a - Same-guest update verification should set the default model explicitly to
before the agent turn and use a fresh explicitopenai/gpt-5.4
so old session model state does not leak into the check.--session-id - The aggregate npm-update wrapper must resolve the Linux VM with the same Ubuntu fallback policy as
before both fresh and update lanes. Treat any Ubuntu guest with major versionparallels-linux-smoke.sh
as acceptable when the exact default VM is missing, preferring the closest version match. On Peter's current host today, missing>= 24
should fall back toUbuntu 24.04.3 ARM64
.Ubuntu 25.10 - On macOS same-guest update checks, restart the gateway after the npm upgrade before
/gateway status
; launchd can otherwise report a loaded service while the old process has exited and the fresh process is not RPC-ready yet.agent - The npm-update aggregate's macOS update leg writes the guest update script as root, then runs it as the desktop user. If
cannot authenticate, retry through plain rootprlctl exec "$MACOS_VM" --current-user ...
plusprlctl exec
. That is a Parallels transport fallback; still verifysudo -u <desktop-user> /usr/bin/env HOME=/Users/<desktop-user> USER=<desktop-user> LOGNAME=<desktop-user> PATH=/opt/homebrew/bin:/opt/homebrew/opt/node/bin:/usr/bin:/bin:/usr/sbin:/sbin ...
, gateway RPC, and an agent turn after the update.openclaw --version - On Windows same-guest update checks, restart the gateway after the npm upgrade before
/gateway status
; in-place global npm updates can otherwise leave stale hashedagent
module imports alive in the running service.dist/* - In those Windows same-guest update checks, do not treat one nonzero
as definitive failure. Current login-item restarts can report failure before the background service becomes observable again; follow with a longer RPC-ready wait and useopenclaw gateway restart
only as a recovery step if readiness still never returns.gateway start - After that Windows restart, do not trust one
call after a fixed sleep. Retry the RPC-ready probe for roughly 30 seconds and log each attempt; current guests can keep portgateway status --deep --require-rpc
bound while the fresh RPC endpoint is still coming up.18789 - For Windows same-guest update checks, prefer the done-file/log-drain PowerShell runner pattern over one long-lived
transport. The guest can finish successfully while the outerprlctl exec ... powershell -EncodedCommand ...
still hangs.prlctl exec - The Windows same-guest update helper should write stage markers to its log before long steps like tgz download and
so the outer progress monitor does not sit onnpm install -g
during healthy but quiet installs.waiting for first log line - Linux same-guest update verification should also export
, passHOME=/root
viaOPENAI_API_KEY
, and useprlctl exec ... /usr/bin/env
; the fresh Linux baseline does not rely on persisted gateway credentials.openclaw agent --local - The npm-update wrapper now prints per-lane progress from the nested log files. If a lane still looks stuck, inspect the nested logs in
first (runDir
,macos-fresh.log
,windows-fresh.log
,linux-fresh.log
,macos-update.log
,windows-update.log
) instead of assuming the outer wrapper hung.linux-update.log - If the wrapper fails a lane, read the auto-dumped tail first, then the full nested lane log under
./tmp/openclaw-parallels-npm-update.* - Current known macOS update-lane transport signature when the fallback is missing or bypassed:
Treat that as Parallels current-user authentication before blaming npm or OpenClaw.Unable to authenticate the user. Make sure that the specified credentials are correct and try again.
CLI invocation footgun
- The Parallels smoke shell scripts should tolerate a literal bare
arg so--
and similar forwarded invocations work without needing to callpnpm test:parallels:* -- --json
directly.bash scripts/e2e/...
macOS flow
- Preferred entrypoint:
pnpm test:parallels:macos - Default upgrade coverage on macOS should now include: fresh snapshot -> site installer pinned to the latest stable tag ->
on the guest. Treat this as part of the default Tahoe regression plan, not an optional side quest.openclaw update --channel dev
should run that release-to-dev lane by default. Keep the older host-tgz upgrade path only when the caller explicitly passesparallels-macos-smoke.sh --mode upgrade
.--target-package-spec- Because the default upgrade lane no longer needs a host tgz, skip
+ host HTTP server startup fornpm pack
unless--mode upgrade
is set. Keep the pack/server path for--target-package-spec
andfresh
.both - If that release-to-dev lane fails with
and repeatedreason=preflight-no-good-commit
tails fromsh: pnpm: command not found
, treat it as an updater regression first. The fix belongs in the git/dev updater bootstrap path, not in Parallels retry logic.preflight build - Until the public stable train includes that updater bootstrap fix, the macOS release-to-dev lane may seed a temporary guest-local
shim immediately beforepnpm
. Keep that workaround scoped to the smoke harness and remove it once the latest stable no longer needs it.openclaw update --channel dev - In Tahoe
runs, prefer explicitprlctl exec --current-user
invocations for the release->dev handoff itself and for post-update verification. The shebanged globalnode .../openclaw.mjs ...
wrapper can fail withopenclaw
, and self-updating through the wrapper is a weaker lane than invoking the entrypoint under a fixedenv: node: No such file or directory
.node - Default to the snapshot closest to
.macOS 26.3.1 latest - On Peter's Tahoe VM,
can hang infresh-latest-march-2026
; if restore times out there, rerun withprlctl snapshot-switch
before blaming auth or the harness.--snapshot-hint 'macOS 26.3.1 latest'
now retriesparallels-macos-smoke.sh
once after force-stopping a stuck running/suspended guest. If Tahoe still times out after that recovery path, then treat it as a real Parallels/host issue and rerun manually.snapshot-switch- The macOS smoke should include a dashboard load phase after gateway health: resolve the tokenized URL with
, verify the served HTML contains the Control UI title/root shell, then open Safari and require an established localhost TCP connection from Safari to the gateway port.openclaw dashboard --no-open - For Tahoe
, prefer non-TTYfresh.gateway-status
plus a few short retries.prlctl exec --current-user ... openclaw gateway status ...
can spam TTY control bytes and hang the phase log even when the CLI itself is healthy.prlctl enter - If a Tahoe lane times out in
and the phase log stops right afterfresh.first-agent-turn
from__OPENCLAW_RC__:0
, suspect themodels set
/prlctl enter
wrapper before blaming auth or the model lane. That pattern means the first guest command finished but the transport never released for the nextexpect
call.guest_current_user_cli - If a packaged install regresses with
on500
,/
, or/healthz
after__openclaw/control-ui-config.json
orfresh.install-main
, suspect bundled plugin runtime deps resolving from the package rootupgrade.install-main
rather thannode_modules
. Repro quickly with a realdist/extensions/*/node_modules
/global install lane before blaming dashboard auth or Safari.npm pack
is fine for deterministic repo commands, but use the guest Terminal orprlctl exec
when installer parity or shell-sensitive behavior matters.prlctl enter- Multi-word
checks should go through a guest shell wrapper (openclaw agent --message ...
/guest_current_user_sh
orguest_current_user_cli
), not raw/bin/sh -lc ...
, or the message can be split into extra argv tokens and Commander reportsprlctl exec ... node openclaw.mjs ...
.too many arguments for 'agent' - The same wrapper rule applies when bypassing
: write a tiny--current-user
on the guest and execute/tmp/*.sh
through the sudo desktop-user environment. Do not pass/bin/bash /tmp/*.sh
directly as one rawopenclaw agent --message '...'
command.prlctl exec - When ref-mode onboarding stores
as an env secret ref, the post-onboard agent verification should also exportOPENAI_API_KEY
for the guest command. The gateway can still reject with pairing-required and fall back to embedded execution, and that fallback needs the env-backed credential available in the shell.OPENAI_API_KEY - On the fresh Tahoe snapshot,
exists butbrew
may be missing from PATH in noninteractive exec. Usenode
when needed./opt/homebrew/bin/node - Fresh host-served tgz installs should install as guest root with
, then run onboarding as the desktop user viaHOME=/var/root
.prlctl exec --current-user - Root-installed tgz smoke can log plugin blocks for world-writable
; do not treat that as an onboarding or gateway failure unless plugin loading is the task.extensions/*
Windows flow
- Preferred entrypoint:
pnpm test:parallels:windows - Use the snapshot closest to
.pre-openclaw-native-e2e-2026-03-12 - Default upgrade coverage on Windows should now include: fresh snapshot -> site installer pinned to the requested stable tag ->
on the guest. Keep the older host-tgz upgrade path only when the caller explicitly passesopenclaw update --channel dev
.--target-package-spec - Optional exact npm-tag baseline on Windows:
. That lane installs the published npm tarball as baseline, then runsbash scripts/e2e/parallels-windows-smoke.sh --mode upgrade --target-package-spec openclaw@<tag> --json
.openclaw update --channel dev - Optional forward-fix Windows validation:
. That lane installs the packed current-main npm tgz as baseline, then runsbash scripts/e2e/parallels-windows-smoke.sh --mode upgrade --upgrade-from-packed-main --json
.openclaw update --channel dev - Always use
; plainprlctl exec --current-user
lands inprlctl exec
.NT AUTHORITY\\SYSTEM - Prefer explicit
andnpm.cmd
.openclaw.cmd - Use PowerShell only as the transport with
, then call the-ExecutionPolicy Bypass
shims from inside it..cmd - Current Windows Node installs expose
as acorepack
shim. If a release-to-dev lane sees.cmd
on PATH butcorepack
still behaves as if corepack is missing, treat that as an exec-shim regression first.openclaw update --channel dev - If an exact published-tag Windows lane fails during preflight with
andnpm run build
, remember that the guest is still executing the old published updater. Validate the fix with'pnpm' is not recognized
, then wait for the next tagged npm release before expecting the historical tag lane to pass.--upgrade-from-packed-main - Multi-word
checks should callopenclaw agent --message ...
inside PowerShell, not& $openclaw ...
againstStart-Process ... -ArgumentList
, or Commander can see split argv and throwopenclaw.cmd
.too many arguments for 'agent' - Windows installer/tgz phases now retry once after guest-ready recheck; keep new Windows smoke steps idempotent so a transport-flake retry is safe.
- If a Windows retry sees the VM become
orsuspended
, resume/start it before the nextstopped
; otherwise the second attempt just repeats the sameprlctl exec
.rc=255 - Windows global
phases can stay quiet for a minute or more even when healthy; inspect the phase log before calling it hung, and only treat it as a regression once the retry wrapper or timeout trips.npm install -g - When those Windows global installs stay quiet, the useful progress often lives in the guest npm debug log, not the helper phase log. The smoke script now streams incremental
deltas into the phase log during long baseline/package installs; read those lines before assuming the lane is stalled.npm-cache/_logs/*-debug-0.log - The Windows baseline-package helpers now auto-dump the latest guest
tail on timeout or nonzero completion. Read that tail in the phase log before opening a second guest shell.npm-cache/_logs/*-debug-0.log - The same incremental npm-debug streaming also applies to
/ packaged-install baseline phases. A phase log that still says only--upgrade-from-packed-main
,install.start
,install.download-tgz
can still be healthy if the streamed npm-debug section shows registry fetches or bundled-plugin postinstall work.install.install-tgz - Fresh Windows tgz install phases should also use the background PowerShell runner plus done-file/log-drain pattern; do not rely on one long-lived
transport for package installs.prlctl exec ... powershell ... npm install -g - Windows release-to-dev helpers should log
before and after the update and requirewhere pnpm
to succeed post-update. That proves the updater installed or enabledwhere pnpm
itself instead of depending on a smoke-only bootstrap.pnpm - Fresh Windows ref-mode onboard should use the same background PowerShell runner plus done-file/log-drain pattern as the npm-update helper, including startup materialization checks, host-side timeouts on short poll
calls, and retry-on-poll-failure behavior for transient transport flakes.prlctl exec - Fresh Windows daemon-health reachability should use
with a longer timeout and treatopenclaw gateway probe --json
as success; fullok: true
checks are too eager during initial startup on current main.gateway status --require-rpc - Fresh Windows ref-mode agent verification should set
in the PowerShell environment before invokingOPENAI_API_KEY
, for the same pairing-required fallback reason as macOS.openclaw.cmd agent - The standalone Windows upgrade smoke lane should stop the managed gateway after
and beforeupgrade.install-main
. Restarting before onboard can leave the old process alive on the pre-onboard token while onboard rewritesupgrade.onboard-ref
, which then fails~/.openclaw/openclaw.json
withgateway-health
.unauthorized: gateway token mismatch - If standalone Windows upgrade fails with a gateway token mismatch but
passes, trust the mismatch as a standalone ref-onboard ordering bug first; the npm-update helper does not re-run ref-mode onboard on the same guest.pnpm test:parallels:npm-update - Keep onboarding and status output ASCII-clean in logs; fancy punctuation becomes mojibake in current capture paths.
- If you hit an older run with
plus an emptyrc=255
orfresh.install-main.log
, treat it as a likelyupgrade.install-main.log
transport drop after guest start-up, not immediate proof of an npm/package failure.prlctl exec
Linux flow
- Preferred entrypoint:
pnpm test:parallels:linux - Use the snapshot closest to fresh
.Ubuntu 24.04.3 ARM64 - If that exact VM is missing on the host, any Ubuntu guest with major version
is acceptable; prefer the closest versioned Ubuntu guest with a fresh poweroff snapshot. On Peter's host today, that is>= 24
.Ubuntu 25.10 - Use plain
;prlctl exec
is not the right transport on this snapshot.--current-user - Fresh snapshots may be missing
, andcurl
can fail on clock skew. Bootstrap withapt-get update
and installapt-get -o Acquire::Check-Date=false update
.curl ca-certificates - Fresh
tgz smoke still needs the latest-release installer first because the snapshot has no Node or npm before bootstrap.main - This snapshot does not have a usable
session; managed daemon install is unsupported.systemd --user - The Linux smoke now falls back to a manual
launch withsetsid openclaw gateway run --bind loopback --port 18789 --force
and the provider secret exported, then verifiesHOME=/root
when available.gateway status --deep --require-rpc - The Linux manual gateway launch should wait for
inside thegateway status --deep --require-rpc
phase; otherwise the first status probe can race the background bind and fail a healthy lane.gateway-start - If Linux gateway bring-up fails, inspect
in the guest phase logs first; the common failure mode is a missing provider secret in the launched gateway environment./tmp/openclaw-parallels-linux-gateway.log
Discord roundtrip
- Discord roundtrip is optional and should be enabled with:
--discord-token-env--discord-guild-id--discord-channel-id
- Keep the Discord token only in a host env var.
- Use installed
, notopenclaw message send/read
.node openclaw.mjs message ... - Set
as one JSON object, not dotted config paths with snowflakes.channels.discord.guilds - Avoid long
or expect-driven Discord config scripts; preferprlctl enter
with short commands.prlctl exec --current-user /bin/sh -lc ... - For a narrower macOS-only Discord proof run, the existing
skill is the deep-dive companion.parallels-discord-roundtrip