fix(terminal): psmux wheel scrolling, per-platform tmux upgrade advice, Windows-safe server tests
- Server tests on Windows no longer reach the user's real psmux: psmux
ignores TMUX_TMPDIR (and 3.3.x PSMUX_DATA_DIR), so quit.test.js's Quit and
the runner's kill-server ended every live lane pane — the pre-commit hook
included. scripts/test-server.js now takes tmux off the suites' PATH there.
- Wheel scrolling on Windows: psmux never turns mouse tracking on for its
client, so xterm.js never reported the wheel and a pane could not scroll.
A Windows attach is told {type:"wheel"} and the browser sends the SGR wheel
report itself; psmux scrolls or forwards it to the pane's app.
- tmux.upgradeAdvice(): the oldest tmux AgentHub asks for and how each
platform upgrades (psmux 3.4.0 -> winget upgrade marlocarlo.psmux; tmux 3.7
-> brew upgrade tmux / build the release on Linux). Used by the doctor,
GET /api/run/tmux ({available, version, upgrade}), `agenthub doctor`, and a
sticky toast on the Workspace page. Advice only: nothing installs tmux.
Committed with --no-verify (user's call): the pre-commit hook runs the full
backend suite, which has ~378 pre-existing failures on Windows (S3/Linux-only
tests: sudo, /proc, systemd, members). Every test touching this change passes:
pty-attach, tmux, run, plugin-doctor-tmux, TerminalView, Workspace, and the
client tests related to the changed files; tsc and the header audit are clean.
This commit is contained in:
+11
-22
@@ -247,15 +247,12 @@ function systemdStatus() {
|
||||
* service can still see a different one — `GET /api/run/tmux` is the server's
|
||||
* own answer, and `agenthub doctor` reports that.
|
||||
*
|
||||
* Also WARN below tmux 3.7, the first with pane scrollbars (`tmux.js` turns
|
||||
* them on), and when a new binary still talks to an older running server — a
|
||||
* server keeps its version until every tmux session has closed. The doctor
|
||||
* only says so: it never installs or restarts tmux.
|
||||
* Also WARN below the platform's minimum (`tmux.upgradeAdvice`: psmux 3.4.0
|
||||
* on Windows, tmux 3.7 elsewhere — the same advice the Workspace shows), and
|
||||
* when a new binary still talks to an older running server — a server keeps
|
||||
* its version until every tmux session has closed. The doctor only says so:
|
||||
* it never installs or restarts tmux.
|
||||
*/
|
||||
const hasScrollbars = (version) => {
|
||||
const m = /(\d+)\.(\d+)/.exec(version || "");
|
||||
return !!m && (Number(m[1]) > 3 || (Number(m[1]) === 3 && Number(m[2]) >= 7));
|
||||
};
|
||||
|
||||
function tmuxStatus() {
|
||||
const tmux = require("../server/lib/tmux");
|
||||
@@ -268,26 +265,18 @@ function tmuxStatus() {
|
||||
"Install it: sudo apt install tmux / brew install tmux (Windows: run AgentHub under WSL2)",
|
||||
];
|
||||
}
|
||||
if (!hasScrollbars(client)) {
|
||||
return [
|
||||
"warn",
|
||||
"tmux",
|
||||
`${client} works, but terminal panes get a scrollbar only from tmux 3.7. ` +
|
||||
"Upgrade: brew upgrade tmux (macOS); on Linux, when the distro ships an older one " +
|
||||
"(Ubuntu 24.04 has 3.4), build the release from https://github.com/tmux/tmux/releases " +
|
||||
"(needs libevent-dev libncurses-dev bison: ./configure && make && sudo make install)",
|
||||
];
|
||||
}
|
||||
const advice = tmux.upgradeAdvice(client);
|
||||
if (advice) return ["warn", "tmux", `${client} works, but upgrade it: ${advice}`];
|
||||
const server = tmux.serverVersion();
|
||||
if (server && !hasScrollbars(server)) {
|
||||
if (server && tmux.upgradeAdvice(server)) {
|
||||
return [
|
||||
"warn",
|
||||
"tmux",
|
||||
`${client} installed, but the running tmux server is ${server} — panes get their ` +
|
||||
"scrollbar once every tmux session has closed (or after a reboot)",
|
||||
`${client} installed, but the running tmux server is ${server} — it is used ` +
|
||||
"until every tmux session has closed (or after a reboot)",
|
||||
];
|
||||
}
|
||||
return ["ok", "tmux", `${client} on PATH — the run console can start sessions, with scrollbars`];
|
||||
return ["ok", "tmux", `${client} on PATH — the run console can start sessions`];
|
||||
}
|
||||
|
||||
function countLegacyHookEntries() {
|
||||
|
||||
@@ -68,6 +68,23 @@ const env = {
|
||||
};
|
||||
delete env.TMUX;
|
||||
delete env.TMUX_PANE;
|
||||
// psmux (the WinGet `tmux` on Windows) ignores TMUX_TMPDIR — and 3.3.x its
|
||||
// PSMUX_DATA_DIR too — so every tmux call reached the user's REAL server:
|
||||
// quit.test.js's Quit killed every live lane pane, and the kill-server below
|
||||
// the rest. Only `-L` isolates there, which no env var can add to each call,
|
||||
// so on Windows the suites get no tmux at all; theirs skip (or fail) instead.
|
||||
if (process.platform === "win32") {
|
||||
const key = Object.keys(env).find((k) => k.toUpperCase() === "PATH");
|
||||
if (key) {
|
||||
env[key] = env[key]
|
||||
.split(path.delimiter)
|
||||
.filter(
|
||||
(d) => !["tmux.exe", "tmux.cmd", "tmux.bat"].some((f) => fs.existsSync(path.join(d, f)))
|
||||
)
|
||||
.join(path.delimiter);
|
||||
}
|
||||
delete env.PSMUX_SESSION;
|
||||
}
|
||||
// Git exports these to a hook it runs from a linked worktree (the pre-commit
|
||||
// hook runs this suite): inherited, every `git init`/`commit` a test makes in
|
||||
// its temp folder went to the REAL repository instead — commits on the
|
||||
|
||||
Reference in New Issue
Block a user