Skip to content

Long-running SSH commands block terminal input, causing zellij keybindings and user input to stop working #925

Description

@knota-lab

Description

When Jcode executes a command on a remote machine over SSH, if the remote command runs for a long time or doesn't exit promptly, keyboard input to the current terminal gets captured by that SSH session.

During this period, it's impossible to type messages normally, and zellij keybindings for switching panes/tabs or performing other actions don't work either. Terminal input only recovers after the SSH command finishes, times out, or is manually killed.

Environment

  • Jcode version: jcode v0.75.3 (fd1ff01)
  • OS: Ubuntu
  • zellij version: zellij 0.44.3
  • SSH client: OpenSSH
  • Remote system: Windows 11 / OpenSSH Server
  • Execution tool: Jcode bash tool

Steps to Reproduce

  1. Start Jcode inside zellij.

  2. Have Jcode run a long-running SSH command, e.g.:

    ssh user@remote-host "ping -t 127.0.0.1"

    or:

    ssh user@remote-host "long-running-command"
  3. While the SSH command is running, try:

    • Typing text into Jcode.
    • Using the zellij prefix keybinding.
    • Switching panes or tabs.
  4. Observe whether terminal input responds normally.

Actual Behavior

While the SSH command is running:

  • The user's keyboard input isn't delivered to Jcode.
  • zellij keybindings are unresponsive, or get captured by the SSH child process instead.
  • Even when the command is marked by the tool as running in the background, the underlying SSH session sometimes still holds on to terminal input.
  • Input only recovers after the SSH process exits, times out, or is killed.

This is more likely to occur when launching Windows remote tasks through nested cmd.exe /c or PowerShell layers. If the remote subprocess inherits SSH's stdin/stdout, the SSH connection may never exit on its own.

Expected Behavior

Jcode's tool commands should not block interactive input to the UI.

Suggested behavior:

  1. Tool subprocess stdin should default to /dev/null instead of Jcode's interactive terminal.
  2. SSH commands should default to non-interactive mode, e.g. ssh -n -T.
  3. Once a long-running task is moved to the background, it should be fully detached from the current terminal's stdin, stdout, and stderr.
  4. While a tool is executing, the user should still be able to type messages and use zellij keybindings.
  5. After a timeout, the entire subprocess tree should be cleaned up, so no lingering SSH, cmd.exe, or PowerShell processes continue to hold the terminal.

Workaround

Currently, the likelihood of this happening can be reduced with:

ssh -n -T -o BatchMode=yes user@remote-host "command" </dev/null

For long-running remote Windows tasks, you can use Task Scheduler to run the job locally on the target machine:

schtasks /Create /TN MyTask /TR "C:\path\run.cmd" /SC ONCE /ST 00:00 /F
schtasks /Run /TN MyTask

Then poll status via short, low-frequency SSH commands instead of keeping a long-running SSH foreground connection open.

Additional Context

The issue isn't just that remote commands take a long time — it's that the tool's subprocess inherits or continues to hold the interactive terminal's input. It would help to review how the tool handles stdin at process creation time, PTY allocation, background task detachment, and subprocess-tree cleanup after a timeout.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions