Skip to content

cli: add an ssh-wrapping +ssh action - #12582

Merged
mitchellh merged 5 commits into
ghostty-org:mainfrom
jparise:ssh-action
May 22, 2026
Merged

mitchellh merged 5 commits into
ghostty-org:mainfrom
jparise:ssh-action

Conversation

@jparise

@jparise jparise commented May 5, 2026 •

Copy link
Copy Markdown
Contributor

Add a drop-in ssh wrapper that sets up the remote environment for Ghostty. Anything not consumed as one of our own flags is forwarded to the real, wrapped ssh binary. It can be used directly (ghostty +ssh user@host), aliased (alias ssh='ghostty +ssh --'), or invoked through Ghostty's shell integration.

Before exec'ing ssh, +ssh:

  • Forwards Ghostty environment to the remote (--forward-env): sets TERM=xterm-256color and requests SendEnv forwarding of COLORTERM, TERM_PROGRAM, and TERM_PROGRAM_VERSION.
  • Installs Ghostty's terminfo on the remote (--terminfo), informed by our existing ssh-cache system and using our internal xterm-ghostty terminfo representation.

A third flag, --cache, controls cache use; --cache=false bypasses both read and write, which is useful for scripting and for debugging install failures without polluting the cache.

For shell integration, this replaces the per-shell logic (which made up roughly a third of our shell integration scripts) with a simple wrapper function that translates GHOSTTY_SHELL_FEATURES into a ghostty +ssh command line.

Add a drop-in `ssh` wrapper that sets up the remote environment for
Ghostty. Anything not consumed as one of our own flags is forwarded to
the real, wrapped `ssh` binary. It can be used directly (`ghostty +ssh
user@host`), aliased (`alias ssh='ghostty +ssh --'`), or invoked through
Ghostty's shell integration.

Before exec'ing ssh, `+ssh`:

- Forwards Ghostty environment to the remote (`--forward-env`): sets
  TERM=xterm-256color and requests SendEnv forwarding of COLORTERM,
  TERM_PROGRAM, and TERM_PROGRAM_VERSION.
- Installs Ghostty's terminfo on the remote (`--terminfo`), informed by
  our existing `ssh-cache` system and using our internal xterm-ghostty
  terminfo representation.

A third flag, `--cache`, controls cache use; `--cache=false` bypasses
both read and write, which is useful for scripting and for debugging
install failures without polluting the cache.

For shell integration, this replaces the per-shell logic (which made up
roughly a third of our shell integration scripts) with a simple wrapper
function that translates GHOSTTY_SHELL_FEATURES into a `ghostty +ssh`
command line. This commit only migrates the bash integration; the other
shells will follow separately.
@jparise
jparise requested a review from a team as a code owner May 5, 2026 00:55
@ghostty-bot ghostty-bot Bot added the cli `ghostty` command-line interface label May 5, 2026
@jparise jparise added this to the 1.4.0 milestone May 5, 2026
jparise added 4 commits May 5, 2026 08:30
Replace the inline ssh integration with a thin wrapper that translates
GHOSTTY_SHELL_FEATURES into a `ghostty +ssh` command line. The shell
wrapper no longer carries terminfo install, ControlMaster wiring, or
cache bookkeeping; it just maps the feature flags to flags on `+ssh`
and forwards everything else.
Replace the inline ssh integration with a thin wrapper that translates
GHOSTTY_SHELL_FEATURES into a `ghostty +ssh` command line.
Replace the inline ssh integration with a thin wrapper that translates
GHOSTTY_SHELL_FEATURES into a `ghostty +ssh` command line.
Replace the inline ssh integration with a thin wrapper that translates
GHOSTTY_SHELL_FEATURES into a `ghostty +ssh` command line. When no
ssh-* feature is enabled, the wrapper falls through to the real `ssh`
binary unchanged so nushell users without ssh integration get plain
ssh behavior.
@mitchellh
mitchellh merged commit f5aa271 into ghostty-org:main May 22, 2026
90 checks passed
@jparise
jparise deleted the ssh-action branch May 22, 2026 17:01
jparise added a commit to jparise/ghostty-website that referenced this pull request May 24, 2026
Consolidate all of the SSH-related details in a new ssh.mdx feature
document, and update the terminfo and shell integration documents to
reference it.

See: ghostty-org/ghostty#12582
mitchellh added a commit that referenced this pull request Oct 26, 2026
`+ssh` passed `-o SetEnv=TERM=...` to ssh. ssh only uses the first
SetEnv it finds, so the one on the command line replaced every SetEnv
entry in the user's ssh config. This brings back the bug that #11518
fixed in the old shell integration wrapper, now in `+ssh` (#12582).

`TERM` was also only set with `--forward-env`, so `--forward-env=false`
(what `ssh-terminfo`-only users get) left the inherited
`TERM=xterm-ghostty` in place even when the terminfo install failed.

ssh sends the SetEnv entries in the user's ssh config again, and a
failed terminfo install falls back to `xterm-256color` like it did in
1.3.1, no matter which `ssh-*` features are enabled.

`TERM` is now set in the environment of the ssh process instead of with
SetEnv, the same way the 1.3.1 wrapper did. ssh sends `TERM` on its own
when it opens a remote terminal, so the server doesn't need `AcceptEnv
TERM`. This happens whenever `--forward-env` or `--terminfo` is enabled.
With both disabled, ssh runs with the user's environment unchanged. The
`+ssh` help is updated to explain how `TERM` is chosen.

Docs: https://man.openbsd.org/ssh_config#SetEnv
jcollie pushed a commit to jcollie/ghostty that referenced this pull request Oct 26, 2026
`+ssh` passed `-o SetEnv=TERM=...` to ssh. ssh only uses the first
SetEnv it finds, so the one on the command line replaced every SetEnv
entry in the user's ssh config. This brings back the bug that ghostty-org#11518
fixed in the old shell integration wrapper, now in `+ssh` (ghostty-org#12582).

`TERM` was also only set with `--forward-env`, so `--forward-env=false`
(what `ssh-terminfo`-only users get) left the inherited
`TERM=xterm-ghostty` in place even when the terminfo install failed.

ssh sends the SetEnv entries in the user's ssh config again, and
a failed terminfo install falls back to `xterm-256color` like it
did in 1.3.1, no matter which `ssh-*` features are enabled.

`TERM` is now set in the environment of the ssh process instead of
with SetEnv, the same way the 1.3.1 wrapper did. ssh sends `TERM` on
its own when it opens a remote terminal, so the server doesn't need
`AcceptEnv TERM`. This happens whenever `--forward-env` or
`--terminfo` is enabled. With both disabled, ssh runs with the user's
environment unchanged. The `+ssh` help is updated to explain how
`TERM` is chosen.

Docs: https://man.openbsd.org/ssh_config#SetEnv
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli `ghostty` command-line interface shell-integration

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants