Issue Draft: Windows SSH target cannot enable `wsh` even when `wsh.exe` is installed
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 35/100
- Tipo de issue
- Error
- Claridad
- Bastante claro
- Estado de actividad
- Tranquilo
- Stack tecnológico
- go, powershell
- Área
- cli, devtools, operating-systems
Línea de trabajo
Start with pkg/remote/conncontroller/conncontroller.go, pkg/remote/connutil.go, pkg/wshutil/wshutil.go, and the referenced remote shell startup paths. Compare the existing POSIX assumptions with the proposed Windows detection, installation, connserver startup, and shell reporting flows. Done means Windows SSH targets with wsh.exe no longer remain degraded, while the suggested unit and integration tests cover Windows and preserve Linux, macOS, and WSL behavior.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Issue Draft: Windows SSH target cannot enable wsh even when wsh.exe is installed
Summary
Wave Terminal can establish a basic SSH session to a Windows OpenSSH target, but the connection remains degraded and the UI reports that wsh is not installed for the connection.
In the tested setup, the SSH target is the same Windows machine running Wave. The wsh.exe binary exists and reports the expected Wave version, but Wave still fails to enable the remote wsh connserver path.
This appears to be a Windows-as-SSH-target compatibility gap: the current remote SSH wsh installation and startup flow assumes a POSIX shell environment (sh, uname, mkdir -p, chmod, POSIX env var syntax), while Windows OpenSSH commonly defaults to PowerShell or cmd and may not provide those tools.
Observed behavior
- Basic SSH command execution works.
- The connection indicator shows:
Connection degraded: [email protected]wsh is not installed for this connection
- Wave initially prompts to automatically install
wsh, but the enhanced connection is still unavailable afterward. - Manually installing
wsh.exeon the Windows target does not resolve the issue.
Expected behavior
If the remote target is Windows and a compatible wsh.exe binary is available, Wave should be able to install and start the remote wsh connserver, or report a Windows-specific actionable error explaining what is missing.
Tested environment
- Wave version:
0.14.5 - Wave host OS: Windows
- SSH target OS: Windows, same physical machine as Wave host
- SSH target user:
Administrator - SSH target:
[email protected] - OpenSSH server: running
- Installed remote binary:
C:\Users\Administrator\.waveterm\bin\wsh.exe
- Binary version check:
C:\Users\Administrator\.waveterm\bin\wsh.exe version- output:
wsh v0.14.5
sh: not foundbash: not found
Support quadrant
| Area | Current status | Notes |
|---|---|---|
| Windows desktop app | Supported | Windows build/package paths exist, including NSIS/MSI/ZIP and Windows CI/build tasks. |
| Windows local terminal | Supported | Local shell detection prefers pwsh, then powershell, then powershell.exe. |
| Windows WSL integration | Supported | WSL paths use github.com/ubuntu/gowsl and WSL-specific connection code. |
| Windows SSH agent | Supported | Windows OpenSSH agent named pipe support exists. |
Unix-like SSH target with wsh |
Supported/expected | Current remote installation and startup logic is POSIX-oriented. |
Windows SSH target with wsh.exe |
Incomplete/broken | Remote install/startup assumes POSIX tools and shell semantics. |
Local evidence
The target has a valid wsh.exe binary:
PS> C:\Users\Administrator\.waveterm\bin\wsh.exe version
wsh v0.14.5
But the target does not have a POSIX shell in PATH:
PS> Get-Command sh -ErrorAction SilentlyContinue
# no result
PS> Get-Command bash -ErrorAction SilentlyContinue
# no result
Simulating the remote startup wrapper fails because sh is unavailable:
PS> sh -c '...'
The term 'sh' is not recognized as a name of a cmdlet, function, script file, or executable program.
Possible root causes
1. Remote wsh path is POSIX-only
pkg/wavebase/wavebase.go defines a single remote binary path:
const RemoteFullWshBinPath = "~/.waveterm/bin/wsh"
For Windows targets, the actual binary is typically wsh.exe, and the usable path is more likely similar to:
C:\Users\<user>\.waveterm\bin\wsh.exe
2. SSH connserver startup assumes sh -c
pkg/remote/conncontroller/conncontroller.go builds a POSIX command template:
var ConnServerCmdTemplate = strings.TrimSpace(
strings.Join([]string{
"%s version 2> /dev/null || (echo -n \"not-installed \"; uname -sm; exit 0);",
"exec %s connserver --conn %s %s %s",
}, "\n"))
The final command is wrapped with sh -c:
shWrappedCmdStr := fmt.Sprintf("sh -c %s", shellutil.HardQuote(cmdStr))
err = sshSession.Start(shWrappedCmdStr)
This fails on Windows OpenSSH targets that do not provide sh.
3. Platform detection assumes uname -sm
pkg/remote/connutil.go uses:
Cmd: "uname -sm"
and the startup template emits:
uname -sm
Windows OpenSSH targets do not normally have uname unless Git Bash/MSYS/Cygwin is installed and visible to non-interactive SSH sessions.
4. Remote install script assumes POSIX tools
pkg/remote/connutil.go uses a POSIX install script:
mkdir -p {{.installDir}} || exit 1;
cat > {{.tempPath}} || exit 1;
mv {{.tempPath}} {{.installPath}} || exit 1;
chmod a+x {{.installPath}} || exit 1;
This does not work in a default Windows PowerShell/cmd SSH environment.
5. Remote shell detection defaults Windows to /bin/bash
pkg/wshutil/wshutil.go reports the remote shell using $SHELL for non-macOS systems and falls back to /bin/bash:
shell := os.Getenv("SHELL")
if shell == "" {
return "/bin/bash"
}
On Windows, $SHELL is usually empty, so a Windows remote can be incorrectly reported as using /bin/bash.
6. Later remote shell startup also uses POSIX env syntax
Even if connserver starts, some remote shell code injects environment variables using POSIX syntax such as:
VAR=value command
For PowerShell, this should be closer to:
$env:VAR = 'value'; command
Suggested fix plan
Phase 1: Detect Windows SSH targets without POSIX tools
Add a Windows-aware remote platform detection path before falling back to uname -sm.
Possible detection approaches:
- Try PowerShell first:
powershell.exe -NoProfile -NonInteractive -Command "[System.Runtime.InteropServices.RuntimeInformation]::OSDescription; [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture"
- Or emit a compact machine-readable response:
powershell.exe -NoProfile -NonInteractive -Command "$arch=[Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString().ToLower(); Write-Output \"windows $arch\""
Then normalize x64/amd64 and arm64 consistently with existing wsh binary naming.
Phase 2: Add Windows remote install flow
Add a Windows branch in the remote wsh copy/install logic.
Suggested behavior:
- Install to a Windows path such as:
%USERPROFILE%\.waveterm\bin\wsh.exe
- Use PowerShell commands instead of POSIX tools:
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.waveterm\bin" | Out-Null
- Copy stdin to a temporary file, then atomically move it into place where possible.
- Do not run
chmodon Windows.
Phase 3: Add Windows connserver startup flow
When the target OS is Windows, avoid sh -c and start wsh.exe with PowerShell or cmd-compatible quoting.
Potential shape:
powershell.exe -NoProfile -NonInteractive -Command ^
"& '$env:USERPROFILE\.waveterm\bin\wsh.exe' version; if ($LASTEXITCODE -ne 0) { Write-Output 'not-installed windows x64'; exit 0 }; & '$env:USERPROFILE\.waveterm\bin\wsh.exe' connserver --conn '<conn>' --router-domainsocket"
The exact quoting should be implemented centrally and covered by tests.
Phase 4: Fix Windows remote shell reporting
Update wshutil.GetInfo() / shell detection for Windows.
Suggested behavior:
- If
runtime.GOOS == "windows", preferpwsh, thenpowershell, thenpowershell.exe. - Return a shell value that
shellutil.GetShellTypeFromShellPath()can classify aspwsh. - Avoid falling back to
/bin/bashon Windows.
Phase 5: Fix shell/env command construction for Windows remotes
Remote shell startup should branch on remoteInfo.ClientOs and use shell-specific environment injection.
Examples:
- POSIX:
VAR=value command
- PowerShell:
$env:VAR='value'; command
This likely affects both generic SSH command construction and enhanced wsh remote shell startup.
Suggested tests
Unit tests
- Normalize Windows architecture strings into existing
SupportedWshBinarieskeys. - Build Windows install command without POSIX tokens (
sh,uname,chmod,mkdir -p,/dev/null). - Build Windows connserver startup command with
wsh.exeand PowerShell-compatible quoting. - Ensure Windows remote shell detection does not return
/bin/bashwhen$SHELLis empty.
Integration tests
- Windows OpenSSH target with default PowerShell shell and no Git Bash installed.
- Windows OpenSSH target with Git Bash installed, to verify fallback compatibility still works.
- Existing Linux/macOS SSH target behavior to prevent regressions.
- WSL connection behavior, since WSL intentionally uses POSIX assumptions and should remain separate from Windows SSH target handling.
Temporary workaround
A possible workaround is to install Git Bash/MSYS and ensure sh, uname, mkdir, cat, mv, and chmod are visible to the Windows OpenSSH non-interactive session.
However, this is not ideal because it requires a POSIX compatibility layer on a Windows SSH target, and it still may not fully address later PowerShell shell/env handling issues.
Impact
This affects users who want to use Wave Terminal to SSH into a Windows machine and use enhanced Wave features such as remote wsh, durable session behavior, remote file/workspace integration, and richer terminal features.
The issue is easy to miss because plain SSH command execution works, but Wave silently falls back to a degraded connection state.
- Lenguaje dominante
- Go
- Estrellas
- 22.4k
- Forks
- 1.1k
- Merge medio
- 12 d 6 h
- PR fusionados (30 d)
- 14
Preparar el entorno
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de wavetermdev/waveterm
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
wavetermdev/waveterm#3481 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
wavetermdev/waveterm#3435 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 85/100
wavetermdev/waveterm#3432 ·
Los mantenedores suelen responder en 1 día
-
enhancement triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
wavetermdev/waveterm#3431 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 86/100
wavetermdev/waveterm#3428 ·
Los mantenedores suelen responder en 1 día
Todos los issues de wavetermdev/waveterm
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
siderolabs/terraform-provider-talos#414 ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
JuliaComputing/jh#63 · 1 comentario ·
-
area/proxy kind/bug priority/backlog triage/accepted
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
lexfrei/cloudflare-tunnel-gateway-controller#840 ·
Los mantenedores suelen responder en 1 día
-
Priority: Normal Type: Bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
cloudflare/cloudflared#1747 ·