fix(pane): don't hand the AppImage runtime's ARGV0 to the pane (#1100) (#1111)

The AppImage runtime exports `ARGV0` (the path the image was launched by)
into tty7's environment, and every pane inherited it. zsh treats an
exported `ARGV0` as the argv[0] of each external command it runs, so in a
pane every program was told it was `tty7-….AppImage`. Volta's shims choose
the tool from argv[0], so `node`, `npm` and every global package failed
with `Could not find executable "tty7-….AppImage"`.

Turning shell integration off would not have helped. `env -u
TTY7_SHELL_INTEGRATION node` only worked because `env` execs node with a
correct argv[0], and `env -u` with any variable name works just as well.

Panes now start without `ARGV0`. The removal happens before the configured
`env` block is applied, so an explicit setting there still wins.

Reproduced on Linux (Debian arm64, zsh, Volta 2.0.2) with tty7-server
started under the environment an AppImage launch leaves behind: the shims
fail with the line removed and work with it in place.
This commit is contained in:
l0ng-ai
2026-10-07 21:01:32 +08:00
committed by GitHub
parent 739a7769dc
commit 591368d80b
2 changed files with 28 additions and 0 deletions
+7
View File
@@ -9,6 +9,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- **Volta shims, and anything else that reads its own argv[0], work again in
the Linux AppImage** (#1100). The AppImage runtime exports `ARGV0` into
tty7's environment and every pane inherited it. zsh gives an exported
`ARGV0` to every external command as its argv[0], so `node` started up as
`tty7-….AppImage` and Volta answered `Could not find executable`. Panes now
start without `ARGV0`. An `env` entry in the config can still set it.
- **The macOS traffic lights sit on the same line as the tiles beside them.**
The buttons AppKit draws are 14 points tall and gpui hangs the top of the
frame `y` points below the window's top edge, so the lights' centre falls
+21
View File
@@ -578,6 +578,16 @@ fn apply_common_command_setup(
#[cfg(unix)]
cmd.env("PWD", dir);
}
// The AppImage runtime exports `ARGV0` (the path the image was launched
// by) into tty7's own environment, and the pane would inherit it. zsh
// treats an exported `ARGV0` as the argv[0] of every external command it
// runs, so each program in the pane is told it is `tty7-….AppImage` — and
// multiplexers like Volta's shims, which pick the tool from argv[0], fail
// with "Could not find executable" (#1100). Nothing outside a single
// command line ever wants it set, so the pane starts without it; the
// configured `env` block, applied below, can still put it back.
cmd.env_remove("ARGV0");
let extra_env = crate::core::config::extra_env();
// Windows hands every process a private copy of the environment at spawn
@@ -4137,6 +4147,17 @@ mod tests {
/// `cwd()` alone loses that: the shell falls back to `getcwd()` and one
/// tab reads `/tmp/x` while the tab opened from it reads `/private/tmp/x`.
/// `PWD` is what carries the name across, and what the shell checks.
/// An AppImage launch leaves `ARGV0` in the daemon's environment; a zsh
/// that inherits it renames every command it runs, which breaks Volta's
/// shims (#1100).
#[test]
fn the_appimage_runtimes_argv0_does_not_reach_the_pane() {
let mut cmd = CommandBuilder::new("/bin/sh");
cmd.env("ARGV0", "./tty7-26.9.5-linux-x86_64.AppImage");
apply_common_command_setup(&mut cmd, &None, 1, None, "sh");
assert_eq!(cmd.get_env("ARGV0"), None);
}
#[cfg(unix)]
#[test]
fn an_inherited_directory_keeps_the_name_it_was_reached_by() {