From 44c365dea33f6fc80adfcd423d0eb0ba7426e8ed Mon Sep 17 00:00:00 2001 From: Devin Foley Date: Tue, 5 May 2026 08:00:23 -0700 Subject: [PATCH] Stop leaking host process.env into the remote Pi SSH probe (#5275) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies > - The Pi adapter runs the pi-coding-agent CLI against local, SSH, and sandbox execution targets > - The Test path's hello probe spreads the host's `process.env` into the remote process env, including the macOS PATH > - The leaked Mac PATH overrides the nvm-sourced PATH set up by `buildSshSpawnTarget`, so on a Linux SSH target `node` resolves to system Node 18 instead of nvm's Node 20+ > - pi-coding-agent v0.68 / pi-tui then crashes at `pi-tui/dist/utils.js:27` with `SyntaxError: Invalid regular expression flags` on the `/v` unicode-sets regex (a Node 20+ feature) > - This pull request stops the leak — same fix as the opencode SSH probe — by passing only user-configured adapter env to the probe when the target is remote > - The benefit is the Pi hello probe now passes end-to-end against an SSH target without the Node version mismatch ## What Changed - `packages/adapters/pi-local/src/server/test.ts` passes only the user-configured adapter env (`normalizeEnv(env)`) to `runAdapterExecutionTargetProcess` when the target is remote - Local probes still get the full `runtimeEnv` so headless permission injection keeps working ## Verification - `pnpm vitest run --no-coverage --project @paperclipai/adapter-pi-local` - `pnpm typecheck` clean - Manual: Pi hello probe goes from `pi_hello_probe_failed` (Node 18 regex error) to `pi_hello_probe_passed` against an SSH target ## Risks Low risk — same pattern shipped for opencode-local and consistent with claude-local / codex-local / gemini-local. ## Model Used Claude Opus 4.7 (1M context) ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable — pattern mirrors sibling adapters - [x] If this change affects the UI, I have included before/after screenshots — N/A (no UI) - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --- packages/adapters/pi-local/src/server/test.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/adapters/pi-local/src/server/test.ts b/packages/adapters/pi-local/src/server/test.ts index 25ef6d3e..3ea8dff2 100644 --- a/packages/adapters/pi-local/src/server/test.ts +++ b/packages/adapters/pi-local/src/server/test.ts @@ -248,6 +248,17 @@ export async function testEnvironment( args.push("--tools", "read"); if (extraArgs.length > 0) args.push(...extraArgs); + // For remote targets, do NOT spread the host process.env into the probe + // env: it leaks macOS-only PATH, HOME, TMPDIR, etc. into the remote shell. + // In particular the Mac PATH overrides the nvm-sourced PATH that + // buildSshSpawnTarget sets up, which on Linux SSH targets resolves `node` + // to /usr/bin/node (Node 18) instead of nvm's Node 22, causing pi-tui to + // crash with `Invalid regular expression flags` on its /v unicode regex. + // Match the pattern used by claude_local / codex_local / gemini_local / + // opencode_local probes: send only the user-configured adapter env across + // SSH. Local probes still get the full runtimeEnv. + const probeEnv = targetIsRemote ? normalizeEnv(env) : runtimeEnv; + try { const probe = await runAdapterExecutionTargetProcess( runId, @@ -256,7 +267,7 @@ export async function testEnvironment( args, { cwd, - env: runtimeEnv, + env: probeEnv, timeoutSec: 60, graceSec: 5, onLog: async () => {},