diff --git a/cmd/hostkeeper/add.go b/cmd/hostkeeper/add.go index d1958d5..7c40526 100644 --- a/cmd/hostkeeper/add.go +++ b/cmd/hostkeeper/add.go @@ -1,6 +1,7 @@ package main import ( + "bufio" "context" "fmt" "os" @@ -174,52 +175,47 @@ func runAddHost(cmd *cobra.Command, args []string) error { } func addHostInteractive(cfg *config.Config) error { - reader := strings.NewReader("") + input := bufio.NewReader(os.Stdin) fmt.Println("╔══════════════════════════════════════╗") fmt.Println("║ Add New SSH Host ║") fmt.Println("╚══════════════════════════════════════╝") fmt.Println() + readLine := func(prompt string) string { + fmt.Print(prompt) + line, _ := input.ReadString('\n') + return strings.TrimRight(line, "\n\r") + } + // Get host name - fmt.Print("Host Name (e.g., myserver): ") - var name string - fmt.Fscanln(reader) - fmt.Scanln(&name) + name := readLine("Host Name (e.g., myserver): ") if name == "" { return fmt.Errorf("host name is required") } // Get hostname - fmt.Print("Hostname or IP (e.g., 192.168.1.10): ") - var hostname string - fmt.Scanln(&hostname) + hostname := readLine("Hostname or IP (e.g., 192.168.1.10): ") if hostname == "" { return fmt.Errorf("hostname is required") } // Get port defaultPort := cfg.GetAppConfig().DefaultPort - fmt.Printf("Port [%d]: ", defaultPort) - var portInput string - fmt.Scanln(&portInput) + portInput := readLine(fmt.Sprintf("Port [%d]: ", defaultPort)) port := defaultPort if portInput != "" { fmt.Sscanf(portInput, "%d", &port) } // Get username - fmt.Print("Username: ") - var username string - fmt.Scanln(&username) + username := readLine("Username: ") if username == "" { return fmt.Errorf("username is required") } // Get auth type - fmt.Print("Auth Type (password/key/both) [password]: ") - var authType string - fmt.Scanln(&authType) + authType := readLine("Auth Type (password/key/both) [password]: ") if authType == "" { authType = "password" } @@ -227,16 +223,13 @@ func addHostInteractive(cfg *config.Config) error { // Get password var password string if authType == "password" || authType == "both" { - fmt.Print("Password: ") - fmt.Scanln(&password) + password = readLine("Password: ") } // Get key path var keyContent string if authType == "key" || authType == "both" { - fmt.Print("Path to private key (~/.ssh/id_rsa): ") - var keyPath string - fmt.Scanln(&keyPath) + keyPath := readLine("Path to private key (~/.ssh/id_rsa): ") if keyPath != "" { data, err := os.ReadFile(keyPath) if err != nil { @@ -247,14 +240,10 @@ func addHostInteractive(cfg *config.Config) error { } // Get group - fmt.Print("Group (optional): ") - var group string - fmt.Scanln(&group) + group := readLine("Group (optional): ") // Get tags - fmt.Print("Tags (comma-separated, optional): ") - var tagsInput string - fmt.Scanln(&tagsInput) + tagsInput := readLine("Tags (comma-separated, optional): ") var tags []string if tagsInput != "" { tags = strings.Split(tagsInput, ",") @@ -264,9 +253,7 @@ func addHostInteractive(cfg *config.Config) error { } // Get notes - fmt.Print("Notes (optional): ") - var notes string - fmt.Scanln(¬es) + notes := readLine("Notes (optional): ") // Create host host := &models.Host{ diff --git a/cmd/hostkeeper/connect.go b/cmd/hostkeeper/connect.go index a7f1ad6..a15a8eb 100644 --- a/cmd/hostkeeper/connect.go +++ b/cmd/hostkeeper/connect.go @@ -103,6 +103,20 @@ func findHost(ctx context.Context, store storage.Storage, identifier string) (*m } } + // Try to find by hostname + for _, h := range hosts { + if h.Hostname == identifier { + return h, nil + } + } + + // Try to find by ID prefix (short ID match) + for _, h := range hosts { + if len(h.ID) >= 8 && h.ID[:8] == identifier { + return h, nil + } + } + // Host not found, provide helpful error return nil, fmt.Errorf("host '%s' not found. Use 'hostkeeper list' to see available hosts", identifier) }