Files
HostKeeper/docs/v2/PROGRESS.md
2026-07-07 11:53:16 +07:00

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 dev opens 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/hosts returns 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.Client using pkg/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:

  1. Read this file (docs/v2/PROGRESS.md) — find the first [ ] item
  2. Read the relevant spec doc — for the current task:
    • REST API endpoints -> docs/v2/API.md
    • UI components -> docs/v2/UI_COMPONENTS.md
    • Data models -> docs/v2/DATA_MODELS.md
    • Visual reference -> docs/v2/UI_TERMIUS_REFERENCE.md
    • Performance notes -> docs/v2/PERFORMANCE.md
    • Build pipeline -> docs/v2/BUILD_SYSTEM.md
  3. Read docs/v2/ARCHITECTURE.md — understand the system
  4. Implement in app/backend/ (Go) or app/frontend/ (React)
  5. Test — run go test ./app/backend/... and npm test in app/frontend/
  6. Update this file — mark [x] the completed task, update "Last Session Notes"

For a returning AI agent:

  1. Read this file — check "Last Session Notes" for context
  2. Check git loggit log --oneline -10 for recent commits
  3. Find the first [ ] — that's where you continue
  4. Update this file when done

7. Reference Documents Index

Document When to read
docs/v2/PROGRESS.md Always (first) — know where to continue
docs/v2/ARCHITECTURE.md Understanding the system
docs/v2/API.md Implementing REST endpoints or WebSocket handlers
docs/v2/DATA_MODELS.md Creating/modifying Go structs or JSON schemas
docs/v2/UI_COMPONENTS.md Building React components
docs/v2/UI_TERMIUS_REFERENCE.md Designing UI layout, colors, typography
docs/v2/SPRINT_PLAN.md Detailed file-by-file task instructions
docs/v2/BUILD_SYSTEM.md Setting up build pipeline
docs/v2/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.