Skip to content

Add 'swash attach' command for interactive TTY session attachment #8

@mbrock

Description

@mbrock

Summary

Add an attach command that connects your terminal to a running TTY session, allowing you to view and interact with it in real-time (like screen -x or tmux attach).

Currently, TTY sessions can be started in the background (swash start --tty -- htop) and their screen can be viewed as a snapshot (swash screen ABC123), but there's no way to interactively connect your terminal to view live updates and send input.

Proposed command

swash attach <session_id>          # attach to a TTY session
swash attach --readonly <session_id>  # view-only mode (optional)

Implementation considerations

Read-only vs interactive

Option A: Start with read-only

  • Simpler to implement: just poll GetScreenANSI() periodically and redraw
  • No input forwarding needed
  • Lower risk of interfering with the background process

Option B: Full interactive from the start

  • The infrastructure already exists: SendInput() D-Bus method works, Resize() exists
  • Read-only might feel incomplete to users expecting screen/tmux behavior
  • Probably not much harder since input forwarding is just stdin -> SendInput()

Recommendation: Go with full interactive. The plumbing is already there, and read-only attach feels like a half-measure. We already have swash screen for snapshots.

Terminal size handling

This is the tricky part. The background TTY session was started with a specific size (e.g., --rows 40 --cols 120), but the attaching terminal might be different.

Options:

  1. Resize the session to match the attaching terminal

    • Pros: Natural UX, what you see is what you get
    • Cons: If the process is running (e.g., vim), resizing might cause UI glitches; if multiple clients attach, who controls the size?
    • Implementation: Call Resize() on attach, then SIGWINCH to the process
  2. Require the attaching terminal to match

    • Pros: Simple, no ambiguity
    • Cons: Annoying UX - user has to manually resize their terminal
    • Implementation: Check sizes, error if mismatch
  3. Viewport/scrolling for size mismatch

    • Pros: Never lose content
    • Cons: Complex to implement, weird UX for interactive programs
    • If local terminal is smaller: show a scrollable viewport of the session
    • If local terminal is larger: pad with empty space or center the content
  4. Warn but allow mismatch

    • Pros: Flexible, lets user decide
    • Cons: Could lead to garbled display
    • Show warning like "Session is 40x120, your terminal is 24x80. Content may be clipped."

Recommendation: Start with option 1 (resize session to match), with a --no-resize flag for option 4. This matches screen/tmux behavior. For multiple attached clients, last-attach-wins for size control (or could add a --readonly flag that doesn't resize).

Screen refresh mechanism

Two approaches for keeping the display updated:

  1. Polling: Call GetScreenANSI() every N milliseconds, redraw if changed

    • Simple to implement
    • Some latency, wastes CPU if nothing changed
    • Reasonable starting point
  2. D-Bus signals: Have TTYHost emit a signal on screen changes

    • More efficient, lower latency
    • Requires adding signal support to the D-Bus interface
    • Better long-term solution

Recommendation: Start with polling (maybe 50-100ms interval). Add D-Bus signals later if performance becomes an issue.

Raw mode and signal handling

The attaching client needs to:

  • Put the local terminal in raw mode (disable line buffering, echo)
  • Forward all input bytes to SendInput(), including control characters
  • Handle SIGWINCH to resize the session (if option 1)
  • Handle Ctrl+\ or similar as a detach key (escape hatch)
  • Restore terminal state on exit

Multiple attachers

Should we support multiple terminals attached to the same session?

  • Screen allows this (screen -x), all see the same thing
  • Could be useful for pair programming or demos
  • Complicates size handling (whose size wins?)

Recommendation: Support it, but keep it simple. All attachers see the same screen. Size is controlled by the most recent non-readonly attacher.

Questions to resolve

  1. What should the detach key sequence be? (Ctrl+] like telnet? ~. like ssh? Something else?)
  2. Should attach block until the session exits, or return to prompt on detach?
  3. Should we add a --size flag to override the resize behavior?

Related

  • This complements the existing swash screen (snapshot) and swash send (one-shot input) commands
  • Would make TTY mode much more useful for interactive programs like vim, htop, etc.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions