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
This commit is contained in:
swanadiva
2026-07-07 13:53:50 +07:00
parent 04d9cfb096
commit fd7361aa14
21 changed files with 746 additions and 306 deletions
+32
View File
@@ -0,0 +1,32 @@
package store
import "git.tukangketik.id/swanadiva/hostkeeper/v2/internal/model"
type DeviceStore struct {
devices []model.Device
}
func NewDeviceStore() *DeviceStore {
s := &DeviceStore{devices: defaultDevices()}
mu.RLock()
readFile("devices.json", &s.devices)
mu.RUnlock()
if s.devices == nil {
s.devices = defaultDevices()
}
return s
}
func (s *DeviceStore) All() []model.Device {
mu.RLock()
defer mu.RUnlock()
return s.devices
}
func defaultDevices() []model.Device {
return []model.Device{
{ID: "d1", Name: "MacBook Pro M4", Type: "desktop", OS: "macOS 15 Sequoia", LastSeen: "Just now", Current: true},
{ID: "d2", Name: "iPhone 17 Pro", Type: "mobile", OS: "iOS 20", LastSeen: "2 hours ago", Current: false},
{ID: "d3", Name: "iPad Air M3", Type: "tablet", OS: "iPadOS 20", LastSeen: "Yesterday", Current: false},
}
}