c215d68c81
- git mv docs/v2/*.md docs/ (11 planning documents) - Remove empty docs/v2/ directory - Update all references: AGENTS.md, CHANGELOG.md, README.md, ARCHITECTURE.md - Fix outdated repo tree in ARCHITECTURE.md to match actual structure
15 KiB
15 KiB
Hostkeeper V2 — Progress Tracker
Purpose: Enable seamless continuation of development by any agent/LLM across sessions. How to use: Read this file first. Find the first unchecked
[ ]item. That's where you continue. Last Updated: 2026-06-29 Status: Planning complete, implementation not started.
1. Overview
Hostkeeper V2 is a Termius-like cross-platform SSH/SFTP management GUI application.
| Item | Value |
|---|---|
| Goal | Build a free, open-source Termius alternative with full feature parity |
| Desktop | GoFiber backend + React/xterm.js UI + Electron wrapper |
| Mobile | Go mobile library + WebView wrapper (Android/iOS) |
| Backend language | Go 1.26 |
| HTTP framework | GoFiber v2 (fasthttp-based) |
| Frontend | React 19, TypeScript, xterm.js, Zustand, Vite |
| Desktop wrapper | Electron (electron-builder) |
| Mobile wrapper | gomobile + WebView |
| V1 (existing) | CLI/TUI SSH/SFTP manager — 105 tests, all passing. Frozen. |
2. Current Status Summary
| Item | Status |
|---|---|
| Planning documents | DONE |
| Sprint 0 — Scaffolding | NOT STARTED |
| Sprint 1 — Foundation | NOT STARTED |
| Sprint 2 — Core Features | NOT STARTED |
| Sprint 3 — SFTP + Polish | NOT STARTED |
| Sprint 4 — Advanced | NOT STARTED |
| Sprint 5 — Platform Polish | NOT STARTED |
3. Sprint Checklist
Sprint 0 — Project Scaffolding (Day 0)
- Create
app/backend/directory with Go module (go mod init) - Install GoFiber v2 + dependencies in
go.mod - Create
app/backend/main.go— minimal fiber server (port 0 for random) - Create
app/frontend/with Vite + React + TypeScript - Create
app/electron/with Electron shell - Electron spawns Go backend as child process on startup
- Electron loads web UI from localhost (Go serve frontend dist)
- Create
app/backend/middleware/— CORS, logging, recover, compress - Create
app/backend/bridge/directory (placeholder handlers) - Create
app/backend/ws/directory (placeholder handlers) - Build script:
scripts/build.sh— Go build → frontend build → Electron package - Verify:
npm run devopens Electron window with "Hostkeeper V2" title - Verify: Go server responds at
localhost:PORT/api/health
Sprint 1 — Foundation (Day 1-5)
Day 1-2: Data API Layer
app/backend/bridge/hosts.go— GET /api/hosts (list, filter, search)app/backend/bridge/hosts.go— POST /api/hosts (create)app/backend/bridge/hosts.go— GET /api/hosts/:id (detail)app/backend/bridge/hosts.go— PUT /api/hosts/:id (update)app/backend/bridge/hosts.go— DELETE /api/hosts/:id (delete)app/backend/bridge/hosts.go— PATCH /api/hosts/:id/favorite (toggle)app/backend/bridge/keys.go— GET /api/keys (list, no private key)app/backend/bridge/keys.go— POST /api/keys (import)app/backend/bridge/keys.go— POST /api/keys/generate (generate new)app/backend/bridge/keys.go— DELETE /api/keys/:id (delete)app/backend/bridge/snippets.go— GET /api/snippets (list)app/backend/bridge/snippets.go— POST /api/snippets (create)app/backend/bridge/snippets.go— PUT /api/snippets/:id (update)app/backend/bridge/snippets.go— DELETE /api/snippets/:id (delete)- JSON error responses:
{ "error": "message" }with proper HTTP codes - Verify:
curl -X POST http://localhost:PORT/api/hostsreturns 201
Day 3: Groups + Config API
app/backend/bridge/groups.go— GET /api/groups (tree structure)app/backend/bridge/groups.go— POST /api/groups (create)app/backend/bridge/groups.go— PUT /api/groups/:id (update)app/backend/bridge/groups.go— DELETE /api/groups/:id (delete)app/backend/bridge/groups.go— PUT /api/groups/:id/move (reparent)app/backend/bridge/config.go— GET /api/config (app config)app/backend/bridge/config.go— PUT /api/config (update config)app/backend/bridge/config.go— POST /api/config/unlock (vault unlock)app/backend/bridge/config.go— POST /api/config/lock (vault lock)app/backend/bridge/config.go— GET /api/config/status (vault status)- Verify: Full CRUD cycle via curl for all endpoints
Day 4: Web UI Scaffold
- React Router setup — routes for all screens (placeholder)
- Layout component — Sidebar + TabBar + MainContent + StatusBar
- Sidebar component — GroupTree (recursive), SearchBar, QuickActions
- Theme system — CSS variables (dark, light, high-contrast)
- API client layer — fetch wrapper + error handling + retry logic
- State management — Zustand stores (hosts, keys, snippets, ui, terminal)
- Keyboard shortcuts — Cmd+N new host, Cmd+K search, Cmd+D dark mode
- Verify: Navigation between screens works
Day 5: Host List Screen
- HostList screen — HostCard components (grid + list view toggle)
- GroupTree — collapsible, recursive, drag-and-drop (host -> group)
- Search — filter by name, hostname, tag
- Tag filter bar — chips for each tag, click to filter
- Favorite toggle — star icon, filter favorites only
- Context menu — right-click: connect, edit, delete, duplicate
- Empty state — illustration + "Add your first host" CTA
- Loading skeleton states
- Verify: Host appears in list, can search, can filter, can favorite
Sprint 2 — Core Features (Day 6-10)
Day 6-7: Host Form + CRUD UI
- HostForm screen — add mode + edit mode
- Basic info fields — name, hostname, port, username
- Auth section — type selector (password/key/agent)
- Password field — show/hide toggle, strength indicator
- Key picker — dropdown from stored keys
- TagsInput — type + Enter to add, backspace to remove, autocomplete
- GroupPicker — tree picker component
- Advanced settings — proxy, jump host, keepalive interval
- Validation — required fields, hostname regex, port range 1-65535
- Error display — inline validation + toast notifications
- Keyboard shortcuts — Cmd+S save, Esc cancel, Tab next field
- Verify: Create host -> appears in list -> edit -> update -> delete
Day 8-10: SSH Terminal (MOST CRITICAL)
- Go: WebSocket handler
app/backend/ws/terminal.go- Accept WS connection with host_id + cols + rows query params
- Lookup host from storage by ID
- Create
ssh.Clientusingpkg/ssh(reuse existing) - Request PTY with xterm-256color
- Stream SSH stdout -> WS binary frames (
c.WriteMessage) - Receive WS frames -> SSH stdin (
session.Stdin.Write) - Handle resize messages — JSON control frames
- Handle disconnect gracefully
- Buffer management (channel-based backpressure)
- Configurable idle timeout (default 300s)
- Connection pool (reuse SSH connections for same host)
- React: XTermWrapper component
- xterm.js instance initialization with addons (fit, web-links, search)
- WebSocket connection management
- Keyboard input -> WS send (binary frames)
- ResizeObserver -> WS send resize message
- Fit addon — auto fit to container
- Web links addon — clickable URLs
- Search addon — Ctrl+F search in terminal
- Copy/paste — Cmd+C/V, right-click menu
- Connection status indicator (connecting, connected, disconnected, error)
- Reconnect button on disconnect
- React: TabBar + Tab management
- Add tab -> connect to host
- Close tab -> disconnect SSH session
- Reorder tabs via drag
- Tab status dot (green=connected, red=error, gray=disconnected)
- Tab title = host name
- Max 20 tabs limit with warning
- Snippet panel (slide-in from right)
- List snippets for current host
- Click snippet -> inject command to terminal
- Edit/delete from panel
- Verify: Connect to host -> terminal works -> type commands -> disconnect -> reconnect
Sprint 3 — SFTP + Polish (Day 11-15)
Day 11-12: SFTP Browser
- Go: SFTP REST handlers
app/backend/bridge/sftp.go- GET /api/sftp/ls — list directory (host_id, path)
- POST /api/sftp/upload — multipart upload with progress
- GET /api/sftp/download — file download stream
- POST /api/sftp/mkdir — create directory
- POST /api/sftp/rm — delete file/directory
- POST /api/sftp/rename — rename/move
- POST /api/sftp/chmod — change permissions
- React: SFTPScreen
- LocalPane + RemotePane (dual pane split view)
- File list table — name, size, date, permissions (sortable)
- Navigation — cd, back, forward, path breadcrumb
- Upload/download with progress bars
- Transfer queue — multiple files, cancel, retry
- Drag & drop from desktop to upload
- Context menu — download, delete, rename, chmod, mkdir
- Keyboard shortcuts — Delete, F2 rename, Ctrl+C/V copy/move
- Verify: Browse remote files -> upload -> download -> delete -> rename
Day 13: Security + Vault
- Vault unlock screen — password prompt on app start
- Lock/unlock flow — auto-lock after inactivity (configurable: 1/5/15/30 min)
- Password change screen
- Known hosts dialog — first connect show fingerprint -> accept/reject
- Key passphrase prompt — when using encrypted private key
- Verify: Start app -> vault locked -> enter password -> unlock -> auto-lock
Day 14: Settings Screen
- Appearance tab — theme switcher, font selection, font size, background opacity
- Terminal tab — scrollback (100-10000), cursor style, cursor blink, bell, copy-on-select
- Connection tab — default timeout, keepalive interval, auto-reconnect
- Vault tab — change password, auto-lock timer, lock on sleep
- General tab — data directory, export/import buttons, about/version
- Verify: Change settings -> restart -> settings persist
Day 15: Mobile Setup
- React Native project with WebView
- Go mobile compilation script (gomobile bind)
- Android minimal app — WebView + gomobile .aar
- iOS minimal app — WKWebView + gomobile .xcframework
- Responsive CSS for mobile (touch-friendly targets)
- Verify: App runs on Android emulator
Sprint 4 — Advanced Features (Day 16-20)
Day 16-17: Port Forwarding
- Model PortForward in Go + storage
- Go: Local forwarding — ssh.Listen -> local listener -> tunnel
- Go: Remote forwarding — ssh.Request remote forward
- Go: Dynamic forwarding — SOCKS5 proxy via SSH
- Status tracking — running/stopped/error
- React: PortForwardScreen — list, add form, start/stop toggles
- Verify: Set local forward ->
curl localhost:PORT-> hits remote
Day 18: Import/Export
- Go: Import from
~/.ssh/config— parse host, hostname, port, user, identity - Go: Import from CSV — columns: name, hostname, port, username, group, tags
- Go: Export all data — encrypted JSON with all entities
- React: Import/Export UI — drag & drop, progress, preview, confirm
- Verify: Export -> delete all -> import -> all data restored
Day 19-20: Jump Hosts + Proxy
- Go: Jump host chain — SSH via intermediate hosts
- Go: Multi-hop support — host -> jump1 -> jump2 -> target
- Go: SOCKS5 proxy before SSH
- Go: HTTP CONNECT proxy
- React: Advanced connection settings — jump host selector, proxy config
- Verify: Connect via jump host -> terminal works
Sprint 5 — Platform Polish (Day 21-25)
Day 21-22: Desktop Enhancements
- Electron native menu bar — File, Edit, View, Window, Help
- System tray icon — quick actions, recent hosts
- Global keyboard shortcuts — Cmd+` toggle, Cmd+N new host
- Window state persistence — position, size, maximized
- Auto-update via electron-updater
- OS Keychain integration — macOS Keychain, Windows Credential Manager, Linux Secret Service
- Verify: Install .dmg -> app appears -> open -> works
Day 23: Performance Optimization
- Go: Connection pooling for SSH sessions
- Go: Memory optimization — buffer pools, goroutine limits
- WebSocket: permessage-deflate compression
- React: Virtual scrolling for host list (1000+ hosts)
- React: Lazy loading screens (code splitting)
- React: Memoization (React.memo, useMemo, useCallback)
- xterm.js: WebGL renderer (preferred) with Canvas fallback
- Verify: 1000 hosts in list -> smooth scrolling -> no lag
Day 24-25: Mobile Polish
- Android: gomobile bind -> .aar
- Android: WebView app with touch-optimized UI
- iOS: gomobile bind -> .xcframework
- iOS: WKWebView app
- Mobile: Custom keyboard toolbar (Tab, Ctrl, Esc, arrows)
- Mobile: Gesture navigation (swipe to switch tabs)
- Mobile: Landscape/portrait handling
- Mobile: Bluetooth keyboard support
- Mobile: Background connection handling
- Verify: Install APK on Android -> connect SSH -> terminal works
4. Known Issues
| # | Issue | Severity | Status |
|---|---|---|---|
| (none) | — | — | — |
5. Last Session Notes
| Date | What was done | Commits |
|---|---|---|
| 2026-06-29 | V2 planning documents created (9 files) | — |
6. How to Continue
For a new AI agent:
- Read this file (
docs/PROGRESS.md) — find the first[ ]item - Read the relevant spec doc — for the current task:
- REST API endpoints ->
docs/API.md - UI components ->
docs/UI_COMPONENTS.md - Data models ->
docs/DATA_MODELS.md - Visual reference ->
docs/UI_TERMIUS_REFERENCE.md - Performance notes ->
docs/PERFORMANCE.md - Build pipeline ->
docs/BUILD_SYSTEM.md
- REST API endpoints ->
- Read
docs/ARCHITECTURE.md— understand the system - Implement in
app/backend/(Go) orapp/frontend/(React) - Test — run
go test ./app/backend/...andnpm testinapp/frontend/ - Update this file — mark
[x]the completed task, update "Last Session Notes"
For a returning AI agent:
- Read this file — check "Last Session Notes" for context
- Check git log —
git log --oneline -10for recent commits - Find the first
[ ]— that's where you continue - Update this file when done
7. Reference Documents Index
| Document | When to read |
|---|---|
docs/PROGRESS.md |
Always (first) — know where to continue |
docs/ARCHITECTURE.md |
Understanding the system |
docs/API.md |
Implementing REST endpoints or WebSocket handlers |
docs/DATA_MODELS.md |
Creating/modifying Go structs or JSON schemas |
docs/UI_COMPONENTS.md |
Building React components |
docs/UI_TERMIUS_REFERENCE.md |
Designing UI layout, colors, typography |
docs/SPRINT_PLAN.md |
Detailed file-by-file task instructions |
docs/BUILD_SYSTEM.md |
Setting up build pipeline |
docs/PERFORMANCE.md |
Tuning for speed and stability |
8. Git History Reference
| Commit | Description |
|---|---|
| (V2 commits will be listed here) | — |
IMPORTANT: This file MUST be updated after every development session to ensure continuity.