Skip to content

scottpeterman/tetherssh

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TetherSSH - SSH Terminal Emulator

A Go-based SSH terminal emulator with session management, built on Fyne 2 GUI framework and the gopyte terminal emulation library.

The first fully-functional Fyne-based SSH terminal with session management, scrollback history, bracketed paste, and text selection.

View on Fyne Apps Showcase

Screenshots

Session Manager with Tree View

TetherSSH Session Manager

Hierarchical folder/session tree with search filter, connection status indicators, and multi-tab interface

Full-Screen Applications

TetherSSH running htop

htop running with full 256-color support, proper resize handling, and alternate screen buffer

Session Editor

TetherSSH Session Editor

CRUD interface for managing sessions and folders with full authentication configuration


Current Status: Alpha (v0.3.0)

Working

  • SSH connectivity with password and public key authentication
  • Multi-tab terminal interface with tree-based session navigator
  • Full terminal emulation via gopyte (VT100/ANSI parsing)
  • Keyboard input routing to SSH sessions
  • Dynamic terminal resize with proper SSH window-change signaling
  • Full-screen applications (htop, vim, nano, etc.)
  • 256-color support with proper color mapping
  • Independent app and terminal theming - three built-in themes (Cyber, Light, Corporate) selectable separately for the chrome and the terminal pane, with per-theme color customization
  • Flicker-free standard-mode rendering via incremental per-cell updates
  • HiDPI-safe cell backgrounds and selection - device-pixel-snapped background rendering, no tiling seams on scaled displays
  • Scrollback history (1000+ lines) with mouse wheel scrolling
  • Text selection with clipboard support (double-click word, triple-click line)
  • Right-click Copy/Paste context menu in the terminal
  • Bracketed paste - multi-line content (configs, scripts) pastes verbatim into vim, editors, and shells, with no auto-indent cascade or premature line-by-line execution
  • Optional paced paste with a configurable per-line delay for slow CLI parsers (network gear, serial-style links)
  • Tree-based session navigator with collapsible folders
  • Right-click context menu on sessions (Connect, Edit)
  • Session persistence via YAML configuration
  • Session search/filter for quick access to devices
  • Session editor with full CRUD operations
  • Quick Connect dialog for ad-hoc connections
  • SSH key authentication with encrypted key support
  • Settings dialog with persistent configuration
  • Session logging - cleaned, timestamped transcript per session, toggled live from the terminal right-click menu (Start/Stop Logging), with optional auto-start per session or globally

Known Issues

  • SSH agent support not fully implemented
  • Host key verification not yet implemented
  • Alternate-screen (full-screen app) rendering uses a full-grid repaint rather than the incremental path used in standard mode

Key Features

Terminal Emulation

TetherSSH uses gopyte, a custom terminal emulation library written specifically for this project. Unlike the Fyne project's proof-of-concept terminal, gopyte provides:

  • Full history buffer with configurable scrollback (default 1000 lines)
  • Wide character support for CJK characters and emojis
  • Alternate screen buffer for full-screen applications (vim, htop, less)
  • Proper resize handling that syncs local screen, gopyte buffers, and SSH session

Standard-mode output is rendered incrementally: each redraw diffs against the on-screen grid and repaints only the cells that actually changed, so typing stays flicker-free even over colored prompts. All redraws are driven by a single coalesced update pass on a short timer rather than one repaint per byte received. Full-screen (alternate-screen) applications use a full-grid repaint, since they tend to redraw most of the screen on each update anyway.

Paste Handling

  • Bracketed paste (DEC mode 2004): when the remote application requests it (vim, shells, editors), pasted text is wrapped in paste markers so it inserts verbatim - no auto-indent stair-stepping, and no multi-line commands running line by line. Mode 2004 is tracked on both the local PTY and SSH output paths.
  • Optional line pacing: a configurable per-line delay (Settings -> Paste Line Delay) for slow CLI parsers on network gear or serial-style links that do not support bracketed paste.
  • Unified paste path: the Ctrl+V / Cmd+V shortcut and the right-click Paste menu both route through the same handler, and Ctrl+C aborts an in-flight paced paste.

Session Management

  • Tree-based navigator with collapsible folders and session counts
  • Right-click context menu for quick Connect or Edit
  • Real-time search/filter - instantly find sessions by name, host, group, or device type
  • Multiple concurrent SSH connections in tabs
  • Visual connection status indicators
  • One-click connect with automatic credential handling

Authentication Support

  • Password authentication - prompted on connect or stored in session
  • SSH key authentication - supports RSA, ECDSA, Ed25519 keys
  • Encrypted key support - passphrase prompts for protected keys
  • Keyboard-interactive - for MFA/RADIUS environments (including YubiKey)
  • Configurable per-session authentication type

Quick Connect

Press the fast-forward button for ad-hoc connections without saving a session:

  • Enter host, port, username
  • Choose Password or SSH Key authentication
  • Default key path: ~/.ssh/id_rsa
  • Optional key passphrase for encrypted keys

Session Editor

Press the gear button to open the full session manager:

  • Folders panel - organize sessions into groups
  • Sessions panel - view/edit sessions in selected folder
  • Add/Edit/Delete - full CRUD operations
  • Import - load sessions from other YAML files
  • Export - save current configuration
  • Device metadata fields (type, vendor, model) for network equipment

Session Persistence

All configuration is stored in ~/.tetherssh/:

  • Sessions: ~/.tetherssh/sessions/sessions.yaml
  • Settings: ~/.tetherssh/settings.json
  • Logs: ~/.tetherssh/logs/ (when logging is enabled)
# TetherSSH Sessions File
# Auth types: password, publickey, keyboard-interactive

- folder_name: Production
  sessions:
    - display_name: web-server-01
      host: 10.0.1.10
      port: "22"
      username: admin
      auth_type: publickey
      key_path: ~/.ssh/id_rsa
      DeviceType: linux

- folder_name: Lab
  sessions:
    - display_name: cisco-router
      host: 172.16.1.1
      port: "22"
      username: admin
      auth_type: password
      DeviceType: cisco_ios
      Vendor: Cisco

Settings

Press the gear icon in the toolbar to open the Settings dialog. Settings are persisted to ~/.tetherssh/settings.json.

Terminal Tab

Setting Description Default
Row Offset Adjust terminal row calculation (increase for Retina/HiDPI displays) 2
Column Offset Adjust terminal column calculation 0
Font Size Terminal font size in points (not yet implemented) 12
Scrollback Lines History buffer size (not yet implemented) 1000
Paste Line Delay Per-line delay for multi-line paste; paces output for slow CLI parsers (None / 25 / 50 / 100 / 250 ms) None
Copy on Select Auto-copy selected text to clipboard (not yet implemented) Off

Appearance Tab

Setting Description Default
App Theme Theme for the application chrome (sidebar, tabs, toolbar, dialogs) Cyber
Terminal Theme Theme for the terminal pane (background, default text, ANSI palette) Cyber
Remember Window Size Restore window dimensions on startup On

The two selectors are independent - see Themes below. Changing the App Theme applies immediately; the Terminal Theme applies to newly connected tabs (reconnect an open tab to repaint it).

Themes

TetherSSH separates theming into two independent axes, both set on the Appearance tab:

  • App Theme drives the application chrome - sidebar, tabs, toolbar, dialogs, buttons - via the Fyne theme.
  • Terminal Theme drives the terminal pane on its own - its background, the default (unset-color) text color, and which ANSI palette colored output maps to.

Because the axes are separate, the chrome and the terminal can run different themes. Three built-in themes are available on each axis:

Theme Chrome Terminal pane
Cyber Deep blue-black with cyan / matrix-green accents Black background, bright on-dark ANSI palette
Light White surfaces with a Microsoft-blue accent (Fluent/Office) White background, dark-on-light ANSI palette
Corporate Navy with cyan accents Navy background, bright on-dark ANSI palette

This yields any combination of the two - for example Corporate chrome over a Light terminal gives a navy application frame around a white terminal pane.

The terminal's default text color (output with no explicit color, e.g. most shell and htop text) is taken from the active terminal palette's default entry, so it stays legible against that palette's own background rather than inheriting the chrome's foreground.

Colors Tab

Each built-in theme can be customized. The Colors tab has a sub-tab per theme (Cyber, Light, Corporate); leave a field blank to use the theme's built-in value. Overridable colors include primary/accent, secondary, background, surface, surface variant, foreground, input background/border, selection, hover, and error/success/warning. A live preview updates as you edit, and changes apply without restarting. Overrides are stored per theme in settings.json.

SSH Tab (not yet implemented)

Setting Description Default
Default SSH Key Default key path for new sessions ~/.ssh/id_rsa
Default Port Default SSH port 22
Default Username Pre-fill username for new sessions (empty)
Connection Timeout SSH connection timeout in seconds 30
Keepalive Interval SSH keepalive interval in seconds 60

