feat: shell integration-based terminal output capture for remote environments

SH
6mo ago
+143-20

Summary

  • When the extension host runs on Windows with a remote workspace (SSH, WSL, Dev Container), childProcess.spawn executes locally instead of on the remote. The existing fallback used ide.runCommand (sendText) with no output capture, returning a hardcoded "Command failed" status.
  • Adds a new runCommandWithOutput IDE 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, runCommandWithOutput falls back to sendText internally and the caller reports "Command completed" — no double-execution.

How it works

  1. Creates an invisible terminal (not shown to user)
  2. Waits for shell integration to activate via onDidChangeTerminalShellIntegration (10s timeout)
  3. Executes via shellIntegration.executeCommand(command)
  4. Reads output via execution.read() async iterable
  5. Strips only VS Code's internal OSC 633 markers; preserves ANSI color codes for UnifiedTerminal's AnsiRenderer
  6. Disposes terminal after capture
  7. If shell integration is unavailable: shows terminal, sends command via sendText, returns empty string (command still executes, just without output capture)

Files changed (10)

FileChange
core/index.d.tsAdd runCommandWithOutput to IDE interface
core/config/types.tsAdd to global IDE type
core/protocol/ide.tsAdd protocol type
core/protocol/messenger/messageIde.tsAdd proxy method
core/protocol/messenger/reverseMessageIde.tsAdd listener
extensions/vscode/src/extension/VsCodeMessenger.tsAdd handler
extensions/vscode/src/VsCodeIde.tsrunCommandWithOutput() + waitForShellIntegration() implementation
core/tools/implementations/runTerminalCommand.tsUse new method in remote fallback path
core/tools/implementations/runTerminalCommand.vitest.tsUpdate mocks and assertions
core/util/filesystem.tsAdd 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.spawn path completely unaffected — no changes to that code path
  • Shell integration unavailable: Falls back to sendText internally, 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 ENOENT in WSL2/Dev Container) — #10391 partially addressed this by adding the isWindowsHostWithRemote guard but the fallback had no output capture
  • Builds on the remote execution guard from #10538
  • ANSI rendering works with @chezsmithy's UnifiedTerminal component (#7383)

🤖 Generated with Claude Code