Skip to content

Commit 8addee3

Browse files
davindicodeclaude
andcommitted
Detect tmux version, warn about 3.4 key handling issues
- API returns tmux version alongside sessions - Show yellow warning banner for tmux 3.4.x with fix instructions - Suggest upgrade to 3.5+ or set extended-keys off Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 6294b79 commit 8addee3

2 files changed

Lines changed: 22 additions & 4 deletions

File tree

app/components/terminal/InputBox.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ export default function InputBox() {
165165
const [text, setText] = useState("");
166166
const [activeGroup, setActiveGroup] = useState<string | null>(null);
167167
const [tmuxSessions, setTmuxSessions] = useState<TmuxSession[]>([]);
168+
const [tmuxVersion, setTmuxVersion] = useState<string | null>(null);
168169
const [tmuxLoading, setTmuxLoading] = useState(false);
169170
const [tmuxNewName, setTmuxNewName] = useState("");
170171
const [editorFileName, setEditorFileName] = useState("");
@@ -275,6 +276,7 @@ export default function InputBox() {
275276
const res = await fetch("/api/tmux/sessions");
276277
const data = await res.json();
277278
setTmuxSessions(data.sessions || []);
279+
if (data.version) setTmuxVersion(data.version);
278280
} catch { setTmuxSessions([]); }
279281
setTmuxLoading(false);
280282
};
@@ -628,6 +630,11 @@ export default function InputBox() {
628630
)}
629631
{activeGroup === TMUX_TAB && !inTmux && (
630632
<div className="border-b border-gray-700/50 bg-[#12122a] px-3 py-2">
633+
{tmuxVersion && tmuxVersion.startsWith("3.4") && (
634+
<div className="text-[10px] text-yellow-400 bg-yellow-900/20 border border-yellow-800/30 rounded px-2 py-1 mb-1.5">
635+
tmux {tmuxVersion} has known key handling issues. Upgrade to 3.5+ or add <code className="text-yellow-300">set -g extended-keys off</code> to ~/.tmux.conf
636+
</div>
637+
)}
631638
{tmuxLoading ? (
632639
<span className="text-[11px] text-gray-500">Loading...</span>
633640
) : tmuxSessions.length === 0 ? (

app/routes/api/tmux.sessions.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,36 @@
11
import { execSync } from "child_process";
22
import type { Route } from "./+types/tmux.sessions";
33

4+
function getTmuxVersion(): string | null {
5+
try {
6+
const output = execSync("tmux -V", { encoding: "utf-8", timeout: 3000 }).trim();
7+
// "tmux 3.4" or "tmux 3.5a"
8+
return output.replace(/^tmux\s+/, "");
9+
} catch {
10+
return null;
11+
}
12+
}
13+
414
export async function loader({ request }: Route.LoaderArgs) {
15+
const version = getTmuxVersion();
16+
517
try {
618
const output = execSync("tmux list-sessions -F '#{session_name}:#{session_windows}:#{session_attached}'", {
719
encoding: "utf-8",
820
timeout: 3000,
921
}).trim();
1022

1123
if (!output) {
12-
return Response.json({ sessions: [] });
24+
return Response.json({ sessions: [], version });
1325
}
1426

1527
const sessions = output.split("\n").map((line) => {
1628
const [name, windows, attached] = line.split(":");
1729
return { name, windows: parseInt(windows, 10), attached: attached === "1" };
1830
});
1931

20-
return Response.json({ sessions });
32+
return Response.json({ sessions, version });
2133
} catch {
22-
// tmux not running or not installed
23-
return Response.json({ sessions: [] });
34+
return Response.json({ sessions: [], version });
2435
}
2536
}

0 commit comments

Comments
 (0)