Skip to content

Windows: execute string commands with PowerShell 7 - #37

Open
Yuzu02 wants to merge 1 commit into
xyTom:fix/sessionless-process-runsfrom
Yuzu02:contrib/windows-pwsh
Open

Windows: execute string commands with PowerShell 7#37
Yuzu02 wants to merge 1 commit into
xyTom:fix/sessionless-process-runsfrom
Yuzu02:contrib/windows-pwsh

Conversation

@Yuzu02

@Yuzu02 Yuzu02 commented Aug 2, 2026

Copy link
Copy Markdown

Summary

This is the first layer of the Windows runtime work tracked in #36 and is intentionally based on #34 (fix/sessionless-process-runs). PR #34 already provides workspace-scoped command handles; this layer adds the Windows shell contract without duplicating that registry.

  • execute Windows string commands through a server-resolved PowerShell 7 (pwsh.exe)
  • never fall back silently to cmd.exe
  • allow operators to pin an absolute launcher with CODING_TOOLS_MCP_PWSH_PATH
  • exclude the current workspace tree from implicit shell resolution
  • verify the resolved PowerShell major version before spawning commands
  • block PowerShell network cmdlets and recursive deletion aliases in safe mode
  • add Windows CI coverage and operator documentation
  • synchronize the existing uv.lock with the 0.2.2 / PyYAML metadata already present on the base branch

Security properties

The request environment cannot choose the shell executable. Resolution uses only the server process environment or the explicit absolute operator setting. The spawned shell runs with -NoLogo -NoProfile -NonInteractive.

Validation

On Windows 11 with PowerShell 7 and Python 3.13:

  • focused PowerShell and Windows smoke tests: pass
  • Ruff: pass
  • uv lock --check: pass
  • combined stack validation: 217 tests passed, 0 failures, 0 errors, 87 explicit POSIX/Linux-only skips
  • combined stack Mypy: 0 errors across 16 source files

Stack

GitHub's stacked-PR preview does not support cross-fork stacks, so the official two-layer stack is hosted in the contributor fork:

The second layer contains only Windows environment normalization, portable fixtures/cleanup, and static typing fixes. It can be retargeted upstream after this layer lands or if the branches are adopted into upstream.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a Windows-specific shell execution contract so Windows string commands are executed via server-resolved PowerShell 7 (pwsh.exe) rather than falling back to cmd.exe, and extends safe-mode policy checks to recognize common PowerShell network/destructive patterns. It also adds Windows CI/test coverage and updates operator-facing documentation, while synchronizing uv.lock metadata.

Changes:

  • Add trusted pwsh.exe resolution (with optional operator pinning) and use it for Windows shell=True string commands.
  • Extend safe-mode command policy scanning to detect PowerShell network cmdlets and recursive deletion aliases/abbreviations.
  • Add Windows PowerShell execution tests, update docs, and run the new tests in Windows CI; update uv.lock for 0.2.2 and pyyaml.

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
coding_tools_mcp/processes.py Resolves pwsh.exe from trusted server environment, verifies PS major version, and uses PowerShell 7 for Windows string commands.
coding_tools_mcp/server.py Adds PowerShell-focused regexes to block network/destructive commands in safe mode.
tests/test_windows_pwsh.py Adds unit/integration tests for pwsh resolution/spawning and safe-mode policy enforcement.
.github/workflows/compliance.yml Runs the new Windows PowerShell tests in the Windows compliance workflow.
README.md Documents Windows string-command behavior, error codes, and the PowerShell 7 contract.
docs/runtime-contract-v0.2.md Adds SHELL_NOT_FOUND / SHELL_VERSION_UNSUPPORTED to documented error codes.
docs/limitations.md Documents Windows PowerShell 7 requirement and lack of cmd.exe fallback.
uv.lock Bumps project version metadata and adds pyyaml to the dev extra lock content.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

POWERSHELL_NETWORK_RE = re.compile(
r"(?:^|[;&|{}\r\n])\s*(?:Invoke-WebRequest|Invoke-RestMethod|Start-BitsTransfer|"
r"Test-NetConnection|Test-Connection|Resolve-DnsName|iwr|irm|tnc|ping(?:\.exe)?|"
r"nslookup(?:\.exe)?|tracert(?:\.exe)?)\b|(?:System\.)?Net\.",
@Satori-Bot

Copy link
Copy Markdown
Collaborator

PowerShell 让 safe mode 的网络/破坏性命令检查可以被绕过。
coding_tools_mcp/server.py:181-195 新增的 PowerShell 检测主要靠正则匹配命令文本,而 :187 的 shell-expansion gate 只识别反引号、$(、${,普通 $var 和 splatting 不拦。
我实际验证下面两条都通过 _check_command_policy():

$c='Invoke-WebRequest'; & $c example.com
$p=@{Recurse=$true}; Remove-Item . @p

第一条可绕过 network gate,第二条可绕过 recursive deletion gate。对应执行切 PowerShell 的位置在 coding_tools_mcp/processes.py:221-224。
这个我认为是 merge blocker,因为 safe mode 的安全语义发生了实际退化。单纯继续堆 PowerShell 正则很难覆盖变量调用、alias、splatting、script block 等语法;至少要把 PowerShell 的动态调用/变量展开整体纳入 permission gate,或者换成更保守的模型。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants