package cmd
|
|
import (
|
"encoding/json"
|
"fmt"
|
"os"
|
"path/filepath"
|
"strings"
|
|
"github.com/aisim/kb-cli/internal/llm"
|
"github.com/aisim/kb-cli/internal/review"
|
"github.com/spf13/cobra"
|
)
|
|
var reviewCmd = &cobra.Command{
|
Use: "review",
|
Short: "审阅预览",
|
Long: `# review - 审阅预览
|
kb-cli review <草稿目录> [--json] # 读取草稿和合并指示,使用 LLM 生成审阅预览`,
|
Args: cobra.ExactArgs(1),
|
RunE: runReview,
|
}
|
|
var reviewJSON bool
|
|
func init() {
|
reviewCmd.Flags().BoolVar(&reviewJSON, "json", false, "JSON 格式输出")
|
rootCmd.AddCommand(reviewCmd)
|
}
|
|
func runReview(cmd *cobra.Command, args []string) error {
|
draftDir := args[0]
|
|
// 读取草稿和合并指示
|
preview, err := review.ReadDraftAndMerge(vaultPath, draftDir)
|
if err != nil {
|
return fmt.Errorf("读取草稿失败: %w", err)
|
}
|
|
// 如果有目标FAQ,用 LLM 生成3句话概要
|
if preview.TargetFAQ != nil && preview.TargetFAQ.Title != "" {
|
targetPath := preview.TargetFAQ.Path
|
if !filepath.IsAbs(targetPath) {
|
targetPath = filepath.Join(vaultPath, targetPath)
|
}
|
|
targetContent, err := os.ReadFile(targetPath)
|
if err == nil && len(targetContent) > 0 {
|
llmClient := llm.NewClient()
|
summary, err := llmClient.GenerateReviewPreview(preview.TargetFAQ.Title, string(targetContent))
|
if err != nil {
|
fmt.Fprintf(os.Stderr, "警告: LLM 生成概要失败: %v\n", err)
|
} else {
|
preview.TargetFAQ.Summary = summary
|
}
|
}
|
}
|
|
// 输出
|
if reviewJSON {
|
output, err := review.FormatPreviewJSON(preview)
|
if err != nil {
|
return fmt.Errorf("格式化输出失败: %w", err)
|
}
|
fmt.Println(output)
|
} else {
|
// 表格输出
|
fmt.Println(review.FormatPreviewTable(preview))
|
|
// 如果有草稿正文,也展示主要内容
|
expandedVault := expandHomePath(vaultPath)
|
draftPath := filepath.Join(expandedVault, draftDir, "draft.md")
|
draftContent, err := os.ReadFile(draftPath)
|
if err == nil {
|
content := extractMainContent(string(draftContent))
|
if content != "" {
|
fmt.Println("### 草稿主要内容\n")
|
fmt.Println(content)
|
}
|
}
|
}
|
|
return nil
|
}
|
|
// extractMainContent 从 draft.md 中提取正文(去掉 frontmatter)
|
func extractMainContent(content string) string {
|
if !strings.HasPrefix(content, "---") {
|
return content
|
}
|
|
// 找到第二个 ---
|
endIdx := strings.Index(content[3:], "\n---")
|
if endIdx == -1 {
|
return content
|
}
|
|
// 返回 frontmatter 之后的内容
|
mainContent := content[endIdx+6:]
|
return strings.TrimSpace(mainContent)
|
}
|
|
// expandHomePath 展开路径中的 ~
|
func expandHomePath(path string) string {
|
if strings.HasPrefix(path, "~/") {
|
homeDir, _ := os.UserHomeDir()
|
return filepath.Join(homeDir, path[2:])
|
}
|
return path
|
}
|
|
// 保留 json 包引用
|
var _ = json.Marshal
|