- Fix xterm.js container not found: use requestAnimationFrame retry loop
instead of single $nextTick (Alpine x-for renders asynchronously)
- Better mock fallback: use host name+IP instead of raw UUID
- Add logging for WebSocket connection path (found/not-found/hostname)
- Add UpdateHost handler + PUT /hosts/:id route
- CreateHost now accepts all fields (port, username, auth, notes)
- host_modal.html: full form with port, username, auth type toggle, edit mode
- host_list.html: edit button dispatches edit-host event with host data
- Connect button links to /terminal?host={id} for pre-selection
- Terminal page reads selected host from query param
- Toast notification system via Alpine.js events
- Add default template function for fallback values
- 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