You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Today the local→remote rendezvous is a single file: ~/.local/state/nssh/session (TOML with server + topic). Every nssh <host> writes that file, every shim invocation reads it. Consequence: two nssh hostA invocations stomp each other, the last writer wins, and any earlier subscriber gets silently orphaned. #11 papered over this with a per-host pidfile registry + join/replace/new UX, but the root cause is the shared file.
What's available to piggyback on
Honest survey:
Convention
Per-session?
ssh
mosh
tmux-survivable
Linux-only
SSH_CONNECTION (sshd)
yes (client port unique per conn)
✓
⚠ stale (refers to bootstrap ssh)
⚠ tmux strips unless update-environment lists it
no
SSH_TTY (sshd)
yes
✓
✗
⚠ tmux strips
no
XDG_SESSION_ID (pam_systemd)
yes
✓
⚠ depends on PAM stack
⚠ tmux strips
yes
MOSH_KEY (mosh-server)
yes
✗
✓
✓ inherited
no
loginctl list-sessions
yes (query)
✓
⚠ same
n/a
yes
None is both portable across ssh+mosh and stable through tmux detach/reattach.
Proposal: inject our own NSSH_SESSION
Each nssh <host> mints a sid (generateTopic()-style random) and writes ~/.local/state/nssh/sessions/<sid>.toml on the remote with that session's server + topic. The legacy single-file session is dropped.
Shim reads $NSSH_SESSION and looks up ~/.local/state/nssh/sessions/$NSSH_SESSION.toml.
$NSSH_SESSION survives tmux because tmux inherits its initial env from the shell that started it. First tmux (or tmux attach) from inside the nssh-spawned shell bakes the sid into the tmux server's env permanently; every pane and window inherits it forever.
Each nssh invocation becomes a fully independent bridge. No collisions. The --join/--replace/--new flags from #11 become unnecessary (and should probably be removed once this lands, otherwise they're vestigial).
Failure mode this doesn't cover
Local nssh dies, tmux server keeps running on the remote with the dead session's NSSH_SESSION baked in. New nssh hostA gets a fresh sid; tmux attach drops you into the old tmux server whose env still references the dead sid. Shim publishes to a dead topic.
Three reasonable handlings:
Accept it. Document: "if your local nssh dies, tmux kill-server (or tmux source-file a script that re-exports NSSH_SESSION in panes) and start fresh." Simplest, slight rough edge.
Re-discover in the shim. If ~/.local/state/nssh/sessions/$NSSH_SESSION.toml is missing/stale, walk the sessions dir on the remote, pick the newest. Almost always Does The Right Thing in a single-user setup.
Reclaim from new nssh. New nssh, on startup, lists remote sessions/, identifies orphans (no live local owner), and offers to take over a specific orphan by overwriting that file's content with the new topic. tmux env still references the same sid, file content swapped under it. Clean from the user's POV.
Recommendation: ship 1+2 together. Cheap. Worst case is "you tmux kill-server once". Option 3 is bigger and only worth it if 1+2 prove painful in practice.
Implementation notes
The shim's TOML lookup is one line different — just substitute session for sessions/<sid>.
prepareRemote's heredoc already writes the session file; just change the path to include the sid.
Need to think about how nssh status discovers remote sessions: currently it reads the single file; would need to glob sessions/*.toml instead, both locally and on the remote.
Env-injection means ssh host becomes ssh -t host '<cmd>', which is a behavioral change for users who relied on running nssh host -- <plain ssh cmd>. Need to either gate this on "is it interactive", or accept the change.
Out of scope here
The "key sessions by full SSH target identity" Codex feedback from nssh: harden session recovery #11 — once each session has its own file, that bug just goes away (no shared key to disambiguate).
Follow-up from #11.
Problem
Today the local→remote rendezvous is a single file:
~/.local/state/nssh/session(TOML withserver+topic). Everynssh <host>writes that file, every shim invocation reads it. Consequence: twonssh hostAinvocations stomp each other, the last writer wins, and any earlier subscriber gets silently orphaned. #11 papered over this with a per-host pidfile registry + join/replace/new UX, but the root cause is the shared file.What's available to piggyback on
Honest survey:
SSH_CONNECTION(sshd)update-environmentlists itSSH_TTY(sshd)XDG_SESSION_ID(pam_systemd)MOSH_KEY(mosh-server)loginctl list-sessionsNone is both portable across ssh+mosh and stable through tmux detach/reattach.
Proposal: inject our own
NSSH_SESSIONnssh <host>mints a sid (generateTopic()-style random) and writes~/.local/state/nssh/sessions/<sid>.tomlon the remote with that session'sserver+topic. The legacy single-filesessionis dropped.ssh -t host 'NSSH_SESSION=<sid> exec $SHELL -l'mosh host -- env NSSH_SESSION=<sid> $SHELL -l$NSSH_SESSIONand looks up~/.local/state/nssh/sessions/$NSSH_SESSION.toml.$NSSH_SESSIONsurvives tmux because tmux inherits its initial env from the shell that started it. Firsttmux(ortmux attach) from inside the nssh-spawned shell bakes the sid into the tmux server's env permanently; every pane and window inherits it forever.Each
nsshinvocation becomes a fully independent bridge. No collisions. The--join/--replace/--newflags from #11 become unnecessary (and should probably be removed once this lands, otherwise they're vestigial).Failure mode this doesn't cover
Local nssh dies, tmux server keeps running on the remote with the dead session's
NSSH_SESSIONbaked in. Newnssh hostAgets a fresh sid;tmux attachdrops you into the old tmux server whose env still references the dead sid. Shim publishes to a dead topic.Three reasonable handlings:
tmux kill-server(ortmux source-filea script that re-exports NSSH_SESSION in panes) and start fresh." Simplest, slight rough edge.~/.local/state/nssh/sessions/$NSSH_SESSION.tomlis missing/stale, walk the sessions dir on the remote, pick the newest. Almost always Does The Right Thing in a single-user setup.Recommendation: ship 1+2 together. Cheap. Worst case is "you
tmux kill-serveronce". Option 3 is bigger and only worth it if 1+2 prove painful in practice.Implementation notes
sessionforsessions/<sid>.nssh statusdiscovers remote sessions: currently it reads the single file; would need to globsessions/*.tomlinstead, both locally and on the remote.ssh hostbecomesssh -t host '<cmd>', which is a behavioral change for users who relied on runningnssh host -- <plain ssh cmd>. Need to either gate this on "is it interactive", or accept the change.Out of scope here