feat: shell integration-based terminal output capture for remote environments
SH
6mo ago+143+143+012345678901234567890123456789-20-20-01234567890123456789
Summary
- When the extension host runs on Windows with a remote workspace (SSH, WSL, Dev Container),
childProcess.spawnexecutes locally instead of on the remote. The existing fallback usedide.runCommand(sendText) with no output capture, returning a hardcoded "Command failed" status. - Adds a new
runCommandWithOutputIDE method using VS Code's Shell Integration API (1.93+) to execute commands on remote terminals with full stdout capture and ANSI color preservation. - When shell integration is unavailable,
runCommandWithOutputfalls back tosendTextinternally and the caller reports "Command completed" — no double-execution.
How it works
- Creates an invisible terminal (not shown to user)
- Waits for shell integration to activate via
onDidChangeTerminalShellIntegration(10s timeout) - Executes via
shellIntegration.executeCommand(command) - Reads output via
execution.read()async iterable - Strips only VS Code's internal OSC 633 markers; preserves ANSI color codes for
UnifiedTerminal'sAnsiRenderer - Disposes terminal after capture
- If shell integration is unavailable: shows terminal, sends command via
sendText, returns empty string (command still executes, just without output capture)
Files changed (10)
| File | Change |
|---|---|
core/index.d.ts | Add runCommandWithOutput to IDE interface |
core/config/types.ts | Add to global IDE type |
core/protocol/ide.ts | Add protocol type |
core/protocol/messenger/messageIde.ts | Add proxy method |
core/protocol/messenger/reverseMessageIde.ts | Add listener |
extensions/vscode/src/extension/VsCodeMessenger.ts | Add handler |
extensions/vscode/src/VsCodeIde.ts | runCommandWithOutput() + waitForShellIntegration() implementation |
core/tools/implementations/runTerminalCommand.ts | Use new method in remote fallback path |
core/tools/implementations/runTerminalCommand.vitest.ts | Update mocks and assertions |
core/util/filesystem.ts | Add stub for FileSystemIde |
Test plan
- SSH remote:
pwd,echo, Python scripts with ANSI output — green "Command completed" with captured output and rendered colors - WSL remote: Same commands — working, ~5s initial delay due to shell integration startup on WSL terminals
- Native Windows (no regression): Local
childProcess.spawnpath completely unaffected — no changes to that code path - Shell integration unavailable: Falls back to
sendTextinternally, reports "Command completed" without double-executing - Unit tests: 36/37 pass (1 pre-existing failure unrelated to this change)
Related issues
- Fixes #10007 (
spawn powershell.exe ENOENTin WSL2/Dev Container) — #10391 partially addressed this by adding theisWindowsHostWithRemoteguard but the fallback had no output capture - Builds on the remote execution guard from #10538
- ANSI rendering works with @chezsmithy's
UnifiedTerminalcomponent (#7383)
🤖 Generated with Claude Code