Fix Windows npm-shim claude spawn + stop leaking env in spawn errors (#63) #66

Merged
kahliburke merged 2 commits from fix/agent-spawn-error-sanitize into main 2026-07-17 19:15:57 -07:00
kahliburke commented 2026-07-17 19:15:38 -07:00 (Migrated from github.com)

Fixes #63. Two commits:

1. Resolve npm .cmd/.ps1 CLI shims (91c8ab2)

On Windows, Sys.which resolves a bare command name only as .exe — it ignores PATHEXT. So an npm-installed CLI that ships .cmd/.ps1 shims (Claude Code, gemini, …) is invisible to it and to Base.run, which ENOENTs even though claude --version works in the user's shell. launch_argv now falls back to a PATH × PATHEXT search (_which_pathext) when Sys.which returns nothing, so the shim is found and wrapped through its interpreter (cmd.exe /d /c / powershell -File) as before. Benefits every CLI spawn routed through launch_argv, not just the agent.

Verified on a real Windows instance against a claude.cmd shim:

  • Sys.which("claude")nothing (the gap)
  • _which_pathext("claude")…\claude.cmd (the fix)
  • launch_argv(["claude","-p","--foo"])["cmd.exe","/d","/c","…\claude.cmd","-p","--foo"]
  • real spawn output → fake-claude-cmd -p --foo (spawns, args passed through)

2. Sanitize spawn failures so they never leak the environment (dd0e45a)

A failed spawn raises an IOError whose text stringifies the whole setenv(cmd, env) — including the process environment (ANTHROPIC_API_KEY, …). That was surfaced verbatim via sprint(showerror, e) into the agent UI, so a user pasting Error opening agent: … into an issue leaked their credentials. backend_start now catches the spawn failure and re-raises a sanitized ErrorException built from the argv alone, with an actionable hint (Windows ENOENT → npm-shim / native-installer guidance; otherwise a PATH hint).

Tests: _which_pathext search, launch_argv PATHEXT fallback, and spawn-error sanitization (both iswin branches, asserts no secret/env in the message). 151/151 agent tests pass.

Fixes #63. Two commits: ## 1. Resolve npm `.cmd`/`.ps1` CLI shims (`91c8ab2`) On Windows, `Sys.which` resolves a bare command name **only as `.exe`** — it ignores PATHEXT. So an npm-installed CLI that ships `.cmd`/`.ps1` shims (Claude Code, gemini, …) is invisible to it and to `Base.run`, which ENOENTs even though `claude --version` works in the user's shell. `launch_argv` now falls back to a `PATH` × `PATHEXT` search (`_which_pathext`) when `Sys.which` returns nothing, so the shim is found and wrapped through its interpreter (`cmd.exe /d /c` / `powershell -File`) as before. Benefits every CLI spawn routed through `launch_argv`, not just the agent. **Verified on a real Windows instance** against a `claude.cmd` shim: - `Sys.which("claude")` → `nothing` (the gap) - `_which_pathext("claude")` → `…\claude.cmd` (the fix) - `launch_argv(["claude","-p","--foo"])` → `["cmd.exe","/d","/c","…\claude.cmd","-p","--foo"]` - real spawn output → `fake-claude-cmd -p --foo` (spawns, args passed through) ## 2. Sanitize spawn failures so they never leak the environment (`dd0e45a`) A failed spawn raises an `IOError` whose text stringifies the whole `setenv(cmd, env)` — including the process environment (`ANTHROPIC_API_KEY`, …). That was surfaced verbatim via `sprint(showerror, e)` into the agent UI, so a user pasting `Error opening agent: …` into an issue leaked their credentials. `backend_start` now catches the spawn failure and re-raises a sanitized `ErrorException` built from the argv alone, with an actionable hint (Windows ENOENT → npm-shim / native-installer guidance; otherwise a PATH hint). Tests: `_which_pathext` search, `launch_argv` PATHEXT fallback, and spawn-error sanitization (both `iswin` branches, asserts no secret/env in the message). 151/151 agent tests pass.
Sign in to join this conversation.
No description provided.