package cmd import ( "fmt" "os" "strings" "github.com/spf13/cobra" "github.com/aisim/kb-cli/internal/llm" ) var ( vaultPath string dbPath string ) // buildLong 为父命令动态生成 Long,格式:# cmd - Short\n子命令详细用法 func buildLong(cmd *cobra.Command) string { var sb strings.Builder sb.WriteString(fmt.Sprintf("# %s - %s\n", cmd.Name(), cmd.Short)) for _, sub := range cmd.Commands() { if sub.Hidden { continue } if sub.Long != "" { sb.WriteString(sub.Long) // 确保 Long 末尾有换行 if !strings.HasSuffix(sub.Long, "\n") { sb.WriteString("\n") } } else { sb.WriteString(fmt.Sprintf("%s # %s\n", sub.CommandPath(), sub.Short)) } } return sb.String() } var rootCmd = &cobra.Command{ Use: "kb-cli", Short: "知识库搜索与管理工具", Long: `kb-cli - 知识库搜索与管理工具 Global: [--vault <路径>] [--db <路径>]`, } func Execute() { // 为每个父命令动态生成 Long(包含子命令详细用法) for _, cmd := range rootCmd.Commands() { if cmd.HasAvailableSubCommands() && !cmd.Hidden { cmd.Long = buildLong(cmd) } } // root Long = 头部 + 所有一级子命令的 Long var sb strings.Builder sb.WriteString(rootCmd.Long) for _, cmd := range rootCmd.Commands() { if cmd.Hidden { continue } sb.WriteString("\n") sb.WriteString(cmd.Long) } rootCmd.Long = sb.String() if err := rootCmd.Execute(); err != nil { // 如果是参数不足的错误,显示对应命令的 help errMsg := err.Error() if strings.Contains(errMsg, "arg(s)") || strings.Contains(errMsg, "received") || strings.Contains(errMsg, "required flag") { // 找到当前命令并显示其 help cmd, _, findErr := rootCmd.Find(os.Args[1:]) if findErr == nil { cmd.Help() } fmt.Println() // 空行 } else { cobra.CheckErr(err) } } } func init() { homeDir, _ := os.UserHomeDir() // 从配置文件读取默认值(优先级:配置文件 > 环境变量 > 内置默认值) cfg := llm.LoadConfig() defaultVault := cfg.KnowledgeBase.VaultPath defaultDB := cfg.KnowledgeBase.DBPath // 如果配置文件没有设置,使用环境变量或默认值 if defaultVault == "" { defaultVault = os.Getenv("KB_VAULT") if defaultVault == "" { defaultVault = homeDir + "/aisim/note/001/笔记001" } } if defaultDB == "" { defaultDB = homeDir + "/.cache/kb-cli/kb.db" } rootCmd.PersistentFlags().StringVar(&vaultPath, "vault", defaultVault, "知识库根目录") rootCmd.PersistentFlags().StringVar(&dbPath, "db", defaultDB, "索引数据库路径") // 自定义 help 模板:只输出 Long helpTemplate := `{{.Long}}` rootCmd.SetUsageTemplate(helpTemplate) rootCmd.SetHelpTemplate(helpTemplate) rootCmd.SilenceUsage = true rootCmd.SilenceErrors = true }