A minimal, keyboard-friendly homepage dashboard with web and CLI frontends.
(the web dashboard — regenerate with make demo-web)
(the CLI TUI — regenerate with make demo)
- Clean, dark-themed UI with light mode option
- Dynamic group filtering (External/Local/All or custom groups)
- Categorized View: Services are grouped with headers in "All" mode
- Intelligent Search: Type-to-jump with auto-scroll to selection
- Drag-and-Drop: Reorder services (persists in browser)
- Mobile Friendly: Long-press (500ms) with haptic feedback to copy URL
- Customizable: Extensive settings panel for theme, clock, and layout
- CLI TUI: Terminal-based interface with health checks, search, and color themes
# Edit services
vim services.yml
# Build everything (web + CLI)
make build
# Build only web
make build-html
# Build only CLI
make build-cmd
# Open web dashboard in browser
make run-web
# Launch CLI TUI
make run-cli
# Run CLI tests
make test
# CLI with custom config
./output/tui path/to/services.yml
# Generate example and open in browser
python3 web/build.py --openEdit services.yml:
title: My Homepage # Browser tab title
header: Dashboard # Header display (optional, defaults to title)
# Define groups
groups:
- id: external
name: External
- id: local
name: Local
# List your services
services:
- name: ServiceName
url: https://service.example.com
icon: 🛠
groups: [external]
- name: LocalService
url: http://localhost:8080
icon: 🏠
groups: [local]- url (required): Service URL
- icon: Emoji or text icon
- groups: List of group IDs. Services without valid groups fall into "No Group"
Optionally set a top-level icon: (emoji) to customize the favicon; defaults to the first service's icon.
Groups are defined in the groups section with:
- id: Unique identifier (used in service
groupsarray) - name: Display name (shown in group selector)
An implicit "All" group is automatically added, showing all services categorized by their primary group.
Click the ⚙ button or press , to access:
- Theme: Toggle light/dark mode
- Group: Cycle through groups
- Clock: Switch between 12h/24h format
- Date: Show/hide date display
- Search: Show/hide search bar
- Icons: Show/hide service icons
- Compact: Smaller cards for more services
- Clear custom order: Reset service order to default
- Reset all settings: Clear all saved preferences
- Type: Filter services and jump to first result (auto-scrolls to view)
- Arrow Keys: Navigate filtered results (or settings when open)
- Enter: Open selected service in browser (search + Enter opens first match)
- Esc: Clear search / Close settings / Close hints
- /: Search / filter
- ,: Toggle settings panel
- H: Re-check service health
- ?: Show keyboard shortcuts overlay
- Drag: Reorder services (persists in browser)
Both frontends treat a service as offline on real 4xx/5xx responses, except 401/403/405 (auth-gated pages stay green so behind-login services don't look broken); only network failures (DNS, refused, timeout) and unhandled status codes are "offline".
The web first checks with a normal CORS request so it can read status codes; if the
server doesn't send CORS headers the browser can't read the response, so it falls back
to mode: 'no-cors' where any opaque response counts as online. Press H (web)
or h (CLI) to re-check.
- Tap: Navigate to service
- Long Press (500ms): Copy URL to clipboard (includes haptic feedback)
- Drag: Reorder services
make build
# Upload output/index.html to your web server.
├── web/
│ ├── build.py # Build script (requires PyYAML)
│ └── src/
│ ├── template.html # HTML template
│ ├── style.css # Styles
│ ├── script.js # JavaScript
│ └── health.js # Health check module
├── cli/
│ ├── tui/
│ │ ├── main.go # Go TUI: model, update, view (bubbletea/lipgloss)
│ │ ├── types.go # TUI structs
│ │ ├── themes.go # Color themes and border sets
│ │ ├── utils.go # Config, install, health-check helpers
│ │ └── utils_test.go # Unit tests (make test)
│ ├── go.mod
│ └── go.sum
├── services.yml # Service definitions
├── services.example.yml # Example config
├── demo/
│ ├── demo.tape # VHS script for the TUI demo gif
│ └── demo.gif # Generated demo (make demo)
├── Makefile # Build orchestration
├── output/ # Generated files (gitignored)
│ ├── index.html
│ ├── example.html
│ └── tui
├── AGENTS.md
└── README.md
