Skip to content

fix: route switch-client CLI to source session server (#202)#214

Merged
psmux merged 1 commit into
psmux:masterfrom
tarikguney:fix/switch-client-routing
Apr 14, 2026
Merged

fix: route switch-client CLI to source session server (#202)#214
psmux merged 1 commit into
psmux:masterfrom
tarikguney:fix/switch-client-routing

Conversation

@tarikguney

Copy link
Copy Markdown
Collaborator

Summary

Fixes the remaining CLI path issue from #202: psmux switch-client -t <session> returns exit 0 but does not switch when invoked from the command line (works from prefix + :).

Root cause: The global -t parser in main.rs sets PSMUX_TARGET_SESSION for all commands, routing send_control() to the target session's server. But for switch-client, -t means "switch TO this session" (destination), not "route to this session's server" (source). The destination server receives the command and responds "already on that session" — doing nothing.

Fix: Skip setting PSMUX_TARGET_SESSION when the command is switch-client or switchc, so the existing TMUX-based fallback resolves the current (source) session for routing. PSMUX_TARGET_FULL still carries the destination for the server-side handler in connection.rs.

Repro (before fix)

# Inside a psmux pane (session "claude-watch"):
psmux switch-client -t convserv    # exit 0, no switch
# prefix + : → switch-client -t convserv  # works

Test plan

  • psmux switch-client -t <other-session> from CLI switches the terminal
  • psmux switch-client -n / -p / -l from CLI still work
  • prefix + :switch-client -t <session> still works
  • Other commands with -t (e.g. select-window -t session:window) still route correctly
  • Existing Rust unit tests pass (cargo test)

…psmux#202)

The global -t parser sets PSMUX_TARGET_SESSION for all commands, but
switch-client -t means "switch TO this session" (destination), not
"route to this session's server". This caused the command to be sent
to the destination server, which responded "already on that session"
and did nothing.

Fix: skip setting PSMUX_TARGET_SESSION when the command is switch-client,
letting the TMUX-based fallback resolve the current (source) session for
routing. PSMUX_TARGET_FULL still carries the destination target for the
server-side handler.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@psmux

psmux commented Apr 14, 2026

Copy link
Copy Markdown
Owner

Hey @tarikguney, what a great contribution. You didn't just report the bug, you dug into the source, traced the exact routing path, identified the precise line where the logic went wrong, and delivered a clean minimal fix. That kind of investigative work is genuinely rare and I want you to know it is really appreciated.

Your root cause analysis was spot on. The global -t parser in main.rs treats -t the same for every command, which is correct for things like select-window or send-keys where -t means "route to this session's server." But for switch-client, -t means "switch TO this session," so the command was being sent to the destination server, which unsurprisingly responded with nothing because it was already on that session.

I reviewed the change carefully, traced the full execution path from CLI invocation through send_control into the server handler, confirmed that PSMUX_TARGET_FULL still carries the destination correctly for the server side, and ran the full test suite (910 unit tests, all passing) before merging. The fix is exactly right and the scope is just what it needs to be.

Merged in df54346 as part of commit cb28ab1.

Looking forward to seeing what claude-watch does with proper programmatic session switching. That project sounds really cool. Thank you again for pushing this all the way through.

1 similar comment
@psmux

psmux commented Apr 14, 2026

Copy link
Copy Markdown
Owner

Hey @tarikguney, what a great contribution. You didn't just report the bug, you dug into the source, traced the exact routing path, identified the precise line where the logic went wrong, and delivered a clean minimal fix. That kind of investigative work is genuinely rare and I want you to know it is really appreciated.

Your root cause analysis was spot on. The global -t parser in main.rs treats -t the same for every command, which is correct for things like select-window or send-keys where -t means "route to this session's server." But for switch-client, -t means "switch TO this session," so the command was being sent to the destination server, which unsurprisingly responded with nothing because it was already on that session.

I reviewed the change carefully, traced the full execution path from CLI invocation through send_control into the server handler, confirmed that PSMUX_TARGET_FULL still carries the destination correctly for the server side, and ran the full test suite (910 unit tests, all passing) before merging. The fix is exactly right and the scope is just what it needs to be.

Merged in df54346 as part of commit cb28ab1.

Looking forward to seeing what claude-watch does with proper programmatic session switching. That project sounds really cool. Thank you again for pushing this all the way through.

psmux added a commit that referenced this pull request Apr 14, 2026
Rust (8 new tests in test_issue202_switch_client.rs):
- pr214_switch_client_t_does_not_set_target_session
- pr214_switchc_alias_does_not_set_target_session
- pr214_other_commands_still_set_target_session (regression: select-window etc. unaffected)
- pr214_no_explicit_session_never_sets_target
- pr214_switch_client_n/p/l_no_explicit_session
- pr214_regression_old_code_was_buggy (documents the pre-fix behavior)

PowerShell E2E (tests/test_issue202_cli_routing.ps1, 5 tests / 9 assertions):
- Test 1: CLI with TMUX->alpha delivers SWITCH to alpha's server, NOT beta's
- Test 2: switchc alias routes identically
- Test 3: select-window -t still routes to destination (no regression)
- Test 4: switch-client -n routes to source session via TMUX fallback
- Test 5: switch-client -t without TMUX uses last-session fallback gracefully

All 26 issue #202 Rust tests pass. All 910 unit tests pass.
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.

2 participants