fix(windows): centralize subprocess compat, add safe_split_command, secure_file_chmod, master_subprocess_run - #37241
Open
dellastreet53-dev wants to merge 1 commit into
Conversation
…ecure_file_chmod, master_subprocess_run Adds a comprehensive Windows subprocess compatibility module with: - safe_split_command: shlex.split replacement that preserves backslashes on Windows - secure_file_chmod: cross-platform chmod (ICACLS on Windows, os.chmod on POSIX) - master_subprocess_run/master_subprocess_popen: centralized .cmd shim resolution - safe_subprocess_run: convenience wrapper for string commands - windows_detach_popen_kwargs: correct detached-process creation flags Migrates 31 files from raw shlex.split (backslash destruction on Windows), os.chmod (ineffective on Windows), and Path.home()/.hermes (breaks profiles) to the centralized wrapper.
teknium1
reviewed
Jul 13, 2026
teknium1
left a comment
Contributor
There was a problem hiding this comment.
Thanks for the broad Windows portability audit. The underlying problem is still real on current main: agent/shell_hooks.py:451 parses commands before the shell=False spawn at agent/shell_hooks.py:462-469, and agent/copilot_acp_client.py:70-74 constructs ACP argv from shlex.split.
Problems
- In
a2cbfbda48e3,safe_split_command()returns[command]on Windows, but the migrated shell-hook caller still usesshell=False. A command with arguments therefore becomes one executable name instead of an argv vector. plugins/disk-cleanup/__init__.pycallssafe_split_command(cmd, posix=True), while the new helper accepts noposixkeyword; this raisesTypeError.master_subprocess_run/master_subprocess_popenpass the entire remainder of a string Node command as one argument, sonpm install --save xis not reconstructed as separate argv entries.- The fallback
get_hermes_homeedits inplugins/disk-cleanup/disk_cleanup.pyandplugins/hermes-achievements/dashboard/plugin_api.pyrecurse when the constants import fails.
Suggested changes
- Separate parser,
shell=Falseargv, and intentional-shell command-string use cases; preserve a real argv for the first two rather than returning a raw one-item list. - Add regression tests for Windows tokenization, migrated shell hooks/ACP args, disk cleanup, Node arguments, and fallback imports.
This is an automated hermes-sweeper review.
| # Tokenise the command — catches `touch /tmp/hermes-x/test_foo.py` | ||
| try: | ||
| for tok in shlex.split(cmd, posix=True): | ||
| for tok in safe_split_command(cmd, posix=True): |
Contributor
There was a problem hiding this comment.
safe_split_command is defined in this PR with only a command parameter, so this existing posix=True call becomes a TypeError. Either preserve the needed keyword contract or remove/rework this call with a tokenizer appropriate for this parser.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a comprehensive Windows subprocess compatibility module with:
Migrates 31 files from raw shlex.split (backslash destruction on Windows),
os.chmod (ineffective on Windows), and Path.home()/.hermes (breaks profiles)
to the centralized wrapper.