Skip to content

feat(badge): show the multiplexer a session runs in next to the terminal - #326

Open
mutoe wants to merge 1 commit into
wxtsky:mainfrom
mutoe:feat/multiplexer-badge
Open

feat(badge): show the multiplexer a session runs in next to the terminal#326
mutoe wants to merge 1 commit into
wxtsky:mainfrom
mutoe:feat/multiplexer-badge

Conversation

@mutoe

@mutoe mutoe commented Aug 25, 2026

Copy link
Copy Markdown

Problem

A CLI running under tmux inside iTerm2 is labelled just iTerm2. The multiplexer it actually sits in is invisible on the badge, even though several sessions in the same terminal may live in different tmux panes — or different tmux sessions entirely.

The data is already there. From a real ~/.codeisland/sessions.json:

{"source":"claude", "termApp":"tmux", "termBundleId":"com.googlecode.iterm2",
 "tmuxEnv":"/private/tmp/tmux-501/default,27935,0", "tmuxPane":"%11", ...}

termApp is tmux, and tmuxEnv / tmuxPane are captured alongside it — activateTmux already relies on them for click-to-jump. But terminalName resolves from termBundleId alone, so it hits com.googlecode.iterm2 and returns "iTerm2"; the multiplexer layer never reaches the badge. Nothing in the collection path needs to change.

Change

SessionSnapshot.multiplexerLabel — the multiplexer layered on top of the terminal — rendered by TerminalBadge as a small chip after the terminal name, in the chip vocabulary already used by the queue counter and the AskUserQuestion header. Both the local and remote branches of the badge get it: SSH sessions are frequently inside tmux too.

The chip augments the terminal name, never replaces it — you still want to know it's iTerm2.

Two deliberate exclusions

cmux is not reported as a multiplexer. It is a terminal app, already named by terminalName (if lower.contains("cmux") { return "cmux" }). Reporting it again here would render the same word twice on one badge. There's a regression test pinning this.

screen is not covered. STY is never captured anywhere in the codebase, so supporting it means touching the hook collection path — a separate change. tmux and zellij both have their env vars already recorded, so they cost nothing.

Nesting

Nested multiplexers each leave their env vars behind, so multiplexerLabel returns the innermost layer — the one the CLI actually sits in. zellij inside tmux reads zellij. This matches how click-to-jump already treats the pair (see the zellij-inside-Terax handling in v1.0.31).

Tests

New SessionMultiplexerLabelTests, built test-first:

  • tmux inside iTerm2 → "tmux", and terminalName still "iTerm2" (the chip must not swallow the terminal)
  • zellij → "zellij"
  • zellij nested in tmux → "zellij" (innermost wins)
  • cmux → nil, with terminalName asserted as "cmux" (pins the no-double-render rule)
  • plain terminal → nil

Full suite green locally on macOS 26.4 / Xcode 26 (Swift 6.3.3): 890 tests, 2 skipped, 0 failures. swift build clean.

Note

Independent of #325 — different files apart from a non-overlapping region of NotchPanelView.swift, and either can merge first.

A CLI running under tmux inside iTerm2 was labelled just "iTerm2". The
multiplexer data was already captured — termApp is "tmux", with tmuxEnv and
tmuxPane alongside it — but terminalName resolves from termBundleId alone,
so the layer the CLI actually sits in never reached the badge.

Add SessionSnapshot.multiplexerLabel and render it as a small chip after the
terminal name, using the chip vocabulary already used by the queue counter
and the AskUserQuestion header.

Two deliberate exclusions:

- cmux is a terminal app, already named by terminalName. Reporting it as a
  multiplexer too would print the same word twice on one badge.
- screen is not covered: STY is never captured, so supporting it means
  touching the hook collection path, which this change does not.

Nested multiplexers each leave their env vars behind, so the innermost layer
wins — zellij inside tmux reads "zellij".
@mutoe

mutoe commented Aug 25, 2026

Copy link
Copy Markdown
Author
image

nguyenvanduocit pushed a commit to nguyenvanduocit/CodeIsland that referenced this pull request Aug 26, 2026
…badge, T-088 question card jump)

New open PRs on wxtsky/CodeIsland (Aug 25, 2026):
- T-088: PR wxtsky#325 — click question card to jump to asking terminal (medium, S; depends on T-036)
- T-087: PR wxtsky#326 — multiplexer badge chip on session cards (low, XS; depends on T-055)

Both gated on upstream merge. Upstream otherwise quiet 11 days since v1.0.32.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UXGjprGYFRNkJMwaYmddBJ
nguyenvanduocit pushed a commit to nguyenvanduocit/CodeIsland that referenced this pull request Aug 29, 2026
…1.0.32)

No new commits on wxtsky/CodeIsland or vibeislandapp/vibe-island since
Aug 26. Issues wxtsky#327 (Qoder) and wxtsky#328 (Codex) are non-Claude CLI specific.
PRs wxtsky#314, wxtsky#323, wxtsky#325, wxtsky#326 remain open and watching. No actionable items.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T4KU8w1bHuFtRzeNAvW1bn
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant