From e028dc07884c5397dafd95f66549d74dcaff945a Mon Sep 17 00:00:00 2001 From: "Paul Campbell (AgOS)" Date: Tue, 2 Jun 2026 20:19:04 -0700 Subject: [PATCH] feat(setup): inject Windows-node guidance into AGENTS.md after pairing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add WindowsNodeBootstrapContextStep that runs after node pairing and injects a managed BEGIN/END block into the gateway's AGENTS.md (workspace resolved from `openclaw config get agents.defaults.workspace`, or from a `WindowsNodeContext.WorkspacePath` override). The injected block tells the running OpenClaw agent how to use the paired Windows tray node (nodes tool, exec host=node, tools.exec defaults, etc.). The file mutation is pure POSIX shell + awk + base64 — no Node.js dependency, no embedded JS, no heredocs. Bare WSL distros (and the gateway distro) do not have node installed, so the previous node-based approach failed at runtime. Scripts that need bash variable handling are piped to `bash -s` via stdin instead of being passed as argv to `bash -c`, because wsl.exe performs shell variable expansion on argv before bash sees it and silently drops user-defined $var references. New docs/WSL_EXE_ARGV_PITFALL.md documents the footgun, the empirical reproduction against fresh Ubuntu-26.04, and the ranked fixes. Notable changes: * CommandRunner.RunInWslAsync gains opt-in `inputViaStdin: true` that switches argv to `bash -s` and pipes the script over stdin * WindowsNodeBootstrapContextStep computes the absolute workspace path once via ExpandLinuxPath and threads it through both `openclaw setup --workspace` and the apply script, so `~/foo` or relative-path overrides cannot land in different directories * RunOpenclawSetupAsync and ResolveWorkspacePathAsync use the stdin path because their scripts include $PATH via WslPathPrefix * Apply script is idempotent and handles missing/symlink/malformed AGENTS.md; rollback removes the managed block in-place * Cross-references in AGENTS.md and docs/WINDOWS_NODE_TESTING.md surface the pitfall doc from likely discovery points * Tests cover apply/rollback shape, override expansion, per-call stdin-vs-argv invariants, and a tilde-override regression * Verified end-to-end against bare Ubuntu-26.04 (no openclaw, no node): apply-to-missing, apply-preserves-content, idempotency (exactly 1 BEGIN marker after second apply), rollback restores original content Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- AGENTS.md | 1 + docs/ONBOARDING_WIZARD.md | 2 + docs/WINDOWS_NODE_TESTING.md | 8 + docs/WSL_EXE_ARGV_PITFALL.md | 134 +++++++ src/OpenClaw.SetupEngine/CommandRunner.cs | 87 ++++- src/OpenClaw.SetupEngine/SetupContext.cs | 10 + src/OpenClaw.SetupEngine/SetupPipeline.cs | 1 + src/OpenClaw.SetupEngine/SetupSteps.cs | 332 +++++++++++++++++- .../WindowsNodeContextSection.cs | 27 ++ src/OpenClaw.SetupEngine/default-config.json | 10 + .../SetupConfigTests.cs | 14 + .../SetupPipelineTests.cs | 5 +- .../SetupStepsTests.cs | 285 ++++++++++++++- 13 files changed, 906 insertions(+), 10 deletions(-) create mode 100644 docs/WSL_EXE_ARGV_PITFALL.md create mode 100644 src/OpenClaw.SetupEngine/WindowsNodeContextSection.cs diff --git a/AGENTS.md b/AGENTS.md index 6c288035f..5450e3b2e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -37,6 +37,7 @@ Start with these docs before changing connection, pairing, node, MCP, or tray UX - `docs/MCP_MODE.md` - local MCP server mode and the `EnableNodeMode` / `EnableMcpServer` matrix. - `docs/WINDOWS_NODE_TESTING.md` - Windows node capabilities, manual smokes, and gateway-dependent behavior. - `docs/ONBOARDING_WIZARD.md` - first-run setup flow, setup-code/bootstrap pairing, and test isolation. +- `docs/WSL_EXE_ARGV_PITFALL.md` - wsl.exe argv variable-expansion pitfall; required reading before adding any multi-line WSL script through `RunInWslAsync`. Important current facts: diff --git a/docs/ONBOARDING_WIZARD.md b/docs/ONBOARDING_WIZARD.md index f58dd1f65..34ebd127f 100644 --- a/docs/ONBOARDING_WIZARD.md +++ b/docs/ONBOARDING_WIZARD.md @@ -26,6 +26,8 @@ Installs and connects a new app-owned `OpenClawGateway` WSL instance from a clea The managed distro is locked down and is not intended to be a normal interactive Ubuntu profile. For editing `openclaw.json` as the `openclaw` user and using root for protected-file administration, see [Managing the locked-down WSL gateway](WSL_GATEWAY_ADMIN.md). +After node pairing, local WSL setup ensures OpenClaw has seeded the runtime workspace, then writes fixed Windows-node guidance into a setup-owned managed section of that workspace's `AGENTS.md`. The section is replaced idempotently between markers, preserves user-authored `AGENTS.md` content outside those markers, and does not modify OpenClaw source files. This helps the initial companion-app OpenClaw session know to use the Windows node / `nodes` tool for Windows desktop, files, screenshots, camera, notifications, browser proxy, and Windows command tasks. + ### Wizard Renders server-defined setup steps via RPC (`wizard.start` / `wizard.next`). The gateway controls the flow — steps can be: - **Note** — informational messages diff --git a/docs/WINDOWS_NODE_TESTING.md b/docs/WINDOWS_NODE_TESTING.md index c0e5cba3e..deef91590 100644 --- a/docs/WINDOWS_NODE_TESTING.md +++ b/docs/WINDOWS_NODE_TESTING.md @@ -12,6 +12,14 @@ The Windows Node feature allows the tray app to receive commands from the OpenCl 4. Toggle "Enable Node Mode" ON 5. Click Save +## Companion-App Setup Guidance + +For app-owned local WSL setup, after node pairing, setup ensures OpenClaw has seeded the runtime workspace and then injects fixed Windows-node guidance into that workspace's `AGENTS.md`. The injected block is setup-owned and idempotently replaced between managed markers, preserving any user-authored `AGENTS.md` content outside those markers and leaving OpenClaw source files unchanged. + +**Note on the apply script's WSL invocation.** The `WindowsNodeBootstrapContextStep` apply and rollback scripts are piped to `bash -s` via stdin (`RunInWslAsync(..., inputViaStdin: true)`) rather than the default `bash -c` argv path. This is required because `wsl.exe` performs shell variable expansion on argv before invoking bash, which would drop user-defined `$var` references in the multi-line script (`workspace='...'` followed by `mkdir -p "$workspace"` becomes `mkdir -p ""`). See `docs/WSL_EXE_ARGV_PITFALL.md` for the full writeup. + +The guidance helps the first companion-app OpenClaw session route Windows desktop, files, screenshots, camera, notifications, browser proxy, and Windows command tasks through the Windows node / `nodes` tool. + ## What You Can Test Now ### 1. Settings Toggle diff --git a/docs/WSL_EXE_ARGV_PITFALL.md b/docs/WSL_EXE_ARGV_PITFALL.md new file mode 100644 index 000000000..aee6d6977 --- /dev/null +++ b/docs/WSL_EXE_ARGV_PITFALL.md @@ -0,0 +1,134 @@ +# WSL.exe argv variable-expansion pitfall + +## Summary + +`wsl.exe -- bash -c