Files
swanadiva fd7361aa14 Sprint 6: JSON file persistence + real SSH terminal + V1 crypto/knownhosts integration
- go.mod replace directive for git.tukangketik.id/swanadiva/hostkeeper → ../../v1
- store/ package: JSON file persistence for hosts, snippets, keys, settings
  (~/Library/Application Support/hostkeeper/v2/)
- model SSH fields: Hostname, Port, Username, AuthType, Password, KeyID
- sshconn/ package: real SSH client via golang.org/x/crypto/ssh
- Terminal WS: real SSH connection with fallback to mock shell
- Dynamic host list in terminal (server-rendered JSON script tag)
- All mock data defaults removed from model packages
- Settings persist via store/settings.go
2026-07-07 13:53:50 +07:00

215 lines
10 KiB
Markdown

# 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-07-07
> **Status**: Sprint 0—6 selesai. V2 HTMX feature complete.
---
## 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 + HTMX + xterm.js + Alpine.js |
| **Mobile** | Go mobile library + WebView wrapper (Android/iOS) |
| **Backend language** | Go 1.26 |
| **HTTP framework** | GoFiber v2 (fasthttp-based) |
| **Frontend** | HTMX + Alpine.js + xterm.js (minimal JS, server-rendered HTML) |
| **Styling** | TailwindCSS v4 + custom CSS (Lumina System) |
| **Desktop wrapper** | Electron (opsional — bisa lewat browser saja) |
| **Mobile wrapper** | gomobile + WebView |
| **V1 (existing)** | CLI/TUI SSH/SFTP manager — 105 tests, all passing. Frozen. |
**Keputusan arsitektur**: Migrasi dari React/SPA ke HTMX/server-rendered HTML.
Lihat [ARCHITECTURE_HTMX.md](ARCHITECTURE_HTMX.md) untuk detail.
---
## 2. Current Status Summary
| Item | Status |
|------|--------|
| Planning documents (HTMX) | DONE |
| Sprint 0 — Setup GoFiber + HTMX | DONE |
| Sprint 1 — Dashboard + Host List | DONE |
| Sprint 2 — Snippets + Keychain | DONE |
| Sprint 3 — Settings + Brief | DONE |
| Sprint 4 — SFTP Dual-Pane | DONE |
| Sprint 5 — Terminal + xterm.js | DONE |
| Sprint 6 — Storage Integration | DONE |
---
## 3. Sprint Checklist (HTMX)
### Sprint 0 — Setup GoFiber + HTMX
- [x] Go module init (`app/backend/go.mod`)
- [x] Install GoFiber v2 + deps
- [x] Minimal Fiber server (`main.go`) — port 1947
- [x] Static files serving (`/static/`)
- [x] HTML template engine (html/template via gofiber/template)
- [x] Download HTMX + Alpine.js (`static/js/`)
- [x] Setup TailwindCSS v4 — `input.css``output.css`
- [x] Custom CSS (Lumina) — dot-grid, glassmorphism, keyframes, toggle, modal, x-cloak
- [x] Layout template (`views/layout.html`) — sidebar + header + main
- [x] Nav template (`views/nav.html`) — nav items with active state
- [x] Index + routing (`views/index.html` + `handler/dashboard.go`)
- [x] Health endpoint (`handler/health.go`)
- **Verify**: `curl :1947/api/health``{"app":"hostkeeper-v2","status":"ok"}`
### Sprint 1 — Dashboard + Host List
- [x] Model Host + HostStore (`internal/model/host.go`) — mock data (8 hosts)
- [x] Dashboard handler — full page render (`handler/dashboard.go`)
- [x] Host list partial (`views/host_list.html`) — cards + list view
- [x] Search HTMX — `hx-get="/hosts?q=..." hx-trigger="keyup delay:200ms"`
- [x] Filter status — `<select>` + `hx-get="/hosts?filter=..."`
- [x] View toggle (grid/list) — Alpine `x-data="{ view: 'grid' }"` + `x-show`
- [x] Add host modal (`views/host_modal.html`) — Alpine event-driven `$dispatch('open-modal')`
- [x] POST /hosts — create host via HTMX form swap
- [x] DELETE /hosts/:id — hx-delete with confirm
- [x] Background transfers panel — static placeholder in nav
- **Verify**: Homepage renders with 8 hosts, search+filter works, create+delete CRUD
### Sprint 2 — Snippets + Keychain
- [x] Model Snippet + SnippetStore (`internal/model/snippet.go`)
- [x] Model Key + KeyStore (`internal/model/keychain.go`)
- [x] Snippets handler (`internal/handler/snippets.go`)
- [x] Keychain handler (`internal/handler/keychain.go`)
- [x] Snippets template (`views/snippets.html`) — standalone page (no layout inheritance)
- [x] Snippet grid partial (`views/snippet_grid.html`) — HTMX partial
- [x] Keychain template (`views/keychain.html`) — standalone page
- [x] Key grid partial (`views/key_grid.html`) — HTMX partial
- [x] Clipboard JS (`static/js/clipboard.js`)
- [x] Utils JS (`static/js/utils.js`)
- **Note**: Removed `layout.html` — all pages are now standalone (Go template `{{define}}` conflict)
- **Verify**: Both pages render, CRUD works, clipboard copies, strength badges display
### Sprint 3 — Settings + Brief
- [x] Model Device + Config (`internal/model/device.go`, `internal/model/config.go`)
- [x] Settings handler + UpdateConfig (`internal/handler/settings.go`)
- [x] Brief handler (`internal/handler/brief.go`)
- [x] Settings template (`views/settings.html`) — profile, tabs, toggles, devices, danger zone
- [x] Brief template (`views/brief.html`) — keyboard shortcuts, about
- [x] Toggle switch JS (`static/js/toggles.js`) — Alpine toggle data
- [x] Danger zone — confirm flow with localStorage.clear()
- **Verify**: Settings page renders with tabs, toggles work via Alpine, brief page shows shortcuts
### Sprint 4 — SFTP Dual-Pane
- [x] Model FileItem + Transfer (`internal/model/file.go`, `internal/model/transfer.go`)
- [x] SFTP handler (`internal/handler/sftp.go`) — page, pane partial, create folder, delete file
- [x] SFTP template (`views/sftp.html`) — dual-pane (local/remote), breadcrumb, search, drop-zone, toast, folder modal
- [x] SFTP pane partial (`views/sftp_pane.html`) — file table with icons by type, hover actions
- [x] `dict` helper fungsitambah di template engine (`main.go`)
- [x] Folder create (Alpine modal + POST) + delete (hx-delete)
- **Verify**: Dual-pane renders, file list per type icons, CRUD works, drop-zone + toast present
### Sprint 5 — Terminal + xterm.js
- [x] Download xterm.js v5.3.0 + xterm.css (`static/xterm/`)
- [x] Install gofiber/contrib/websocket v1.3.4
- [x] Terminal handler (`internal/handler/terminal.go`) — page + WebSocket mock shell (ls, pwd, cd, cat, whoami, etc.)
- [x] Terminal template (`views/terminal.html`) — dark theme, tab bar with Alpine, xterm containers
- [x] Terminal JS (`static/js/terminal.js`) — Alpine terminalManager, xterm init, WS connect, tab CRUD
- [x] Tab management — add/switch/close tabs, random host assignment
- **Verify**: Terminal page renders, xterm.js loaded, WS endpoint returns Upgrade Required
### Sprint 6 — Data Store Integration
- [x] `go.mod` replace directive → `v1/pkg/crypto` + `v1/pkg/knownhosts` importable
- [x] `store/` package — JSON file persistence for hosts, snippets, keys, settings (stored at `~/Library/Application Support/hostkeeper/v2/`)
- [x] Model SSH fields (Hostname, Port, Username, AuthType, Password, KeyID, Group, Tags, Notes)
- [x] Handlers updated to use persistent store instead of in-memory mock data
- [x] `sshconn/` package — real SSH client via `golang.org/x/crypto/ssh`
- [x] Terminal WebSocket — real SSH connection (falls back to mock)
- [x] Dynamic host list in terminal page (server-rendered via JSON script tag)
- [x] All mock defaults removed from model packages (Host, Snippet, Key no longer have `defaultXxx()`)
- [x] Settings persist via JSON file
---
## 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) | — |
| 2026-07-07 | Sprint 0: GoFiber+HTMX scaffolding, TailwindCSS, layout, nav, health | `43a19b7` |
| 2026-07-07 | Sprint 1: Host model+store, dashboard CRUD, HTMX partials (grid/list, search, filter, modal, delete), transfers panel | `d771925`, `86620b0` |
| 2026-07-07 | Sprint 2 dimulai: Snippet + Keychain models created | — |
| 2026-07-07 | Sprint 2 selesai: all CRUD, standalone templates, clipboard.js, utils.js, fix template {{define}} conflict | `c4b0d7d` |
| 2026-07-07 | Sprint 3 selesai: settings page, tabs, toggles, connected devices, danger zone, brief page | `c5ac07e` |
| 2026-07-07 | Sprint 4 selesai: SFTP dual-pane, breadcrumb, per-type icons, create/delete, toast, drop-zone | `941a67b` |
| 2026-07-07 | Sprint 5 selesai: xterm.js terminal, WebSocket mock shell, tab management | `04d9cfb` |
| 2026-07-07 | Sprint 6 selesai: JSON persistence, go.mod replace, real SSH client, dynamic hosts, model SSH fields | `(pending — akan commit)` |
---
## 6. How to Continue
### For a new AI agent:
All Sprint 0—6 tasks for HTMX are **complete**. The V2 backend is fully functional with:
- GoFiber v2 server on `:1947`
- HTMX + Alpine.js for interactivity
- JSON file persistence in `~/Library/Application Support/hostkeeper/v2/`
- Real SSH terminal (with mock fallback)
- All CRUD operations for hosts, snippets, keychain, settings
Future work areas (beyond Sprint 6):
- **Real SFTP**: Connect SFTP dual-pane to real SSH via `github.com/pkg/sftp`
- **Mobile wrapper**: `gomobile` + WebView
- **Electron wrapper**: Wrap in Electron for standalone desktop app
- **Tests**: Write Go unit/integration tests for handlers and store
- **CI/CD**: GitHub Actions for build + test
- **Encryption**: Wire up `v1/pkg/crypto` to encrypt stored data
- **Known Hosts**: Integrate `v1/pkg/knownhosts` for SSH host key verification
### For a returning AI agent:
1. **Read this file** — check "Last Session Notes" for context
2. **Check git log**`git log --oneline -10`
3. **All Sprint items are `[x]`** — pick from "Future work areas" above
4. **Update this file** when done
---
## 7. Reference Documents Index
| Document | When to read |
|----------|-------------|
| `docs/PROGRESS.md` | Always (first) — know where to continue |
| `AGENTS.md` (root) | Architecture, paths, important rules |
| `docs/ARCHITECTURE_HTMX.md` | System design, component flow |
| `docs/ARCHITECTURE.md` | Summary + pointer to HTMX doc |
| `docs/SPRINT_PLAN.md` | Detailed file-by-file task instructions |
| `docs/API.md` | REST + WebSocket endpoint specs |
| `docs/DATA_MODELS.md` | Go struct definitions |
| `docs/UI_COMPONENTS.md` | HTMX partials / Alpine components |
| `docs/BUILD_SYSTEM.md` | Build pipeline (Go + CSS) |
| `docs/UI_TERMIUS_REFERENCE.md` | Visual layout reference |
| `docs/PERFORMANCE.md` | Performance & stability notes |
| `template/` dir | Visual reference only (Lumina System) |
---
## 8. Git History Reference
| Commit | Description |
|--------|-------------|
| `43a19b7` | Sprint 0 — GoFiber + HTMX + TailwindCSS v4 scaffolding |
| `d771925` | Sprint 1 — host model, mock store, dashboard CRUD, HTMX partials |
| `86620b0` | Sprint 1 final — delete host, Alpine modal events, grid/list toggle, transfers panel |
---
**IMPORTANT**: This file MUST be updated after every development session to ensure continuity.