Overview
SSH Portfolio is built with Go using three main libraries:- Wish - SSH server framework
- Bubble Tea - Terminal UI framework with The Elm Architecture
- Lipgloss - Terminal styling and layout
Core Components
1. SSH Server (Wish)
The application uses Charm’s Wish library to create an SSH server that serves interactive terminal UIs.main.go:36-44
- Listens on
0.0.0.0:2222by default (configurable viaSSH_PORTenv var) - Uses Ed25519 host key from
.ssh/id_ed25519 - Runs with graceful shutdown handling (30s timeout)
2. Middleware Stack
The server uses three middleware layers in order:| Middleware | Purpose | Source |
|---|---|---|
bubbletea.Middleware | Runs Bubble Tea programs for each SSH session | main.go:40 |
activeterm.Middleware | Filters out non-interactive terminals | main.go:41 |
logging.Middleware | Logs SSH connection events | main.go:42 |
3. Configuration Loader
Loads portfolio data fromconfig.yaml on startup:
main.go:31-34
4. TUI Framework (Bubble Tea)
Each SSH session runs an independent Bubble Tea program with The Elm Architecture:Model Initialization
TheteaHandler function creates a new model for each SSH connection:
main.go:70-77
- Extract PTY dimensions from SSH session
- Create a Lipgloss renderer for the session
- Initialize the UI model with config and dimensions
- Enable alternate screen buffer (restores terminal on exit)
Message Flow
Update Cycle
Bubble Tea processes messages through theUpdate method:
ui/model.go:59-97
- Window resize events (updates dimensions)
- Global keyboard shortcuts (
q, arrows for navigation) - Delegation to active page model for page-specific input
Render Cycle
TheView method renders the UI in three parts:
ui/model.go:99-127
Directory Structure
Package Responsibilities
| Package | Purpose | Key Files |
|---|---|---|
main | Server initialization, middleware setup | main.go |
config | Configuration loading and schema | config/config.go |
ui | All UI components and rendering logic | ui/*.go |
Page Models
Each page implements its own model withUpdate and View methods:
cursor field for selection state.
See UI Components for detailed component reference.
Styling System
All styling uses Lipgloss with Catppuccin Mocha theme:ui/theme.go
*lipgloss.Renderer passed from the session.
Key Design Patterns
The Elm Architecture
All UI logic follows TEA principles:- Model - Application state (immutable)
- Update - State transitions based on messages
- View - Pure rendering function from state
Session Isolation
Each SSH connection gets:- Independent Bubble Tea program instance
- Separate renderer for terminal capabilities
- Own copy of the config data
- Isolated state (cursor positions, active page)
Layout Calculation
Available content space is calculated dynamically:ui/model.go:129-139
tabBarHeight = 3, statusBarHeight = 1