Skip to content

[PF-24] Sandbox PATH resolution and Windows EINVAL fix for Claude/Codex - #25

Merged
chucoding merged 3 commits into
developfrom
bugfix/PF-24
Mar 14, 2026
Merged

[PF-24] Sandbox PATH resolution and Windows EINVAL fix for Claude/Codex#25
chucoding merged 3 commits into
developfrom
bugfix/PF-24

Conversation

@chucoding

Copy link
Copy Markdown
Owner

Purpose

Make both Claude and Codex CLIs run reliably in Cursor agent sandbox (PowerShell on Windows, macOS) by (1) resolving executables from common npm global paths when PATH is restricted, and (2) avoiding EINVAL on Windows by running .cmd via PowerShell instead of spawning them directly.

Description

Related Notion: Sandbox Path

Summary of changes:

Area File(s) Change
cli-js shell packages/cli-js/src/utils/shell.ts Added getNpmGlobalExeCandidates(cmd) and resolveCommandPathWithNpmFallback(cmd) for PATH + npm global fallback (Windows: APPDATA/LOCALAPPDATA npm; Unix: HOME-based paths).
cli-js Claude packages/cli-js/src/providers/claude.ts resolveClaudeExe() now uses the shared fallback. completeOneTurn and runClaudeStreaming on Windows use a temp file + PowerShell script (Get-Content ... | & 'exe') so .cmd is never spawned directly (avoids EINVAL / CVE-2024-27980).
cli-js Codex packages/cli-js/src/providers/codex.ts Added resolveCodexExe(). checkCodex / listModelsCodex use fallback. runCodexExec and runCodexExecStreaming resolve exe first; on Windows the script uses & 'escapedExe' exec -, on non-Windows spawn(exe, ["exec", fullPrompt], ...).
cli-py shell packages/cli-py/planforge/utils/shell.py Added get_npm_global_exe_candidates(cmd) and resolve_command_path_with_npm_fallback(cmd) (same path logic as cli-js).
cli-py Claude packages/cli-py/planforge/providers/claude.py All subprocess calls use resolved exe. On Windows (os.name == "nt"), complete_one_turn and _run_claude_streaming use temp file + PowerShell. run_implement delegates to _run_claude_streaming.
cli-py Codex packages/cli-py/planforge/providers/codex.py Added _resolve_codex_exe(). Windows script invokes codex by absolute path (& 'escaped_exe' exec -); non-Windows uses [exe, "exec", full_prompt].
  • Root cause: In sandbox, PATH often omits npm global bin → ENOENT for claude. On Windows, spawning claude.cmd (or codex.cmd) directly from Node can yield EINVAL; running them via PowerShell avoids that.
  • Design: Shared “PATH then npm global candidates” resolution in shell utils; both providers use it. On Windows, Claude and Codex are invoked only via powershell -Command "..." with temp-file or pipe, never by direct spawn of the .cmd.

How to test

  1. Build: From repo root, run pnpm run build in packages/cli-js — should succeed.
  2. Doctor (Claude on Windows): Run planforge doctor ai, choose claude. TC1–TC3 should pass without spawnSync ... EINVAL.
  3. Plan/Implement in sandbox: In Cursor agent (or a restricted PATH), run planforge plan "simple goal" and planforge implement "simple task" with planner=claude and implementer=codex — both should run without ENOENT/EINVAL.
  4. Python (optional): From packages/cli-py, run the same flows if you use the Python CLI; behavior should match.

Review Requirement

  • Windows path escaping: In PowerShell scripts, exe and temp paths use single-quote escaping (''') for safety; please confirm there are no edge cases (e.g. paths with ').
  • Provider symmetry: Claude and Codex now share the same resolution and Windows-invocation pattern; worth a quick cross-check between claude.ts/codex.ts and claude.py/codex.py.

Additional Info

  • Related Notion: Sandbox Path (design and implementation notes).
  • Aligns with .cursor/rules/provider-symmetry.mdc, node-python-symmetry.mdc, and cross-platform.mdc.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@chucoding chucoding self-assigned this Mar 14, 2026
@chucoding chucoding added the bug Something isn't working label Mar 14, 2026
@chucoding
chucoding merged commit ee0c8d5 into develop Mar 14, 2026
1 check passed
@chucoding
chucoding deleted the bugfix/PF-24 branch March 14, 2026 05:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant