Add Go TUI implementation plan
- Comprehensive research on Go TUI libraries - Architecture design with Bubble Tea stack - 14-day implementation roadmap - Package structure and component design - User experience wireframes - Security and performance considerations
This commit is contained in:
543
GO_TUI_PLAN.md
Normal file
543
GO_TUI_PLAN.md
Normal file
@@ -0,0 +1,543 @@
|
|||||||
|
# WireGuard Client Manager - Go TUI Implementation Plan
|
||||||
|
|
||||||
|
## Executive Summary
|
||||||
|
|
||||||
|
Converting the bash-based `wg-client-manager` to a modern, responsive Go TUI application using Bubble Tea and the Charm ecosystem. This will provide a better user experience with interactive forms, real-time status updates, and intuitive navigation.
|
||||||
|
|
||||||
|
## Technology Stack
|
||||||
|
|
||||||
|
### Core Framework
|
||||||
|
- **bubbletea** (v1.3.10) - Elm-architecture TUI framework
|
||||||
|
- **lipgloss** - Expressive styling and theming
|
||||||
|
|
||||||
|
### Component Libraries
|
||||||
|
- **huh** - Terminal forms for client creation
|
||||||
|
- **bubble-table** - Interactive table for client list
|
||||||
|
- **bubbles** - Text input and other UI components
|
||||||
|
- **qrterminal** - QR code generation for terminal display
|
||||||
|
|
||||||
|
### Go Modules
|
||||||
|
- WireGuard Go library (if available) or exec-based wrapper
|
||||||
|
- Configuration management (Viper or native config)
|
||||||
|
- File system operations (os, path/filepath)
|
||||||
|
|
||||||
|
## Functional Requirements Analysis
|
||||||
|
|
||||||
|
### Commands to Implement
|
||||||
|
|
||||||
|
| Command | Current Behavior | TUI Implementation |
|
||||||
|
|---------|-----------------|-------------------|
|
||||||
|
| **add** | Interactive prompts or WGI_ env vars | Form modal with fields: name, DNS, PSK option |
|
||||||
|
| **remove** | Command-line with confirmation | Select from list → Confirm modal → Delete |
|
||||||
|
| **list** | Table view with status | Interactive table with sorting, filtering |
|
||||||
|
| **show** | Display client config | Detail view with copyable sections |
|
||||||
|
| **qr** | Display QR code | Inline QR code in modal |
|
||||||
|
|
||||||
|
### Key Features
|
||||||
|
|
||||||
|
#### 1. Client Management
|
||||||
|
- **Add client**
|
||||||
|
- Name input (regex validation: `[a-zA-Z0-9_-]+`, max 64 chars)
|
||||||
|
- Optional DNS configuration
|
||||||
|
- PSK toggle (yes/no)
|
||||||
|
- Auto-assign IPv4/IPv6 addresses
|
||||||
|
- Generate client keys
|
||||||
|
- Create server and client configs
|
||||||
|
- Generate QR code
|
||||||
|
|
||||||
|
- **Remove client**
|
||||||
|
- Select from list
|
||||||
|
- Confirmation dialog
|
||||||
|
- Remove config files
|
||||||
|
- Reload WireGuard
|
||||||
|
|
||||||
|
- **List clients**
|
||||||
|
- Table view: Name, IPv4, IPv6, Status (Connected/Disconnected)
|
||||||
|
- Sorting by column
|
||||||
|
- Filtering/search
|
||||||
|
- Real-time status refresh
|
||||||
|
|
||||||
|
- **Show client details**
|
||||||
|
- Full configuration display
|
||||||
|
- Copy to clipboard functionality
|
||||||
|
- Status information (last handshake, transfer stats)
|
||||||
|
|
||||||
|
- **QR code display**
|
||||||
|
- ANSI-colored QR code in terminal
|
||||||
|
- Toggle fullscreen/inline mode
|
||||||
|
|
||||||
|
#### 2. Configuration Loading
|
||||||
|
- Read `/etc/wg-admin/config.conf`
|
||||||
|
- Environment variable support
|
||||||
|
- Validation of required settings (SERVER_DOMAIN, WG_PORT, etc.)
|
||||||
|
|
||||||
|
#### 3. Validation
|
||||||
|
- Client name format
|
||||||
|
- IP availability checks
|
||||||
|
- DNS server format validation
|
||||||
|
- Pre-install checks (WireGuard installed, config exists)
|
||||||
|
|
||||||
|
#### 4. Security
|
||||||
|
- Run as root required
|
||||||
|
- Proper file permissions (0600 for keys)
|
||||||
|
- Atomic config writes
|
||||||
|
- Temporary key cleanup
|
||||||
|
|
||||||
|
#### 5. Backup & Recovery
|
||||||
|
- Auto-backup before add/remove
|
||||||
|
- Config backup/restore functionality
|
||||||
|
|
||||||
|
## Architecture Design
|
||||||
|
|
||||||
|
### Package Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
wg-admin-tui/
|
||||||
|
├── cmd/
|
||||||
|
│ └── main.go # Entry point
|
||||||
|
├── internal/
|
||||||
|
│ ├── config/
|
||||||
|
│ │ ├── config.go # Configuration loading
|
||||||
|
│ │ └── defaults.go # Default values
|
||||||
|
│ ├── wireguard/
|
||||||
|
│ │ ├── client.go # Client management
|
||||||
|
│ │ ├── keys.go # Key generation
|
||||||
|
│ │ ├── config.go # WireGuard config parsing
|
||||||
|
│ │ └── status.go # Status monitoring
|
||||||
|
│ ├── tui/
|
||||||
|
│ │ ├── app.go # Main TUI application
|
||||||
|
│ │ ├── model.go # Application state
|
||||||
|
│ │ ├── update.go # Message handlers
|
||||||
|
│ │ ├── view.go # Rendering
|
||||||
|
│ │ ├── screens/
|
||||||
|
│ │ │ ├── list.go # Client list view
|
||||||
|
│ │ │ ├── add.go # Add client form
|
||||||
|
│ │ │ ├── detail.go # Client detail view
|
||||||
|
│ │ │ └── qr.go # QR code view
|
||||||
|
│ │ ├── components/
|
||||||
|
│ │ │ ├── table.go # Client table
|
||||||
|
│ │ │ ├── statusbar.go # Status bar
|
||||||
|
│ │ │ └── modal.go # Modal dialogs
|
||||||
|
│ │ └── theme/
|
||||||
|
│ │ ├── colors.go # Color scheme
|
||||||
|
│ │ └── style.go # Styling utilities
|
||||||
|
│ ├── validation/
|
||||||
|
│ │ ├── client.go # Client name validation
|
||||||
|
│ │ ├── network.go # IP/DNS validation
|
||||||
|
│ │ └── config.go # Config syntax validation
|
||||||
|
│ └── backup/
|
||||||
|
│ ├── backup.go # Backup operations
|
||||||
|
│ └── restore.go # Restore operations
|
||||||
|
├── pkg/
|
||||||
|
│ └── util/
|
||||||
|
│ ├── exec.go # Command execution helpers
|
||||||
|
│ └── file.go # File operations
|
||||||
|
└── go.mod
|
||||||
|
```
|
||||||
|
|
||||||
|
### Component Design
|
||||||
|
|
||||||
|
#### 1. Main Application (app.go)
|
||||||
|
```go
|
||||||
|
type Application struct {
|
||||||
|
model Model
|
||||||
|
programs *tea.Program
|
||||||
|
config *config.Config
|
||||||
|
wireguard *wireguard.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewApplication() (*Application, error)
|
||||||
|
func (a *Application) Run() error
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. Model (model.go)
|
||||||
|
```go
|
||||||
|
type Model struct {
|
||||||
|
screen Screen // Current active screen
|
||||||
|
clients []Client // Client data
|
||||||
|
selected int // Selected client
|
||||||
|
loading bool // Loading state
|
||||||
|
error error // Error message
|
||||||
|
table table.Model // Client table
|
||||||
|
form *huh.Form // Add client form
|
||||||
|
modal *Modal // Active modal
|
||||||
|
status Status // Status bar state
|
||||||
|
}
|
||||||
|
|
||||||
|
type Screen interface {
|
||||||
|
Init() tea.Cmd
|
||||||
|
Update(msg tea.Msg) (Screen, tea.Cmd)
|
||||||
|
View() string
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3. Screens
|
||||||
|
- **ListScreen**: Display client table
|
||||||
|
- **AddScreen**: Form for adding client
|
||||||
|
- **DetailScreen**: Show client configuration
|
||||||
|
- **QRScreen**: Display QR code
|
||||||
|
|
||||||
|
#### 4. WireGuard Integration
|
||||||
|
```go
|
||||||
|
type Client struct {
|
||||||
|
Name string
|
||||||
|
IPv4 string
|
||||||
|
IPv6 string
|
||||||
|
PublicKey string
|
||||||
|
HasPSK bool
|
||||||
|
Status ConnectionStatus
|
||||||
|
LastSeen time.Time
|
||||||
|
Handshake string
|
||||||
|
ConfigPath string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Manager interface {
|
||||||
|
ListClients() ([]Client, error)
|
||||||
|
AddClient(name, dns string, usePSK bool) (*Client, error)
|
||||||
|
RemoveClient(name string) error
|
||||||
|
GetClient(name string) (*Client, error)
|
||||||
|
GetStatus() (Status, error)
|
||||||
|
ReloadConfig() error
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Implementation Roadmap
|
||||||
|
|
||||||
|
### Phase 1: Project Setup & Foundation (Days 1-2)
|
||||||
|
|
||||||
|
**Goal**: Establish project structure and core framework
|
||||||
|
|
||||||
|
**Tasks**:
|
||||||
|
- [ ] Initialize Go module
|
||||||
|
- [ ] Set up project structure
|
||||||
|
- [ ] Add dependencies (bubbletea, lipgloss, huh, bubble-table, qrterminal)
|
||||||
|
- [ ] Create configuration loading from `/etc/wg-admin/config.conf`
|
||||||
|
- [ ] Implement root check
|
||||||
|
- [ ] Create basic TUI skeleton with empty screens
|
||||||
|
- [ ] Set up logging (both file and console)
|
||||||
|
|
||||||
|
**Deliverables**:
|
||||||
|
- Working TUI that launches and shows a placeholder screen
|
||||||
|
- Configuration system in place
|
||||||
|
|
||||||
|
### Phase 2: Client List View (Days 3-4)
|
||||||
|
|
||||||
|
**Goal**: Display clients in interactive table
|
||||||
|
|
||||||
|
**Tasks**:
|
||||||
|
- [ ] Implement WireGuard client list parsing
|
||||||
|
- [ ] Create `Client` struct
|
||||||
|
- [ ] Set up bubble-table with columns: Name, IPv4, IPv6, Status
|
||||||
|
- [ ] Parse client configs from `/etc/wireguard/conf.d/client-*.conf`
|
||||||
|
- [ ] Check connection status using `wg show`
|
||||||
|
- [ ] Implement keyboard navigation (j/k, arrows, Enter, q)
|
||||||
|
- [ ] Add status bar with help text
|
||||||
|
- [ ] Implement auto-refresh (every 30 seconds)
|
||||||
|
|
||||||
|
**Deliverables**:
|
||||||
|
- Functional client list with real-time status
|
||||||
|
|
||||||
|
### Phase 3: Add Client Form (Days 5-6)
|
||||||
|
|
||||||
|
**Goal**: Create interactive form for adding clients
|
||||||
|
|
||||||
|
**Tasks**:
|
||||||
|
- [ ] Create add screen with `huh` form
|
||||||
|
- [ ] Implement fields:
|
||||||
|
- Client name (text input)
|
||||||
|
- DNS servers (text input with default)
|
||||||
|
- Use PSK (toggle/confirm)
|
||||||
|
- [ ] Add validation:
|
||||||
|
- Client name regex
|
||||||
|
- IP availability check
|
||||||
|
- DNS format validation
|
||||||
|
- [ ] Implement WireGuard key generation
|
||||||
|
- [ ] Auto-assign IPv4/IPv6 addresses
|
||||||
|
- [ ] Create server config file
|
||||||
|
- [ ] Create client config file
|
||||||
|
- [ ] Generate QR code
|
||||||
|
- [ ] Implement atomic config writes
|
||||||
|
- [ ] Auto-backup before add
|
||||||
|
- [ ] Reload WireGuard config
|
||||||
|
|
||||||
|
**Deliverables**:
|
||||||
|
- Working add client form with all validations
|
||||||
|
|
||||||
|
### Phase 4: Client Detail View (Days 7-8)
|
||||||
|
|
||||||
|
**Goal**: Show full client configuration
|
||||||
|
|
||||||
|
**Tasks**:
|
||||||
|
- [ ] Create detail screen
|
||||||
|
- [ ] Display:
|
||||||
|
- Client name
|
||||||
|
- IP addresses
|
||||||
|
- Public key
|
||||||
|
- Full configuration
|
||||||
|
- Connection status
|
||||||
|
- Last handshake
|
||||||
|
- Transfer stats (Rx/Tx)
|
||||||
|
- [ ] Implement copy to clipboard
|
||||||
|
- [ ] Add "Back" and "Delete" buttons
|
||||||
|
- [ ] Delete confirmation modal
|
||||||
|
- [ ] Remove client with config deletion
|
||||||
|
- [ ] Auto-backup before remove
|
||||||
|
- [ ] Reload WireGuard config
|
||||||
|
|
||||||
|
**Deliverables**:
|
||||||
|
- Functional detail view with delete capability
|
||||||
|
|
||||||
|
### Phase 5: QR Code Display (Days 9-10)
|
||||||
|
|
||||||
|
**Goal**: Display QR codes for mobile setup
|
||||||
|
|
||||||
|
**Tasks**:
|
||||||
|
- [ ] Create QR screen
|
||||||
|
- [ ] Read client config
|
||||||
|
- [ ] Generate QR code using `qrterminal`
|
||||||
|
- [ ] Display QR code inline
|
||||||
|
- [ ] Implement fullscreen QR mode
|
||||||
|
- [ ] Add resize handling for QR codes
|
||||||
|
- [ ] Test with various terminal sizes
|
||||||
|
|
||||||
|
**Deliverables**:
|
||||||
|
- Working QR code display
|
||||||
|
|
||||||
|
### Phase 6: Polish & UX Improvements (Days 11-12)
|
||||||
|
|
||||||
|
**Goal**: Improve user experience
|
||||||
|
|
||||||
|
**Tasks**:
|
||||||
|
- [ ] Add color themes
|
||||||
|
- [ ] Implement modal dialogs for confirmations
|
||||||
|
- [ ] Add toast notifications for success/error
|
||||||
|
- [ ] Implement search/filter clients
|
||||||
|
- [ ] Add sorting by columns
|
||||||
|
- [ ] Improve error messages with actionable guidance
|
||||||
|
- [ ] Add keyboard shortcuts help
|
||||||
|
- [ ] Implement loading indicators
|
||||||
|
|
||||||
|
**Deliverables**:
|
||||||
|
- Polished, user-friendly interface
|
||||||
|
|
||||||
|
### Phase 7: Backup & Recovery (Days 13-14)
|
||||||
|
|
||||||
|
**Goal**: Add backup and restore functionality
|
||||||
|
|
||||||
|
**Tasks**:
|
||||||
|
- [ ] Implement backup operations
|
||||||
|
- [ ] Create restore functionality
|
||||||
|
- [ ] Add backup history view
|
||||||
|
- [ ] Implement retention policy
|
||||||
|
- [ ] Add backup/restore screens
|
||||||
|
|
||||||
|
**Deliverables**:
|
||||||
|
- Complete backup/restore system
|
||||||
|
|
||||||
|
## User Experience Design
|
||||||
|
|
||||||
|
### Screen Flow
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────┐
|
||||||
|
│ Client List (Main) │
|
||||||
|
│ ┌─────┬─────┬──────────┬─────────┐│
|
||||||
|
│ │Name │IPv4 │ IPv6 │ Status ││
|
||||||
|
│ ├─────┼─────┼──────────┼─────────┤│
|
||||||
|
│ │laptop│ .2 │ ::2 │Connected││ ← Selected
|
||||||
|
│ │phone │ .3 │ ::3 │ Disc ││
|
||||||
|
│ └─────┴─────┴──────────┴─────────┘│
|
||||||
|
│ │
|
||||||
|
│ [a] Add [d] Detail [?] Help [q] Quit│
|
||||||
|
└─────────────────────────────────────┘
|
||||||
|
↓ Enter
|
||||||
|
┌─────────────────────────────────────┐
|
||||||
|
│ Client Detail: laptop │
|
||||||
|
│ │
|
||||||
|
│ Name: laptop │
|
||||||
|
│ IPv4: 10.10.69.2 │
|
||||||
|
│ IPv6: fd69:dead:beef:69::2 │
|
||||||
|
│ Status: Connected │
|
||||||
|
│ Last Handshake: 2m ago │
|
||||||
|
│ Rx: 1.2 MB Tx: 3.4 MB │
|
||||||
|
│ │
|
||||||
|
│ [Interface] │
|
||||||
|
│ PrivateKey = ... │
|
||||||
|
│ Address = 10.10.69.2/24... │
|
||||||
|
│ │
|
||||||
|
│ [ESC] Back [x] Delete [c] Copy │
|
||||||
|
└─────────────────────────────────────┘
|
||||||
|
↓ 'a' from list
|
||||||
|
┌─────────────────────────────────────┐
|
||||||
|
│ Add New Client │
|
||||||
|
│ │
|
||||||
|
│ Client Name: [_________] │
|
||||||
|
│ DNS Servers: [8.8.8.8, 8.8.4.4] │
|
||||||
|
│ Use PSK? [x] Yes │
|
||||||
|
│ │
|
||||||
|
│ [Enter] Submit [ESC] Cancel │
|
||||||
|
└─────────────────────────────────────┘
|
||||||
|
↓ 'q' from detail
|
||||||
|
┌─────────────────────────────────────┐
|
||||||
|
│ Delete Confirmation │
|
||||||
|
│ │
|
||||||
|
│ Delete client 'laptop'? │
|
||||||
|
│ │
|
||||||
|
│ [Enter] Yes [ESC] No │
|
||||||
|
└─────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### Keyboard Shortcuts
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
|-----|--------|
|
||||||
|
| `q` | Quit |
|
||||||
|
| `a` | Add client |
|
||||||
|
| `d` | Show details |
|
||||||
|
| `x` | Delete |
|
||||||
|
| `r` | Refresh |
|
||||||
|
| `/` | Search/filter |
|
||||||
|
| `↑/k` | Move up |
|
||||||
|
| `↓/j` | Move down |
|
||||||
|
| `Enter` | Select/Confirm |
|
||||||
|
| `Esc` | Back/Cancel |
|
||||||
|
| `?` | Help |
|
||||||
|
| `c` | Copy to clipboard |
|
||||||
|
|
||||||
|
### Color Scheme
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Default theme
|
||||||
|
const (
|
||||||
|
ColorPrimary lipgloss.Color
|
||||||
|
ColorSecondary lipgloss.Color
|
||||||
|
ColorSuccess lipgloss.Color
|
||||||
|
ColorWarning lipgloss.Color
|
||||||
|
ColorError lipgloss.Color
|
||||||
|
ColorMuted lipgloss.Color
|
||||||
|
)
|
||||||
|
|
||||||
|
// Example
|
||||||
|
ColorPrimary = lipgloss.Color("#007AFF") // Blue
|
||||||
|
ColorSuccess = lipgloss.Color("#34C759") // Green
|
||||||
|
ColorWarning = lipgloss.Color("#FF9500") // Orange
|
||||||
|
ColorError = lipgloss.Color("#FF3B30") // Red
|
||||||
|
ColorMuted = lipgloss.Color("#8E8E93") // Gray
|
||||||
|
```
|
||||||
|
|
||||||
|
## Error Handling Strategy
|
||||||
|
|
||||||
|
### Validation Errors
|
||||||
|
- Display inline validation messages
|
||||||
|
- Show specific error with action guidance
|
||||||
|
- Keep form state on error
|
||||||
|
- Highlight invalid fields
|
||||||
|
|
||||||
|
### System Errors
|
||||||
|
- Show modal with error message
|
||||||
|
- Log full error to file
|
||||||
|
- Provide actionable guidance
|
||||||
|
- Offer retry or cancel options
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
```
|
||||||
|
ERROR: Client 'laptop' already exists
|
||||||
|
Action: Choose a different name or remove existing client first
|
||||||
|
|
||||||
|
ERROR: No available IPv4 addresses
|
||||||
|
Action: Remove unused clients or expand VPN range
|
||||||
|
```
|
||||||
|
|
||||||
|
## Performance Considerations
|
||||||
|
|
||||||
|
1. **Lazy Loading**
|
||||||
|
- Load clients on screen init
|
||||||
|
- Cache client data between refreshes
|
||||||
|
|
||||||
|
2. **Asynchronous Operations**
|
||||||
|
- Run WireGuard status checks in background
|
||||||
|
- Use tea.Cmd for async operations
|
||||||
|
|
||||||
|
3. **Throttled Refresh**
|
||||||
|
- Auto-refresh every 30 seconds (configurable)
|
||||||
|
- Manual refresh with 'r' key
|
||||||
|
|
||||||
|
4. **QR Code Optimization**
|
||||||
|
- Generate on demand, not cached
|
||||||
|
- Use appropriate error correction level
|
||||||
|
|
||||||
|
## Security Considerations
|
||||||
|
|
||||||
|
1. **Root Privileges**
|
||||||
|
- Check for root at startup
|
||||||
|
- Display clear error if not root
|
||||||
|
|
||||||
|
2. **Key Storage**
|
||||||
|
- Write keys with 0600 permissions
|
||||||
|
- Clean up temporary key files
|
||||||
|
|
||||||
|
3. **Atomic Operations**
|
||||||
|
- Write to temp file, then move
|
||||||
|
- Prevent config corruption
|
||||||
|
|
||||||
|
4. **Input Validation**
|
||||||
|
- Strict regex for client names
|
||||||
|
- IP availability checks
|
||||||
|
- DNS format validation
|
||||||
|
|
||||||
|
## Testing Strategy
|
||||||
|
|
||||||
|
### Unit Tests
|
||||||
|
- Validation functions
|
||||||
|
- Configuration parsing
|
||||||
|
- Client model methods
|
||||||
|
|
||||||
|
### Integration Tests
|
||||||
|
- WireGuard config generation
|
||||||
|
- Key generation
|
||||||
|
- Backup/restore
|
||||||
|
|
||||||
|
### Manual Testing
|
||||||
|
- End-to-end workflows
|
||||||
|
- Terminal size handling
|
||||||
|
- Error scenarios
|
||||||
|
|
||||||
|
## Milestones
|
||||||
|
|
||||||
|
| Milestone | Days | Goal |
|
||||||
|
|-----------|------|------|
|
||||||
|
| M1: Foundation | 2 | Project setup, basic TUI |
|
||||||
|
| M2: List View | 4 | Client list with status |
|
||||||
|
| M3: Add Client | 6 | Working add form |
|
||||||
|
| M4: Detail & Delete | 8 | Full client management |
|
||||||
|
| M5: QR Codes | 10 | QR code display |
|
||||||
|
| M6: Polish | 12 | UX improvements |
|
||||||
|
| M7: Complete | 14 | Fully functional TUI |
|
||||||
|
|
||||||
|
## Success Criteria
|
||||||
|
|
||||||
|
- ✅ All bash functionality replicated in TUI
|
||||||
|
- ✅ Responsive and performant UI
|
||||||
|
- ✅ Clear error messages with actionable guidance
|
||||||
|
- ✅ Keyboard shortcuts for all actions
|
||||||
|
- ✅ Real-time client status updates
|
||||||
|
- ✅ Working QR code generation
|
||||||
|
- ✅ Backup/restore functionality
|
||||||
|
- ✅ Polished, intuitive user experience
|
||||||
|
|
||||||
|
## Future Enhancements
|
||||||
|
|
||||||
|
- Config import/export
|
||||||
|
- Client statistics dashboard
|
||||||
|
- Connection monitoring view
|
||||||
|
- Multiple server support
|
||||||
|
- Template-based client creation
|
||||||
|
- Bulk operations
|
||||||
|
- Dark/Light theme toggle
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Estimated Timeline**: 14 days for MVP
|
||||||
|
**Primary Dependencies**: bubbletea, lipgloss, huh, bubble-table, qrterminal
|
||||||
|
**Minimum Go Version**: 1.21+
|
||||||
|
**Target Terminal**: ANSI-compatible terminals (Linux, macOS, Windows with WSL)
|
||||||
Reference in New Issue
Block a user