package main import ( "fmt" "github.com/spf13/cobra" "github.com/spf13/viper" "git.tukangketik.id/swanadiva/hostkeeper/pkg/config" ) var ( cfgFile string appCfg *config.Config verbose int debug bool ) var rootCmd = &cobra.Command{ Use: "hostkeeper", Short: "Cross-platform SSH/SFTP management tool", Long: `Hostkeeper - Cross-platform SSH/SFTP Management Tool A comprehensive SSH/SFTP management tool with secure credential storage, host management, and cross-device sync capabilities. Quick Start: hostkeeper add myserver --host 192.168.1.10 --user admin hostkeeper list hostkeeper connect myserver For more information, visit the project repository.`, PersistentPreRunE: func(cmd *cobra.Command, args []string) error { // Initialize configuration cfg, err := config.New() if err != nil { return fmt.Errorf("failed to initialize config: %w", err) } appCfg = cfg return nil }, } func init() { cobra.OnInitialize(initConfig) rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is platform-specific app dir)") rootCmd.PersistentFlags().CountVarP(&verbose, "verbose", "v", "verbose output (-v for info, -vv for debug)") rootCmd.PersistentFlags().BoolVar(&debug, "debug", false, "enable debug mode") rootCmd.AddCommand(versionCmd) } // initConfig reads in config file and ENV variables if set func initConfig() { if cfgFile != "" { viper.SetConfigFile(cfgFile) } else { // Use platform-specific config directory cfg, err := config.New() if err != nil { return } viper.AddConfigPath(cfg.GetConfigDir()) viper.SetConfigType("json") viper.SetConfigName("config") } viper.AutomaticEnv() // Read config file (ignore if not found for first run) _ = viper.ReadInConfig() } var versionCmd = &cobra.Command{ Use: "version", Short: "Print the version number", Long: `Print the version and build information for HostKeeper.`, Run: func(cmd *cobra.Command, args []string) { fmt.Printf("hostkeeper %s (built: %s)\n", version, buildTime) }, } // Execute runs the root command func Execute() error { return rootCmd.Execute() }