feat(shell): enhance shell tool with version-aware PowerShell context#1135
feat(shell): enhance shell tool with version-aware PowerShell context#1135QIN2DIM wants to merge 7 commits intoMoonshotAI:mainfrom
Conversation
This commit improves the shell tool by introducing version-specific documentation for PowerShell environments. - Added dynamic shell key detection in `Shell._get_shell_key()` to distinguish between: - `bash` for non-Windows systems - `powershell5` for Windows PowerShell 5.1 - `powershell7` for PowerShell 7+ - Created new documentation files: - `powershell5.md`: Specific guidelines for PowerShell 5.1 with syntax limitations and required workarounds - `powershell7.md`: Modern PowerShell 7+ features including `&&`/`||` operators and native cmdlet usage - Removed obsolete `powershell.md` file and updated environment detection to include shell version detection - Enhanced `Environment` class with async shell version detection via `_get_powershell_version()` and `_get_bash_version()` - Updated shell description to include detected shell version in the template context This change ensures users receive accurate, version-specific guidance, improving both safety and efficiency when using the shell tool on different Windows PowerShell versions.
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com> Signed-off-by: QIN2DIM <62018067+QIN2DIM@users.noreply.github.com>
| stdout=asyncio.subprocess.PIPE, | ||
| stderr=asyncio.subprocess.PIPE, | ||
| ) | ||
| stdout, _ = await asyncio.wait_for(proc.communicate(), timeout=2.0) |
There was a problem hiding this comment.
🟡 Process resource leak in _get_bash_version on timeout
In _get_bash_version, if asyncio.wait_for raises TimeoutError, the spawned bash process is never killed. The exception is caught by the broad except Exception handler which returns "unknown" but leaves the child process running.
Root Cause and Comparison with _get_powershell_version
In _get_powershell_version (src/kimi_cli/utils/environment.py:106-110), there is an explicit inner try/except asyncio.TimeoutError block that properly cleans up:
try:
stdout, _ = await asyncio.wait_for(proc.communicate(), timeout=3.0)
except asyncio.TimeoutError:
proc.kill()
await proc.wait()
return "unknown"But in _get_bash_version, no such cleanup exists:
proc = await asyncio.create_subprocess_exec(bash_path, "--version", ...)
stdout, _ = await asyncio.wait_for(proc.communicate(), timeout=2.0)
# If TimeoutError is raised here, proc is never killedThe TimeoutError (which is asyncio.TimeoutError in Python 3.11+) propagates to the outer except Exception on line 142, which returns "unknown" without terminating the child process. This leaves a zombie/orphaned process.
Impact: While bash --version is unlikely to hang in practice, this is an inconsistency with the sibling function and a potential process leak.
| stdout, _ = await asyncio.wait_for(proc.communicate(), timeout=2.0) | |
| try: | |
| stdout, _ = await asyncio.wait_for(proc.communicate(), timeout=2.0) | |
| except asyncio.TimeoutError: | |
| proc.kill() | |
| await proc.wait() | |
| return "unknown" | |
Was this helpful? React with 👍 or 👎 to provide feedback.
Related Issue
Resolve #1136
Description
Shell: Add version-aware documentation that detects PowerShell 5.1 vs 7+ and provides appropriate syntax guidance
Checklist
make gen-changelogto update the changelog.make gen-docsto update the user documentation.