Logging Tab

Session logs are cleaned transcripts: ANSI/control sequences are stripped and carriage-return/backspace edits applied, so each logged line matches what was on screen. Logging is toggled live per session from the terminal right-click menu (Start/Stop Logging); the settings below are the global defaults.

Setting Description Default
Auto-start logging on new connections Begin logging automatically when a session connects Off
Log Directory Directory for session logs ~/.tetherssh/logs
Add timestamps to log entries Prefix each line with a timestamp On

Log filename format: {session_name}_{YYYYMMDD_HHMMSS}.log

Any session may also set logging: true in its YAML to auto-start logging on connect. Full-screen apps (vim, htop) drive the screen by cursor addressing and will log as noise - logging is intended for line-oriented CLI sessions.


File Structure

tetherssh/
├── cli/
│   ├── main.go                  # Application entry, window setup
│   ├── paths.go                 # Centralized path management (~/.tetherssh)
│   ├── session_manager.go       # Tree navigator, search, tab management
│   ├── session_persistence.go   # YAML load/save, SessionStore
│   ├── session_editor.go        # CRUD modal dialog
│   ├── settings.go              # Application settings dialog
│   ├── ssh_backend.go           # SSH client, auth chain, SSHTerminalWidget
│   ├── terminal_logger.go       # Session logging - cleaned, timestamped transcript
│   ├── terminal_widget.go       # NativeTerminalWidget - core terminal UI
│   ├── terminal_pty.go          # Local PTY support, WriteToPTY, history
│   ├── terminal_events.go       # Keyboard/mouse event handling
│   ├── terminal_events_bus.go   # Event bus for terminal events
│   ├── terminal_display.go      # TextGrid rendering, incremental cell diff, viewport
│   ├── terminal_bglayer.go      # Cell/selection background overlay (HiDPI-safe snapped runs)
│   ├── terminal_paste.go        # Paste handling - bracketed paste, line pacing, context menu
│   ├── terminal_selection.go    # Text selection and clipboard
│   ├── terminal_containers.go   # Custom container widgets
│   ├── tappable_tree_node.go    # Right-click support for tree nodes
│   ├── theme.go                 # Named themes (chrome + terminal), color mappings
│   ├── pty_unix.go              # Unix PTY implementation
│   └── pty_windows.go           # Windows PTY implementation
├── internal/
│   └── gopyte/                  # Terminal emulation library
│       ├── screen.go            # Base screen buffer (NativeScreen)
│       ├── screen_interface.go  # Screen interface definitions
│       ├── history_screen.go    # Scrollback history management
│       ├── wide_char_screen.go  # Wide character support
│       ├── alternative_screen.go # Alternate screen buffer (vim, htop)
│       ├── streams.go           # ANSI escape sequence parser
│       ├── escape.go            # Escape sequence definitions
│       ├── control.go           # Control character handling
│       ├── graphics.go          # SGR/graphics attributes
│       ├── modes.go             # Terminal mode handling
│       ├── charset.go           # Character set support
│       └── gopyte_test/         # Test suite
├── screenshots/
│   ├── htop.png
│   ├── session_detail.png
│   └── session_manager.png
├── go.mod
├── go.sum
├── LICENSE
└── README.md

Building

Prerequisites

  • Go 1.21 or later
  • GCC compiler (required for CGO/OpenGL):
    • Windows: Install TDM-GCC from https://jmeubank.github.io/tdm-gcc/ (MinGW-w64 based)
    • Linux: sudo apt install build-essential (Debian/Ubuntu) or equivalent
    • macOS: xcode-select --install

Development Build

# Linux/macOS - run directly
go run -tags='!windows' ./cli

# Linux/macOS - build with debug symbols
go build -tags='!windows' -o tetherssh ./cli

# Windows - run directly
go run ./cli

# Windows - build with debug symbols
go build -o tetherssh.exe ./cli

Release Build (Recommended)

Stripped binaries are approximately 50% smaller with no debug symbols.

# Linux/macOS
go build -tags='!windows' -ldflags="-s -w" -o tetherssh ./cli

# Windows
go build -ldflags="-s -w" -o tetherssh.exe ./cli

Cross-Compilation

Cross-compiling Fyne apps requires CGO, which complicates cross-builds. Build natively on each target platform, or use fyne-cross with Docker:

