package cmd
|
|
import (
|
"fmt"
|
"os"
|
|
"github.com/aisim/kb-cli/internal/draft"
|
"github.com/aisim/kb-cli/internal/index"
|
"github.com/spf13/cobra"
|
)
|
|
var draftCmd = &cobra.Command{
|
Use: "draft",
|
Short: "草稿管理",
|
Long: `kb-cli draft create # 创建草稿(AI 生成 tags + 合并指示)`,
|
}
|
|
var draftCreateCmd = &cobra.Command{
|
Use: "create",
|
Short: "创建草稿",
|
Long: `kb-cli draft create --type <类型> --title <标题> --content-file <内容文件> [--source <来源>] [--force]
|
|
创建草稿,自动提取 tags 并生成合并指示。
|
|
类型: 售后/产品/运营/行业/TAPD
|
示例:
|
kb-cli draft create --type 售后 --title "充不进气问题" --content-file /tmp/draft.md
|
kb-cli draft create --type TAPD --title "档案下载失败" --content-file /tmp/bug.md --source "TAPD#12345"`,
|
RunE: runDraftCreate,
|
}
|
|
var tagsCmd = &cobra.Command{
|
Use: "tags",
|
Short: "标签管理",
|
Long: `kb-cli tags rebuild # 批量重建现有文档的 tags`,
|
}
|
|
var tagsRebuildCmd = &cobra.Command{
|
Use: "rebuild",
|
Short: "批量重建 tags",
|
Long: `kb-cli tags rebuild [--vault <路径>] [--limit <数量>] [--dry-run]
|
|
批量重建现有文档的 tags,使用 LLM 重新提取。
|
|
示例:
|
kb-cli tags rebuild --limit 10 # 重建前 10 个文档的 tags
|
kb-cli tags rebuild --dry-run # 仅预览,不实际更新`,
|
RunE: runTagsRebuild,
|
}
|
|
var (
|
draftType string
|
draftTitle string
|
draftContentFile string
|
draftSource string
|
draftForce bool
|
tagsLimit int
|
tagsDryRun bool
|
)
|
|
func init() {
|
// draft create 命令
|
draftCreateCmd.Flags().StringVar(&draftType, "type", "", "草稿类型(售后/产品/运营/行业/TAPD)")
|
draftCreateCmd.Flags().StringVar(&draftTitle, "title", "", "草稿标题")
|
draftCreateCmd.Flags().StringVar(&draftContentFile, "content-file", "", "草稿内容文件路径")
|
draftCreateCmd.Flags().StringVar(&draftSource, "source", "", "来源标识")
|
draftCreateCmd.Flags().BoolVar(&draftForce, "force", false, "强制创建(跳过重复检查)")
|
draftCreateCmd.MarkFlagRequired("type")
|
draftCreateCmd.MarkFlagRequired("title")
|
draftCreateCmd.MarkFlagRequired("content-file")
|
|
draftCmd.AddCommand(draftCreateCmd)
|
|
// tags rebuild 命令
|
tagsRebuildCmd.Flags().IntVar(&tagsLimit, "limit", 0, "限制处理文档数量(0=全部)")
|
tagsRebuildCmd.Flags().BoolVar(&tagsDryRun, "dry-run", false, "仅预览,不实际更新")
|
|
tagsCmd.AddCommand(tagsRebuildCmd)
|
|
rootCmd.AddCommand(draftCmd)
|
rootCmd.AddCommand(tagsCmd)
|
}
|
|
func runDraftCreate(cmd *cobra.Command, args []string) error {
|
// 读取内容文件
|
content, err := os.ReadFile(draftContentFile)
|
if err != nil {
|
return fmt.Errorf("读取内容文件失败: %w", err)
|
}
|
|
if len(content) == 0 {
|
return fmt.Errorf("内容文件为空")
|
}
|
|
// 打开索引
|
store, err := index.Open(dbPath)
|
if err != nil {
|
return fmt.Errorf("打开索引失败: %w", err)
|
}
|
defer store.Close()
|
|
// 创建草稿录入器
|
intake := draft.NewIntake(vaultPath, store)
|
|
// 创建草稿
|
if err := intake.CreateDraft(draftType, draftTitle, string(content), draftSource, draftForce); err != nil {
|
return fmt.Errorf("创建草稿失败: %w", err)
|
}
|
|
return nil
|
}
|
|
func runTagsRebuild(cmd *cobra.Command, args []string) error {
|
// 打开索引
|
store, err := index.Open(dbPath)
|
if err != nil {
|
return fmt.Errorf("打开索引失败: %w", err)
|
}
|
defer store.Close()
|
|
// 创建草稿录入器
|
intake := draft.NewIntake(vaultPath, store)
|
|
// 重建 tags
|
if err := intake.RebuildTags(tagsLimit, tagsDryRun); err != nil {
|
return fmt.Errorf("重建 tags 失败: %w", err)
|
}
|
|
return nil
|
}
|