diff --git a/.agents/skills/openclaw-parallels-smoke/SKILL.md b/.agents/skills/openclaw-parallels-smoke/SKILL.md index a38bb14cb4..e7d98050c6 100644 --- a/.agents/skills/openclaw-parallels-smoke/SKILL.md +++ b/.agents/skills/openclaw-parallels-smoke/SKILL.md @@ -23,10 +23,15 @@ Use this skill for Parallels guest workflows and smoke interpretation. Do not lo - Preferred entrypoint: `pnpm test:parallels:npm-update` - Flow: fresh snapshot -> install npm package baseline -> smoke -> install current main tgz on the same guest -> smoke again. - Same-guest update verification should set the default model explicitly to `openai/gpt-5.4` before the agent turn and use a fresh explicit `--session-id` so old session model state does not leak into the check. -- Keep the aggregate npm-update Linux VM name aligned with the default Linux smoke VM (`Ubuntu 24.04.3 ARM64` on Peter's host today). Do not hardcode a different Linux guest in the wrapper unless the per-OS Linux smoke default changed too. +- The aggregate npm-update wrapper must resolve the Linux VM with the same Ubuntu fallback policy as `parallels-linux-smoke.sh` before both fresh and update lanes. On Peter's current host, missing `Ubuntu 24.04.3 ARM64` should fall back to `Ubuntu 25.10`. - On Windows same-guest update checks, restart the gateway after the npm upgrade before `gateway status` / `agent`; in-place global npm updates can otherwise leave stale hashed `dist/*` module imports alive in the running service. +- For Windows same-guest update checks, prefer the done-file/log-drain PowerShell runner pattern over one long-lived `prlctl exec ... powershell -EncodedCommand ...` transport. The guest can finish successfully while the outer `prlctl exec` still hangs. - Linux same-guest update verification should also export `HOME=/root`, pass `OPENAI_API_KEY` via `prlctl exec ... /usr/bin/env`, and use `openclaw agent --local`; the fresh Linux baseline does not rely on persisted gateway credentials. +## CLI invocation footgun + +- The Parallels smoke shell scripts should tolerate a literal bare `--` arg so `pnpm test:parallels:* -- --json` and similar forwarded invocations work without needing to call `bash scripts/e2e/...` directly. + ## macOS flow - Preferred entrypoint: `pnpm test:parallels:macos` diff --git a/scripts/e2e/parallels-linux-smoke.sh b/scripts/e2e/parallels-linux-smoke.sh index 71d503c5f8..5f07765a59 100644 --- a/scripts/e2e/parallels-linux-smoke.sh +++ b/scripts/e2e/parallels-linux-smoke.sh @@ -99,6 +99,9 @@ EOF while [[ $# -gt 0 ]]; do case "$1" in + --) + shift + ;; --vm) VM_NAME="$2" VM_NAME_EXPLICIT=1 diff --git a/scripts/e2e/parallels-macos-smoke.sh b/scripts/e2e/parallels-macos-smoke.sh index 3f2889a6b4..2a86be8529 100644 --- a/scripts/e2e/parallels-macos-smoke.sh +++ b/scripts/e2e/parallels-macos-smoke.sh @@ -133,6 +133,9 @@ EOF while [[ $# -gt 0 ]]; do case "$1" in + --) + shift + ;; --vm) VM_NAME="$2" shift 2 diff --git a/scripts/e2e/parallels-npm-update-smoke.sh b/scripts/e2e/parallels-npm-update-smoke.sh index 6ecf95df94..3668f1fa0e 100755 --- a/scripts/e2e/parallels-npm-update-smoke.sh +++ b/scripts/e2e/parallels-npm-update-smoke.sh @@ -66,6 +66,9 @@ EOF while [[ $# -gt 0 ]]; do case "$1" in + --) + shift + ;; --package-spec) PACKAGE_SPEC="$2" shift 2 @@ -91,6 +94,37 @@ done OPENAI_API_KEY_VALUE="${!OPENAI_API_KEY_ENV:-}" [[ -n "$OPENAI_API_KEY_VALUE" ]] || die "$OPENAI_API_KEY_ENV is required" +resolve_linux_vm_name() { + local json requested + json="$(prlctl list --all --json)" + requested="$LINUX_VM" + PRL_VM_JSON="$json" REQUESTED_VM_NAME="$requested" python3 - <<'PY' +import difflib +import json +import os +import sys + +payload = json.loads(os.environ["PRL_VM_JSON"]) +requested = os.environ["REQUESTED_VM_NAME"].strip() +requested_lower = requested.lower() +names = [str(item.get("name", "")).strip() for item in payload if str(item.get("name", "")).strip()] + +if requested in names: + print(requested) + raise SystemExit(0) + +ubuntu_names = [name for name in names if "ubuntu" in name.lower()] +if not ubuntu_names: + sys.exit(f"default vm not found and no Ubuntu fallback available: {requested}") + +best_name = max( + ubuntu_names, + key=lambda name: difflib.SequenceMatcher(None, requested_lower, name.lower()).ratio(), +) +print(best_name) +PY +} + resolve_latest_version() { npm view openclaw version --userconfig "$(mktemp)" } @@ -183,6 +217,53 @@ PY prlctl exec "$WINDOWS_VM" --current-user powershell.exe -NoProfile -ExecutionPolicy Bypass -EncodedCommand "$encoded" } +run_windows_script_via_log() { + local script_body="$1" + local runner_name log_name done_name done_status + runner_name="openclaw-update-$RANDOM-$RANDOM.ps1" + log_name="openclaw-update-$RANDOM-$RANDOM.log" + done_name="openclaw-update-$RANDOM-$RANDOM.done" + + guest_powershell "$(cat <