# Install fyne-cross
go install github.com/fyne-io/fyne-cross@latest

# Build for Windows from Linux/macOS
fyne-cross windows -arch=amd64 ./cli

# Build for Linux from macOS/Windows
fyne-cross linux -arch=amd64 ./cli

Binary Sizes (typical)

Build Type Size
Debug (full symbols) ~53 MB
Release (stripped) ~26 MB
Zipped release ~12 MB

Dependencies

fyne.io/fyne/v2               # GUI framework
golang.org/x/crypto/ssh       # SSH client
github.com/creack/pty         # Local PTY (Unix)
github.com/mattn/go-runewidth # Wide character width calculation
github.com/google/uuid        # Tab/session unique IDs
gopkg.in/yaml.v3              # Session persistence

Configuration

Configuration Location

TetherSSH stores all configuration in ~/.tetherssh/:

File Purpose
~/.tetherssh/sessions/sessions.yaml Session definitions
~/.tetherssh/settings.json Application settings
~/.tetherssh/logs/ Session logs (when enabled)

On first run, a stub sessions file is created with example entries.

Supported Auth Types

YAML Value Description
password Prompt for password on connect
publickey Use SSH key from key_path
keyboard-interactive MFA/RADIUS environments

Key Path Expansion

The ~ character is expanded to the user's home directory:

  • ~/.ssh/id_rsa becomes /home/username/.ssh/id_rsa (Linux)
  • ~/.ssh/id_rsa becomes /Users/username/.ssh/id_rsa (macOS)
  • ~/.ssh/id_rsa becomes C:\Users\username\.ssh\id_rsa (Windows)

Roadmap

Phase 1: Core Features (Complete)

  • Fix vim/htop resize issues
  • Implement resize callback pattern
  • Post-connect resize sync
  • Buffer bounds safety in gopyte
  • Session persistence (YAML config)
  • Public key authentication
  • Encrypted key passphrase support
  • Session search/filter
  • Session editor with CRUD
  • Quick Connect dialog
  • Tree-based session navigator
  • Settings dialog with persistence
  • Right-click context menu
  • Bracketed paste support (DEC mode 2004)
  • Right-click Copy/Paste in terminal
  • Optional paced multi-line paste
  • Incremental, flicker-free standard-mode rendering
  • HiDPI-safe background and selection rendering (no tiling seams)
  • Session logging (cleaned, timestamped transcripts; live right-click toggle)

Phase 2: Stability (Current)

  • Implement SSH agent support
  • Add host key verification with known_hosts
  • Clean up debug logging (gate render/paste diagnostics behind a debug flag)
  • Bring incremental rendering to the alternate screen (full-screen apps)
  • More cross-platform testing (Windows, Linux, macOS)

Phase 3: Logging and Security

  • Log viewer/browser
  • Encrypted credentials manager (AES-256-GCM)
  • Master password unlock flow
  • Credential references in sessions (decouple passwords from YAML)

Phase 4: Terminal Features

  • Split panes (horizontal/vertical)
  • Find in terminal output
  • Clickable URLs
  • Command snippets/macros

Phase 5: Advanced

  • SFTP file browser integration
  • Port forwarding UI
  • Jump host/proxy support
  • Session import from PuTTY/SecureCRT

gopyte Terminal Emulation

gopyte is a terminal emulation library built specifically for TetherSSH. It provides:

Screen Hierarchy

  • NativeScreen: Base screen buffer
  • HistoryScreen: Adds scrollback history
  • WideCharScreen: Adds wide character support and alternate screen buffer

Key Features

  • VT100/ANSI parsing via Stream.Feed()
  • Scrollback history with linked list storage
  • Alternate screen buffer for vim, htop, less, etc.
  • Wide character support for CJK and emojis
  • Resize handling that preserves content and history

Escape Sequences Supported

  • Cursor movement (CUP, CUU, CUD, CUF, CUB)
  • Erase operations (ED, EL)
  • SGR attributes (colors, bold, underline, etc.)
  • Scroll regions (DECSTBM)
  • Alternate screen (DECSET/DECRST 1049)
  • Bracketed paste mode (DECSET/DECRST 2004)
  • Window title (OSC 0, 1, 2)

Related Projects


License

MIT License - See LICENSE file


Last updated: May 28, 2026

Author: Scott Peterman

About

A Go-based SSH terminal emulator with session management, built on Fyne 2 GUI framework and the gopyte terminal emulation library.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages