Skill: gitgily/kuaidao (version 1.0.4)

--- name: kd version: 1.1.0 description: "快导(KD) - 短视频脚本批量生成与管理。当用户需要批量生成多平台短视频脚本、管理文案库时使用。" metadata: requires: bins: ["python"] pypi_packages: ["openpyxl"] skills: - "web_search" optional: bins: ["lark-cli"] skills: - "lark-doc" - "lark-wiki" env: required: [] # 没有必需的环境变量 optional: - name: "LARK_CLI_TOKEN" description: "飞书 CLI 认证 token（仅当使用飞书上传功能时需要）" sensitive: true files: - "config/platforms.json" - "config/user_config.json" cliHelp: | # 查看帮助 python kd.py --help # 执行完整快导流程 python kd.py run --platform xiaohongshu # 执行单步 python kd.py step --platform xiaohongshu --step 6 # 规则更新 python kd.py rules --platform xiaohongshu # 活动管理（v1.1.0新增） python kd.py activity --command "添加活动：春节特惠，关键词：春节、过年" python kd.py activity --command "列出所有活动" configPaths: - "~/.agents/skills/kd/config/" configPaths.optional: - "~/.agents/skills/kd/references/platform_rules/" --- # 快导 (KD) 快导(KD)是一个跨平台、跨行业的短视频脚本批量生成与管理工具。 ## ⚠️ CRITICAL — 首次使用必读 **使用前必须完成以下配置：** 1. **安装依赖：** `pip install openpyxl` 2. **配置搜索关键词：** 编辑 `config/platforms.json` 3. **设置文案库路径：** 编辑 `config/user_config.json` 详见 [README.md](./README.md) 完整文档。 ## 核心功能 | 功能 | 说明 | |:---|:---| | **快导系列** | 10步流程生成多平台短视频脚本 | | **规则更新** | 生成/更新平台运营规则文档 | ## Shortcuts（快速使用参考） | 用户说 | 我执行 | 说明 | |:---|:---|:---| | "快导小红书，生成5条" | 执行完整10步流程 | 自动执行搜索→生成→写入→报告全流程 | | "快导第6步" | 执行单步生成脚本 | 仅执行Step 6，需前置步骤数据 | | "配置关键词" | 引导配置 platforms.json | 设置平台搜索关键词池 | | "配置文案库路径" | 引导配置 user_config.json | 设置Excel文案库保存位置 | | "配置飞书空间" | 引导配置 report_space_id | 设置报告上传的飞书知识库 | | "检查文案库格式" | 执行Step 5格式扫描 | 读取Excel实际格式参数 | | "查看平台规则" | 读取 rules 文档 | 查看已生成的平台运营规则 | | "更新小红书规则" | 执行规则更新系列 | 搜索最新规则并更新文档 | | "测试快导" | 运行 test_workflow.py | 快速测试核心功能是否正常 | ## 执行模式 ### 自动模式（默认） ```python from scripts import WorkflowManager workflow = WorkflowManager('xiaohongshu') result = workflow.run_full() ``` ### 交互模式（每步完成后暂停） ```python from scripts import WorkflowManager # 启用交互模式 workflow = WorkflowManager('xiaohongshu', interactive=True) # 执行，每步完成后返回等待 result = workflow.run_full() if result.get('paused'): print(result['message']) # "Step X 完成，是否继续？" # 用户确认后继续 result = workflow.resume() ``` ### 回调模式（即时回复每步结果） ```python def on_step_complete(step_num, result, should_pause): print(f"Step {step_num} 完成") # 即时回复用户 workflow = WorkflowManager('xiaohongshu') workflow.run_full(callback=on_step_complete) ``` ## 核心模块 - `ConfigManager` - 配置管理 - `ScriptGenerator` - 脚本生成 - `ExcelManager` - Excel操作 **详细用法和示例见 [README.md](./README.md)** ## 版本 | 版本 | 日期 | 说明 | |:---:|:---:|:---| | 1.1.0 | 2026-04-27 | 新增：智能时长计算、活动管理、详细内容格式、BGM生成、Excel行高100 | | 1.0.0 | 2026-04-24 | 初始版本，支持3平台 | --- ## v1.1.0 新功能详解 ### 1. 智能时长计算 系统会自动计算并调整每个分镜的时间段： - **台词时长**：字数 × 0.25秒 - **运镜时长**：固定2秒、推拉3秒、摇移4秒、复杂6秒、航拍8秒 - **建议时长**：max(台词, 运镜) + 1秒缓冲 - **自动调整**：使用建议时长更新B列时间段 **配置**（`config/platforms.json`）： ```json "duration_policy": { "xiaohongshu": { "auto_adjust": true, // 开启自动调整 "calculation_rules": { "speech_rate": 0.25, "motion_base": { "static": 2, "push_pull": 3, ... }, "buffer_seconds": 1 } } } ``` ### 2. 活动管理 支持自然语言管理活动： - 添加活动：`添加活动：春节特惠，关键词：春节、过年` - 列出活动：`列出所有活动` - 查询活动：`查询活动：春节` - 删除活动：`删除活动：春节特惠` 系统会根据脚本主题自动匹配活动，填入L列（关联活动）。 ### 3. 详细内容格式 分镜内容现在支持更详细的描述： - **C列-镜头**：设备/焦段/内容 - **D列-运镜**：方式/轨迹/速度 - **E列-技巧**：光线/ISO/对焦/色调 - **F列-画面**：场景/构图/色彩/氛围 ### 4. BGM详细生成 I列BGM现在要求详细格式： ``` 音乐名：《稻香》周杰伦 风格：田园治愈、轻快温暖 使用时机：0-30秒前奏，30-60秒主歌，60-90秒副歌 ``` ### 5. Excel行高统一 数据行统一设置为100，标题行20.4： ```json "row_height": { "title_row": 20.4, "data_row": 100 } ``` ### 6. 外网搜索自动收集 `user_config.json` 新增 `external_search` 配置： ```json { "external_search": { "auto_collect": true, // 空关键词时自动获取热门 "collect_count": 20, "platforms": ["TikTok", "YouTube"], "default_keywords": [] // 备用关键词（可选） } } ``` **三种使用场景：** 1. `external_keywords` 有值 → 使用用户配置的关键词 2. `external_keywords` 为空，`default_keywords` 有值 → 使用默认关键词 3. 两者都为空 + `auto_collect: true` → 调用 web_search 自动获取当前热门 **注意：** 场景3如果搜索失败会直接报错，不使用备用数据。 --- ## 联系我们 如有问题或建议，欢迎交流： - **微信号：** huitouyoujianta - **用途：** 快导(KD)技能使用咨询、功能建议、技术交流 欢迎加微信交流学习！

path: config/feishu_permissions.json
content: {
  "scopes": {
    "tenant": [
      "aily:file:read",
      "aily:file:write",
      "application:application.app_message_stats.overview:readonly",
      "application:application:self_manage",
      "application:bot.menu:write",
      "cardkit:card:read",
      "cardkit:card:write",
      "contact:user.employee_id:readonly",
      "corehr:file:download",
      "event:ip_list",
      "im:chat.access_event.bot_p2p_chat:read",
      "im:chat.members:bot_access",
      "im:message",
      "im:message.group_at_msg:readonly",
      "im:message.p2p_msg:readonly",
      "im:message:readonly",
      "im:message:send_as_bot",
      "im:resource",
      "drive:file:read",
      "drive:file:write",
      "wiki:space:read",
      "wiki:space:write",
      "docx:document:read",
      "docx:document:write",
      "sheets:spreadsheet:read",
      "sheets:spreadsheet:write"
    ],
    "user": [
      "aily:file:read",
      "aily:file:write",
      "im:chat.access_event.bot_p2p_chat:read",
      "drive:file:read",
      "drive:file:write",
      "wiki:space:read",
      "docx:document:read",
      "docx:document:write",
      "sheets:spreadsheet:read",
      "sheets:spreadsheet:write"
    ]
  },
  "explanation": {
    "tenant": {
      "description": "应用身份权限（tenant_access_token）",
      "required_for": [
        "读取/写入云文档",
        "读取/写入知识库",
        "发送消息",
        "上传文件"
      ]
    },
    "user": {
      "description": "用户身份权限（user_access_token）",
      "required_for": [
        "以用户身份操作文档",
        "访问用户个人资源"
      ]
    }
  }
}


path: config/platforms.json
content: {
  "metadata": {
    "version": "1.1.0",
    "description": "快导(KD) Skill - 平台参数配置",
    "last_updated": "2026-04-27"
  },
  "platforms": {
    "xiaohongshu": {
      "name": "小红书",
      "name_en": "Xiaohongshu",
      "user_profile": "女性、种草决策",
      "content_style": "攻略型、图文结合、实用价值",
      "theme_direction": [],
      "theme_direction_note": "用户首次使用时需配置主题方向",
      "title_rules": {
        "max_length": 20,
        "style": "攻略感强",
        "emoji": true
      },
      "duration": {
        "total": "2-3min",
        "total_seconds": { "min": 120, "max": 180 },
        "segment": "6-12s",
        "segment_seconds": { "min": 6, "max": 12 },
        "segments_count": 18
      },
      "content_requirements": {
        "columns": {
          "A": { "name": "视频文案", "min_chars": 0, "story_required": true },
          "B": { "name": "时间段", "format": "精确到秒" },
          "C": { "name": "镜头", "min_chars": 20 },
          "D": { "name": "运镜", "min_chars": 15 },
          "E": { "name": "拍摄技巧", "min_chars": 15 },
          "F": { "name": "画面", "min_chars": 20 },
          "G": { "name": "台词", "min_chars": 30 },
          "H": { "name": "音效", "min_chars": 15 },
          "I": { "name": "推荐音乐/BGM" },
          "J": { "name": "文案标签" },
          "K": { "name": "使用状态", "default": "待使用" },
          "L": { "name": "关联活动" },
          "M": { "name": "发布日期" },
          "N": { "name": "备注" }
        }
      },
      "keywords": [],
      "keywords_note": "用户首次使用时需配置搜索关键词"
    },
    "douyin": {
      "name": "抖音",
      "name_en": "Douyin",
      "user_profile": "年轻人、公域流量",
      "content_style": "快节奏、黄金3秒、视觉冲击",
      "theme_direction": [],
      "theme_direction_note": "用户首次使用时需配置主题方向",
      "title_rules": {
        "max_length": 50,
        "style": "吸睛、话题性强",
        "emoji": true
      },
      "duration": {
        "total": "1min",
        "total_seconds": { "min": 45, "max": 60 },
        "segment": "3-5s",
        "segment_seconds": { "min": 3, "max": 5 },
        "segments_count": 12
      },
      "content_requirements": {
        "columns": {
          "A": { "name": "视频文案", "story_required": true },
          "B": { "name": "时间段", "min_chars": 0 },
          "C": { "name": "镜头", "min_chars": 15 },
          "D": { "name": "运镜", "min_chars": 10 },
          "E": { "name": "拍摄技巧", "min_chars": 10 },
          "F": { "name": "画面", "min_chars": 15 },
          "G": { "name": "台词", "min_chars": 20 },
          "H": { "name": "音效", "min_chars": 10 },
          "I": { "name": "推荐音乐/BGM" },
          "J": { "name": "文案标签" },
          "K": { "name": "使用状态", "default": "待使用" },
          "L": { "name": "关联活动" },
          "M": { "name": "发布日期" },
          "N": { "name": "备注" }
        }
      },
      "keywords": [],
      "keywords_note": "用户首次使用时需配置搜索关键词"
    },
    "shipinhao": {
      "name": "视频号",
      "name_en": "Channels",
      "user_profile": "中老年、私域社交",
      "content_style": "温情叙事、真实人设、完播率",
      "theme_direction": [],
      "theme_direction_note": "用户首次使用时需配置主题方向",
      "title_rules": {
        "max_length": 16,
        "no_punctuation": true,
        "style": "温情、真实"
      },
      "duration": {
        "total": "1-3min",
        "total_seconds": { "min": 60, "max": 180 },
        "segment": "5-10s",
        "segment_seconds": { "min": 5, "max": 10 },
        "segments_count": 15
      },
      "content_requirements": {
        "columns": {
          "A": { "name": "视频文案", "story_required": true },
          "B": { "name": "时间段" },
          "C": { "name": "镜头", "min_chars": 18 },
          "D": { "name": "运镜", "min_chars": 12 },
          "E": { "name": "拍摄技巧", "min_chars": 12 },
          "F": { "name": "画面", "min_chars": 18 },
          "G": { "name": "台词", "min_chars": 25 },
          "H": { "name": "音效", "min_chars": 12 },
          "I": { "name": "推荐音乐/BGM" },
          "J": { "name": "文案标签" },
          "K": { "name": "使用状态", "default": "待使用" },
          "L": { "name": "关联活动" },
          "M": { "name": "发布日期" },
          "N": { "name": "备注" }
        }
      },
      "keywords": [],
      "keywords_note": "用户首次使用时需配置搜索关键词"
    }
  },
  "industry_templates": {
    "note": "用户可在此添加自定义行业模板"
  },
  "global_settings": {
    "copy_library_path": "",
    "copy_library_path_note": "用户首次使用时需配置文案库路径",
    "file_naming": "{platform}文案库.xlsx",
    "report_space_id": "",
    "report_space_id_note": "用户首次使用时需配置飞书空间ID",
    "rules_path": "",
    "rules_path_note": "用户首次使用时需配置平台规则文档保存路径（默认：references/platform_rules/）",
    "max_scripts_per_task": 5,
    "skip_conditions": {
      "no_trending": "如无爆款可选，则取消本次任务执行",
      "duplicate_theme": "避开已有脚本主题"
    },
    "row_height": {
      "title_row": 20.4,
      "data_row": 100
    },
    "row_height_note": "Excel行高设置：标题行20.4，数据行100（符合嘉泰苑标准）"
  },
  "activities": {
    "list": [
      {
        "id": "example",
        "name": "日常推广",
        "keywords": [],
        "applicable_platforms": ["xiaohongshu", "douyin", "shipinhao", "pyq"],
        "note": "示例活动，请删除后添加自己的活动"
      }
    ],
    "default": "日常推广，当前未设置activities",
    "user_configured": false,
    "tutorial_note": "请参考SKILL.md中的'如何配置活动'章节"
  },
  "bgm_library": {
    "categories": {
      "food_display": {
        "name": "美食展示",
        "tracks": [
          {"name": "《小美满》周深", "style": "治愈轻快", "suitable": "全程"},
          {"name": "《风吹一夏》", "style": "轻快活泼", "suitable": "卡点"},
          {"name": "《世间美好与你环环相扣》", "style": "温暖治愈", "suitable": "全程"}
        ]
      },
      "emotional_narrative": {
        "name": "情感叙事",
        "tracks": [
          {"name": "《父亲写的散文诗》许飞", "style": "温情叙事", "suitable": "高潮"},
          {"name": "《成都》赵雷", "style": "民谣怀旧", "suitable": "全程"},
          {"name": "《光阴的故事》罗大佑", "style": "经典怀旧", "suitable": "回忆段落"}
        ]
      },
      "weekend_leisure": {
        "name": "周末休闲",
        "tracks": [
          {"name": "《想去海边》夏日入侵企画", "style": "轻快青春", "suitable": "开头+全程"},
          {"name": "《稻香》周杰伦", "style": "田园治愈", "suitable": "全程"},
          {"name": "《平凡之路》朴树", "style": "励志治愈", "suitable": "转场+高潮"}
        ]
      },
      "nostalgic": {
        "name": "怀旧回忆",
        "tracks": [
          {"name": "《童年》罗大佑", "style": "经典怀旧", "suitable": "回忆片段"},
          {"name": "《外婆的澎湖湾》", "style": "温情经典", "suitable": "家庭场景"},
          {"name": "《故乡的云》费翔", "style": "思乡情怀", "suitable": "返乡场景"}
        ]
      }
    },
    "update_note": "每月更新热门抖音BGM，保持时效性"
  },
  "duration_policy": {
    "xiaohongshu": {
      "target_duration": { "min": 120, "max": 180, "default": 150 },
      "segment_duration": { "min": 6, "max": 15 },
      "auto_calculate": true,
      "auto_adjust": true,
      "adjust_mode": "recommended",
      "calculation_rules": {
        "speech_rate": 0.25,
        "motion_base": {
          "static": 2,
          "push_pull": 3,
          "pan_tilt": 4,
          "complex": 6,
          "drone": 8
        },
        "buffer_seconds": 1,
        "min_motion_time": 2
      }
    },
    "douyin": {
      "target_duration": { "min": 45, "max": 60, "default": 55 },
      "segment_duration": { "min": 3, "max": 8 },
      "auto_calculate": true,
      "auto_adjust": true,
      "adjust_mode": "recommended",
      "calculation_rules": {
        "speech_rate": 0.25,
        "motion_base": {
          "static": 2,
          "push_pull": 2,
          "pan_tilt": 3,
          "complex": 5,
          "drone": 6
        },
        "buffer_seconds": 1,
        "min_motion_time": 2
      }
    },
    "shipinhao": {
      "target_duration": { "min": 60, "max": 180, "default": 120 },
      "segment_duration": { "min": 5, "max": 12 },
      "auto_calculate": true,
      "auto_adjust": true,
      "adjust_mode": "recommended",
      "calculation_rules": {
        "speech_rate": 0.25,
        "motion_base": {
          "static": 2,
          "push_pull": 3,
          "pan_tilt": 4,
          "complex": 6,
          "drone": 8
        },
        "buffer_seconds": 1,
        "min_motion_time": 2
      }
    }
  }
}


path: config/templates.json
content: {
  "metadata": {
    "name": "快导(KD) - 脚本生成模板",
    "version": "1.0.0",
    "description": "提示词模板配置，由用户自定义"
  },
  "prompt_templates": {
    "subtask6_generate": {
      "name": "生成脚本",
      "template": "【角色设定】(Role)\n你是一位拥有5年经验的资深短视频编导\n\n【任务目标】(Task)\n请为我撰写一份关于[主题]的短视频完整脚本\n\n【输入来源】\n- 主题：[TRENDING_TITLES]\n- 平台规则：[PLATFORM_RULES]\n- 平台配置：[PLATFORM_CONFIG]\n- 分镜数量：[SEGMENTS_COUNT]（根据总时长自动计算）\n- 视频时长：[TOTAL_DURATION]\n- 分镜时长范围：[SEGMENT_DURATION_RANGE]\n- 需避开方向：[AVOID_THEMES]\n\n【核心要素】(Core Elements)\n- 目标平台：[PLATFORM_NAME]\n- 分镜时长范围：[SEGMENT_DURATION_RANGE]\n- 目标受众：[TARGET_AUDIENCE]\n- 风格语气：[CONTENT_STYLE]\n\n【脚本要求】(Requirements)\n- 数量：[SCRIPT_COUNT]条\n- 分镜数量：[SEGMENTS_COUNT]个/条（自动计算）\n- 分镜时长：每个[SEGMENT_DURATION_RANGE]，遵循'开头快、中间稳、结尾慢'\n- 总时长：[TOTAL_DURATION]\n- 关系：[SCRIPT_COUNT]条脚本必须差异化\n\n【分镜时长分配模式】\n- 开场分镜：3-5秒（快速吸引）\n- 主体分镜：6-10秒（内容展开）\n- 结尾分镜：10-12秒（升华收尾）\n\n【详细要求】\n1. A列-视频文案：必须包含完整故事叙述（起承转合），不只是标题+标签\n2. B列-时间段：精确到秒，格式如'0-5秒'，每个分镜按分配模式设置\n3. C列-镜头：详细描述景别、角度、主体\n4. D列-运镜：详细说明运镜方式、速度、轨迹\n5. E列-拍摄技巧：详细说明设备、参数、手法\n6. F列-画面：详细描述光影效果、构图方式、色调风格\n7. G列-台词：包含完整台词+语气/停顿说明\n8. H列-音效：详细说明音效类型、音量、节奏\n9. I列-BGM：推荐音乐名称、风格、卡点位置\n10. J列-标签：#话题标签，附选择理由\n11. K列-状态：待使用\n12. L列-活动：关联活动（如有）\n13. M列-日期：计划发布日期\n14. N列-备注：拍摄注意事项\n\n【故事结构要求】\n- 黄金3秒钩子\n- 痛点引入\n- 核心内容\n- 互动引导\n\n【质量检查】\n- [ ] 每个分镜时长是否符合分配模式\n- [ ] 总时长是否控制在[TOTAL_DURATION]\n- [ ] 台词是否口语化（非书面化）\n- [ ] B-C列时间段与镜头是否设计合理\n- [ ] A列是否包含完整故事叙述\n- [ ] C-H列内容是否详细\n\n【输出格式】\n按JSON格式输出[SCRIPT_COUNT]条脚本，每条包含完整的[SEGMENTS_COUNT]个分镜。",
      "template_note": "用户可通过编辑prompts/step6_generate_scripts.md自定义提示词模板",
      "variables": [
        "TRENDING_TITLES",
        "EXTERNAL_TITLE",
        "PLATFORM_RULES",
        "PLATFORM_CONFIG",
        "SEGMENTS_COUNT",
        "TOTAL_DURATION",
        "SEGMENT_DURATION_RANGE",
        "AVOID_THEMES",
        "SCRIPT_COUNT",
        "PLATFORM_NAME",
        "TARGET_AUDIENCE",
        "CONTENT_STYLE"
      ]
    },
    "subtask7_validate": {
      "name": "合理性检查",
      "template": "【任务】对生成的[SCRIPT_COUNT]条脚本进行批量检查\n\n【检查维度】\n1. 时间合理性：时间段分配是否合理，总时长是否符合[TOTAL_DURATION]\n2. 内容合理性：内容是否连贯，逻辑是否通顺\n3. 场景合理性：场景是否真实可拍\n4. 台词合理性：台词是否口语化，是否符合人设\n5. 分镜时长限制：每个分镜是否在[SEGMENT_DURATION_RANGE]范围内，是否遵循分配模式\n6. 技术描述合理性：运镜、技巧、画面描述是否足够详细\n7. 标题合理性：标题是否符合平台限制\n8. 格式合理性：14列内容是否完整\n9. 故事叙述：A列是否包含完整的起承转合\n\n【处理方式】\n发现不合理项 → 直接修改脚本 → 记录修改内容\n\n【输出格式】\n表格形式输出检查结果和修改记录。",
      "template_note": "用户可通过编辑prompts/step7_validate_scripts.md自定义检查标准"
    }
  },
  "script_templates": {
    "structure": {
      "note": "脚本结构模板，由用户通过编辑prompts/step6_generate_scripts.md自定义",
      "columns": ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N"],
      "columns_description": "用户可在step6中自定义每列的详细要求",
      "example": {
        "A": "视频文案（标题+故事+标签）",
        "B": "时间段（0-5秒）",
        "C": "镜头描述",
        "D": "运镜描述",
        "E": "拍摄技巧",
        "F": "画面描述",
        "G": "台词",
        "H": "音效",
        "I": "BGM",
        "J": "标签",
        "K": "状态",
        "L": "活动",
        "M": "日期",
        "N": "备注"
      }
    }
  },
  "duration_distribution": {
    "note": "分镜时长分配模式由用户在step6中自定义，默认遵循'开头快、中间稳、结尾慢'原则",
    "calculation_method": "总时长 ÷ 平均分镜时长 = 分镜数量，然后按分配模式分配",
    "example": {
      "description": "例如：2分钟视频，16个分镜",
      "pattern": [3, 5, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 10, 10, 12],
      "note": "以上为示例，实际由用户自行配置"
    }
  },
  "user_customization": {
    "说明": "本文件所有模板内容均可由用户自定义",
    "自定义方式": [
      "1. 直接编辑本文件",
      "2. 编辑prompts/目录下的对应.md文件",
      "3. 使用kd config命令设置"
    ],
    "首次使用": "首次使用时需要通过以上方式配置模板内容"
  }
}


path: config/user_config.json
content: {
  "_comment": "快导(KD) 用户配置文件 - 首次使用时请填写以下配置项",
  "_comment2": "或运行: kd setup 进行交互式配置",

  "copy_libraries": {
    "xiaohongshu": "",
    "douyin": "",
    "shipinhao": "",
    "pyq": ""
  },
  "copy_libraries_note": "各平台文案库Excel文件路径，示例: {\"xiaohongshu\": \"F:\\\\vlog\\\\JT\\\\idea\\\\小红书文案库.xlsx\"}",

  "report_space_id": "",
  "report_space_id_note": "飞书知识库空间ID，用于保存执行报告",

  "rules_files": {
    "xiaohongshu": "references/platform_rules/xiaohongshu_rules.md",
    "douyin": "references/platform_rules/douyin_rules.md",
    "shipinhao": "references/platform_rules/shipinhao_rules.md",
    "pyq": "references/platform_rules/pyq_rules.md"
  },
  "rules_files_note": "各平台规则文档路径，可按平台自定义",

  "external_keywords": [],
  "external_keywords_note": "外网搜索关键词池（可选），示例: [\"food\", \"cooking\", \"life\", \"vlog\"]",

  "external_search": {
    "auto_collect": true,
    "collect_count": 20,
    "platforms": ["TikTok", "YouTube"],
    "default_keywords": []
  },
  "external_search_note": "外网搜索配置：auto_collect=true时空关键词自动收集热门视频（default_keywords为空时将自动生成）",

  "user_info": {
    "name": "",
    "email": ""
  }
}


path: config/workflow.json
content: {
  "metadata": {
    "name": "快导(KD) - 脚本生成工作流",
    "version": "1.0.0",
    "description": "10步完整执行流程",
    "total_steps": 10
  },
  "workflow": {
    "name": "快导系列",
    "description": "生成多平台短视频脚本的10步流程",
    "execution_mode": "step_by_step",
    "error_handling": "stop_and_notify",
    "step_timeout": 300,
    "user_config_required": [
      "copy_library_path",
      "report_space_id",
      "platform_keywords",
      "rules_path"
    ],
    "steps": {
      "step1": {
        "name": "搜索目标平台爆款",
        "description": "搜索并选定平台爆款视频",
        "note": "关键词池从用户配置的platforms.json读取",
        "execution": {
          "method": "random_sample",
          "sample_size": "用户配置",
          "results_per_search": 20,
          "final_selection": "用户配置"
        },
        "output": {
          "selected_keywords": [],
          "trending_videos": [],
          "final_selection": []
        }
      },
      "step2": {
        "name": "读取平台规则",
        "description": "读取平台运营规则文档",
        "note": "规则文档由用户通过'规则更新系列'生成",
        "rules_summary": [
          "时长要求",
          "核心指标",
          "引流限制",
          "原创要求",
          "互动率要求",
          "违规红线",
          "文案要求"
        ],
        "output": {
          "platform_rules": {},
          "key_requirements": []
        }
      },
      "step3": {
        "name": "搜索外网平台",
        "description": "搜索TikTok/YouTube爆款",
        "note": "关键词池从用户配置的外部关键词设置读取",
        "execution": {
          "method": "random_sample",
          "sample_size": 3,
          "results_per_search": 20,
          "final_selection": 1
        },
        "skip_condition": "如无爆款可选，则取消本次任务执行"
      },
      "step4": {
        "name": "同质化检查",
        "description": "检查避免与已有脚本重复",
        "note": "从用户配置的文案库路径读取已有脚本",
        "action": "读取文案库，输出已有脚本详情",
        "output": {
          "existing_scripts_count": 0,
          "existing_scripts": [],
          "themes_to_avoid": []
        }
      },
      "step5": {
        "name": "格式检查",
        "description": "现场读取Excel实际格式",
        "action": "使用Python openpyxl读取，禁止凭记忆",
        "check_items": {
        "title_row": ["字体", "字号", "粗体", "字体颜色", "填充类型", "填充颜色", "水平对齐", "垂直对齐", "自动换行", "边框", "行高"],
        "data_row_A": ["字体", "字号", "粗体", "填充类型", "填充颜色", "水平对齐", "垂直对齐", "自动换行", "边框", "行高", "合并"],
        "data_row_B_H": ["字体", "字号", "粗体", "填充类型", "水平对齐", "垂直对齐", "自动换行", "边框", "行高", "合并"],
        "data_row_I_N": ["字体", "字号", "粗体", "填充类型", "水平对齐", "垂直对齐", "自动换行", "边框", "行高", "合并"],
        "summary": ["总行数", "总列数", "标题行格式", "数据行A列格式", "数据行B-H列格式", "数据行I-N列格式", "合并单元格范围"]
      },
        "output": {
          "format_confirmed": false,
          "format_details": {}
        }
      },
      "step6": {
        "name": "生成脚本",
        "description": "生成差异化脚本",
        "note": "分镜数量根据总时长和分镜时长自动计算",
        "requirements": {
          "script_count": "用户配置，默认5条",
          "segments_per_script": "auto",
          "segment_duration": "from_platform_config",
          "content_detail": "from_platform_config"
        },
        "key_rules": [
          "每个分镜时长必须符合平台配置",
          "A列必须包含完整故事叙述（起承转合）",
          "C-H列内容必须详细（满足字数要求）",
          "脚本必须差异化"
        ]
      },
      "step7": {
        "name": "合理性检查",
        "description": "对生成的脚本进行批量检查",
        "check_dimensions": [
          "时间合理性",
          "内容合理性",
          "场景合理性",
          "台词合理性",
          "分镜时长限制",
          "技术描述合理性",
          "标题合理性",
          "格式合理性",
          "故事叙述"
        ],
        "action_on_fail": "直接修改脚本，记录修改内容"
      },
      "step8": {
        "name": "更新文案库",
        "description": "将脚本写入Excel文案库",
        "execution": {
          "method": "split_write",
          "scripts_per_batch": 1,
          "write_mode": "append",
          "preserve_format": true
        },
        "output": {
          "write_status": [],
          "start_row": 0,
          "end_row": 0
        }
      },
      "step9": {
        "name": "全面检查对比",
        "description": "验证写入后的文件",
        "method": "python_openpyxl",
        "visual_confirmation": "禁止",
        "check_dimensions": [
          "格式正确性",
          "内容完整性",
          "写入位置正确性"
        ],
        "error_handling": {
          "first_fail": "自主修改格式问题",
          "after_fix": "重新执行step9",
          "second_fail": "删除step8写入的所有内容，回退到step8重新执行"
        }
      },
      "step10": {
        "name": "提交报告",
        "description": "生成并保存执行报告",
        "note": "保存到用户配置的飞书空间ID",
        "report_format": "markdown",
        "save_location": "飞书知识库",
        "naming": "日期-快导-平台名称"
      }
    }
  },
  "rule_update_workflow": {
    "name": "规则更新系列",
    "description": "生成/更新平台规则文档（单次任务，非周期）",
    "execution_mode": "manual",
    "steps": [
      "搜索平台规则变化",
      "搜索违规案例",
      "搜索爆款趋势",
      "生成规则文档"
    ],
    "output": {
      "rules_document": "保存到用户配置的rules_path目录（默认：references/platform_rules/）"
    }
  }
}


path: config/__init__.py
content: # config 包初始化
# 快导(KD) 配置文件目录


path: entry_template.py
content: #!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
KD Skill 入口脚本模板

使用此模板创建你自己的 KD Skill 入口脚本
编码修复已内置，支持 Windows 中文正常显示

⚠️ 安全提示：
1. 修改下方 SKILL_PATH 为你实际的安装路径
2. 修改 OUTPUT_PATH 为你希望保存输出的目录
3. 首次运行前请检查所有路径配置
"""

import sys
import io

# ========== Windows 编码修复 - 必须在所有导入之前 ==========
if sys.platform == 'win32':
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
    sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='replace')
# ==========================================================

# ========== 配置区域 - 修改为你自己的路径 ==========
# KD Skill 安装路径
SKILL_PATH = r'C:\Users\YOUR_USERNAME\.agents\skills\kd'  # <-- 修改这里

# 输出文件保存路径（请确保目录存在）
OUTPUT_PATH = r'C:\Users\YOUR_USERNAME\Documents\kd_output.txt'  # <-- 修改这里
# ==================================================

# 安全提示
print("⚠️  安全提示：首次运行前请确认：")
print(f"  1. SKILL_PATH: {SKILL_PATH}")
print(f"  2. OUTPUT_PATH: {OUTPUT_PATH}")
print("  3. 这些路径是你期望的")
print()
response = input("是否继续? (yes/no): ")
if response.lower() != 'yes':
    print("已取消")
    sys.exit(0)

# 添加 KD Skill 到路径
sys.path.insert(0, SKILL_PATH)

# 导入 KD Skill 模块
from scripts import (
    ConfigManager,
    ScriptGenerator,
    ExcelManager,
    WorkflowManager,
    FormatChecker
)

# ========== 你的代码从这里开始 ==========

def main():
    # 使用用户指定的输出路径
    output_file = OUTPUT_PATH
    
    with open(output_file, 'w', encoding='utf-8') as f:
        f.write("=" * 50 + "\n")
        f.write("快导(KD) Skill 入口脚本\n")
        f.write("=" * 50 + "\n")
        
        # 示例：加载配置
        f.write("\n[1] 加载平台配置\n")
        config = ConfigManager()
        platform = config.get_platform_config('xiaohongshu')
        f.write(f"  平台: {platform['name']}\n")
        f.write(f"  用户画像: {platform['user_profile']}\n")
        f.write(f"  内容风格: {platform['content_style']}\n")
        
        # 示例：创建脚本生成器
        f.write("\n[2] 创建脚本生成器\n")
        generator = ScriptGenerator('xiaohongshu')
        f.write(f"  分镜数量: {generator.segments_count}\n")
        
        f.write("\n" + "=" * 50 + "\n")
        f.write("运行成功！\n")
        f.write("=" * 50 + "\n")
    
    print(f"输出已保存到: {output_file}")

if __name__ == '__main__':
    main()


path: kd.py
content: #!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
快导(KD) - 短视频脚本批量生成与管理

使用方法:
    kd run --platform xiaohongshu              # 执行完整任务链
    kd step --platform xiaohongshu --step 6    # 执行单个子任务
    kd rules --platform xiaohongshu            # 更新平台规则
    kd config show                             # 查看配置
"""

import sys
import os
import argparse
from pathlib import Path

# Windows 编码修复 - 必须在所有导入之前
if sys.platform == 'win32':
    import io
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
    sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='replace')

# 添加scripts目录到路径
SCRIPT_DIR = Path(__file__).parent / "scripts"
sys.path.insert(0, str(SCRIPT_DIR))

from config_manager import ConfigManager
from script_generator import ScriptGenerator


def main():
    parser = argparse.ArgumentParser(
        description="快导(KD) - 短视频脚本批量生成与管理",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
示例:
    kd run --platform xiaohongshu                    # 执行完整任务链
    kd run --platform xiaohongshu --duration "2-3min" # 指定时长
    kd step --platform xiaohongshu --step 6          # 执行单个子任务
    kd rules --platform xiaohongshu                  # 更新平台规则
    kd config show                                   # 查看配置
    kd config validate                               # 验证配置
    kd config set-keywords --platform xiaohongshu --keywords "美食,探店"
    kd config set-external-keywords --keywords "food,cooking"
    kd config set copy_library_path "F:\\文案库\\"
    kd config set report_space_id "7627134963053235418"
        """
    )
    
    subparsers = parser.add_subparsers(dest="command", help="可用命令")
    
    # run 命令
    run_parser = subparsers.add_parser("run", help="执行完整任务链（10步）")
    run_parser.add_argument("--platform", required=True, 
                           choices=["xiaohongshu", "douyin", "shipinhao"],
                           help="目标平台")
    run_parser.add_argument("--duration", 
                           help="总时长（如：2-3min, 1min）")
    run_parser.add_argument("--count", type=int, default=5,
                           help="生成脚本数量（默认5）")
    
    # step 命令
    step_parser = subparsers.add_parser("step", help="执行单个子任务")
    step_parser.add_argument("--platform", required=True,
                            choices=["xiaohongshu", "douyin", "shipinhao"],
                            help="目标平台")
    step_parser.add_argument("--step", type=int, required=True,
                            choices=range(1, 11),
                            help="子任务编号（1-10）")
    
    # rules 命令
    rules_parser = subparsers.add_parser("rules", help="更新平台规则")
    rules_parser.add_argument("--platform", required=True,
                             choices=["xiaohongshu", "douyin", "shipinhao"],
                             help="目标平台")
    
    # config 命令
    config_parser = subparsers.add_parser("config", help="配置管理")
    config_subparsers = config_parser.add_subparsers(dest="config_cmd")
    
    # config show
    show_parser = config_subparsers.add_parser("show", help="查看配置")
    show_parser.add_argument("--platform",
                            choices=["xiaohongshu", "douyin", "shipinhao"],
                            help="指定平台")
    
    # config validate
    validate_parser = config_subparsers.add_parser("validate", help="验证配置")
    validate_parser.add_argument("--platform",
                                 choices=["xiaohongshu", "douyin", "shipinhao"],
                                 help="指定平台")
    
    # config set
    set_parser = config_subparsers.add_parser("set", help="设置配置项")
    set_parser.add_argument("key", help="配置键名")
    set_parser.add_argument("value", help="配置值")
    
    # config set-keywords
    keywords_parser = config_subparsers.add_parser("set-keywords", help="设置平台关键词")
    keywords_parser.add_argument("--platform", required=True,
                                choices=["xiaohongshu", "douyin", "shipinhao"],
                                help="目标平台")
    keywords_parser.add_argument("--keywords", required=True,
                                help="关键词列表（逗号分隔）")
    
    # config set-external-keywords
    ext_keywords_parser = config_subparsers.add_parser("set-external-keywords",
                                                         help="设置外网关键词")
    ext_keywords_parser.add_argument("--keywords", required=True,
                                    help="关键词列表（逗号分隔）")
    
    # refs 命令
    refs_parser = subparsers.add_parser("refs", help="文案库管理")
    refs_subparsers = refs_parser.add_subparsers(dest="refs_cmd")
    
    # refs show
    refs_show_parser = refs_subparsers.add_parser("show", help="查看文案库")
    refs_show_parser.add_argument("--platform", required=True,
                                 choices=["xiaohongshu", "douyin", "shipinhao"],
                                 help="目标平台")
    
    # setup 命令
    setup_parser = subparsers.add_parser("setup", help="安装和配置")
    setup_parser.add_argument("--check-deps", action="store_true",
                             help="检查依赖")
    setup_parser.add_argument("--install-deps", action="store_true",
                             help="安装依赖")
    
    args = parser.parse_args()
    
    if not args.command:
        parser.print_help()
        return 0
    
    # 处理命令
    if args.command == "run":
        return cmd_run(args)
    elif args.command == "step":
        return cmd_step(args)
    elif args.command == "rules":
        return cmd_rules(args)
    elif args.command == "config":
        return cmd_config(args)
    elif args.command == "refs":
        return cmd_refs(args)
    elif args.command == "setup":
        return cmd_setup(args)
    
    return 0


def cmd_run(args):
    """执行完整任务链"""
    print(f"🚀 启动快导系列任务")
    print(f"   平台: {args.platform}")
    if args.duration:
        print(f"   时长: {args.duration}")
    print(f"   脚本数: {args.count}")
    print()
    
    # TODO: 实现完整任务链
    print("⚠️  完整任务链执行功能开发中...")
    print("   当前可用: kd step --platform {} --step <编号>".format(args.platform))
    
    return 0


def cmd_step(args):
    """执行单个子任务"""
    print(f"🚀 执行子任务 {args.step}")
    print(f"   平台: {args.platform}")
    print()
    
    # TODO: 实现单个子任务执行
    step_names = {
        1: "搜索目标平台爆款",
        2: "读取平台规则",
        3: "搜索外网平台",
        4: "同质化检查",
        5: "格式检查",
        6: "生成脚本",
        7: "合理性检查",
        8: "更新文案库",
        9: "全面检查对比",
        10: "提交报告"
    }
    
    print(f"   任务: {step_names.get(args.step, '未知')}")
    print("⚠️  单个子任务执行功能开发中...")
    print("   当前可用Python API:")
    print("   from kd import ScriptGenerator")
    print("   gen = ScriptGenerator(platform='{}')".format(args.platform))
    
    return 0


def cmd_rules(args):
    """更新平台规则"""
    print(f"📝 更新平台规则")
    print(f"   平台: {args.platform}")
    print()
    
    # TODO: 实现规则更新
    print("⚠️  规则更新功能开发中...")
    print("   请手动编辑: references/platform_rules/{}_rules.md".format(args.platform))
    
    return 0


def cmd_config(args):
    """配置管理"""
    config = ConfigManager()
    
    if not hasattr(args, 'config_cmd') or not args.config_cmd:
        print("📋 配置管理")
        print()
        print("可用子命令:")
        print("   kd config show              查看配置")
        print("   kd config validate          验证配置")
        print("   kd config set <key> <val>   设置配置")
        print("   kd config set-keywords      设置平台关键词")
        print("   kd config set-external-keywords 设置外网关键词")
        return 0
    
    if args.config_cmd == "show":
        print("📋 当前配置")
        print()
        print(config.get_all())
        
    elif args.config_cmd == "validate":
        print("✅ 验证配置")
        print()
        # TODO: 实现配置验证
        print("⚠️  配置验证功能开发中...")
        
    elif args.config_cmd == "set":
        print(f"⚙️  设置配置: {args.key} = {args.value}")
        # TODO: 实现配置设置
        print("⚠️  配置设置功能开发中...")
        
    elif args.config_cmd == "set-keywords":
        keywords = [k.strip() for k in args.keywords.split(",")]
        print(f"⚙️  设置 {args.platform} 关键词: {keywords}")
        # TODO: 实现关键词设置
        print("⚠️  关键词设置功能开发中...")
        print("   请手动编辑: config/platforms.json")
        
    elif args.config_cmd == "set-external-keywords":
        keywords = [k.strip() for k in args.keywords.split(",")]
        print(f"⚙️  设置外网关键词: {keywords}")
        # TODO: 实现外网关键词设置
        print("⚠️  外网关键词设置功能开发中...")
        print("   请手动编辑: config/platforms.json")
    
    return 0


def cmd_refs(args):
    """文案库管理"""
    if not hasattr(args, 'refs_cmd') or not args.refs_cmd:
        print("📚 文案库管理")
        print()
        print("可用子命令:")
        print("   kd refs show --platform <平台>  查看文案库")
        return 0
    
    if args.refs_cmd == "show":
        print(f"📚 查看 {args.platform} 文案库")
        print()
        # TODO: 实现文案库查看
        print("⚠️  文案库查看功能开发中...")
    
    return 0


def cmd_setup(args):
    """安装和配置"""
    print("🔧 安装和配置")
    print()
    
    if args.check_deps:
        print("检查依赖...")
        # TODO: 实现依赖检查
        print("⚠️  依赖检查功能开发中...")
        
    elif args.install_deps:
        print("安装依赖...")
        # TODO: 实现依赖安装
        print("⚠️  依赖安装功能开发中...")
        print("   请手动安装: pip install openpyxl")
        
    else:
        print("首次使用配置指南:")
        print()
        print("1. 设置文案库路径:")
        print('   kd config set copy_library_path "F:\\vlog\\JT\\idea\\"')
        print()
        print("2. 设置飞书空间ID:")
        print("   kd config set report_space_id \"你的空间ID\"")
        print()
        print("3. 配置平台关键词:")
        print("   kd config set-keywords --platform xiaohongshu \\")
        print('     --keywords "美食,探店,农家菜,采摘"')
        print()
        print("4. 验证配置:")
        print("   kd config validate")
        print()
        print("5. 执行快导任务:")
        print("   kd run --platform xiaohongshu")
    
    return 0


if __name__ == "__main__":
    sys.exit(main())


path: prompts/README.md
content: # Prompts 目录说明

本目录存放快导(KD) Skill 10步流程的子任务提示词模板。

## 目录结构

```
prompts/
├── step1_search_trending.md      # 子任务1：搜索目标平台爆款
├── step2_read_rules.md            # 子任务2：读取平台规则
├── step3_search_external.md       # 子任务3：搜索外网平台
├── step4_check_duplicates.md      # 子任务4：同质化检查
├── step5_scan_format.md           # 子任务5：格式检查
├── step6_generate_scripts.md      # 子任务6：生成脚本
├── step7_validate_scripts.md      # 子任务7：合理性检查
├── step8_append_to_excel.md       # 子任务8：更新文案库
├── step9_verify_write.md          # 子任务9：全面检查对比
├── step10_generate_report.md      # 子任务10：提交报告
└── README.md                      # 本文件
```

## 文件命名规则

```
step{序号}_{任务简称}.md
```

**示例：**
- `step1_search_trending.md` - 子任务1，搜索爆款
- `step6_generate_scripts.md` - 子任务6，生成脚本

## 文件内容结构

每个提示词文件包含以下部分：

1. **任务目标** - 该子任务的目标说明
2. **输入变量** - 需要动态填充的数据（`{{变量名}}`）
3. **执行流程** - 该子任务的执行步骤
4. **输出格式** - 期望的输出结构和示例
5. **注意事项** - 执行时的关键点
6. **错误处理** - 异常情况的处理方式

## 使用方式

提示词文件由 `ScriptGenerator` 类动态读取和使用：

```python
from script_generator import ScriptGenerator

# 生成脚本时自动加载 step6_generate_scripts.md
generator = ScriptGenerator(platform="xiaohongshu")
prompt = generator.load_prompt("step6", {
    "platform": "xiaohongshu",
    "trending_titles": [...],
    "rules_summary": {...}
})
```

## 10步流程概览

| 步骤 | 名称 | 核心任务 | 输出 |
|:---:|:---|:---|:---|
| 1 | 搜索目标平台爆款 | 搜索并选定4个爆款 | 爆款列表+主题 |
| 2 | 读取平台规则 | 提取7项关键规则 | 规则摘要 |
| 3 | 搜索外网平台 | 搜索并选定1个外网爆款 | 外网爆款（可选）|
| 4 | 同质化检查 | 检查已有脚本，确定避开方向 | 需避开主题 |
| 5 | 格式检查 | 读取Excel实际格式 | 格式参数 |
| 6 | 生成脚本 | 生成4-5条差异化脚本 | 完整脚本 |
| 7 | 合理性检查 | 检查7项合理性，直接修改 | 检查清单+修改记录 |
| 8 | 更新文案库 | 脚本写入Excel | 写入确认 |
| 9 | 全面检查对比 | 验证格式、内容、位置 | 验证报告 |
| 10 | 提交报告 | 生成并保存执行报告 | Markdown报告 |

## 提示词变量规范

### 通用变量

| 变量名 | 说明 | 示例 |
|:---|:---|:---|
| `{{platform}}` | 平台英文标识 | xiaohongshu, douyin, shipinhao |
| `{{platform_name}}` | 平台中文名 | 小红书, 抖音, 视频号 |
| `{{task_date}}` | 任务日期 | 2026-04-22 |

### 子任务特定变量

每个提示词文件会定义自己的输入变量，详见各文件。

## 自定义提示词

您可以根据实际运营经验修改提示词：

```bash
# 编辑子任务6的提示词
nano prompts/step6_generate_scripts.md

# 编辑子任务7的提示词
nano prompts/step7_validate_scripts.md
```

**注意：** 修改提示词可能影响生成脚本的质量，建议先备份原文件。

## 版本管理

提示词文件版本与Skill版本一致：

| Skill版本 | 提示词版本 | 更新日期 |
|:---:|:---:|:---:|
| 1.0.0 | 1.0.0 | 2026-04-22 |

## 相关文件

- **配置：** `config/templates.json` - 提示词模板配置
- **脚本：** `scripts/script_generator.py` - 提示词加载器
- **流程：** `config/workflow.json` - 10步流程定义

## 常见问题

**Q: 提示词文件可以删除吗？**

A: 不建议删除，会导致对应子任务无法执行。可以修改内容，但不要删除文件。

**Q: 如何添加新的子任务提示词？**

A: 按照命名规则创建新文件（如 `step11_xxx.md`），并在 `config/workflow.json` 中添加对应步骤。

**Q: 提示词中的变量如何填充？**

A: 由 `ScriptGenerator` 类自动从子任务结果中提取并填充，无需手动处理。


path: prompts/step10_generate_report.md
content: # 子任务10：提交报告

## 任务目标
生成Markdown格式报告，包含每个子任务的关键输出和执行过程记录，保存到飞书文案库wiki。

## 输入变量

| 变量名 | 说明 | 来源 |
|:---|:---|:---|
| `{{task_date}}` | 任务执行日期 | 当前日期 |
| `{{platform}}` | 目标平台 | 子任务2 |
| `{{platform_name}}` | 平台中文名 | 配置 |
| `{{report_space_id}}` | 飞书空间ID | 用户配置 |
| `{{subtask_results}}` | 各子任务结果 | 子任务1-9 |
| `{{generated_scripts}}` | 生成的脚本列表 | 子任务7 |
| `{{write_positions}}` | 写入位置信息 | 子任务8 |

## 报告命名格式

```
{{task_date}}-快导-{{platform_name}}.md
```

**示例：**
- `2026-04-22-快导-小红书.md`
- `2026-04-22-快导-抖音.md`
- `2026-04-22-快导-视频号.md`

## 报告内容结构

```markdown
# 快导任务执行报告

## 基本信息
- **日期：** {{task_date}}
- **任务：** 快导系列
- **平台：** {{platform_name}} ({{platform}})
- **执行结果：** ✅ 成功 / ❌ 失败

---

## 各子任务关键输出

### 子任务1：搜索目标平台爆款
- **抽取的关键词：** [关键词1]、[关键词2]、[关键词3]
- **搜索1结果：** [爆款标题1（前20条中选取）]
- **搜索2结果：** [爆款标题2（前20条中选取）]
- **搜索3结果：** [爆款标题3（前20条中选取）]
- **最终选定4个爆款：** [主题1]、[主题2]、[主题3]、[主题4]

### 子任务2：读取平台规则
- **7项关键规则摘要：**
  - 时长要求：[内容]
  - 核心指标：[内容]
  - 引流限制：[内容]
  - 原创要求：[内容]
  - 互动率要求：[内容]
  - 违规红线：[内容]
  - 文案要求：[内容]

### 子任务3：搜索外网平台
- **抽取的关键词：** [关键词1]、[关键词2]、[关键词3]
- **搜索1结果：** [爆款标题1（前20条中选取）]
- **搜索2结果：** [爆款标题2（前20条中选取）]
- **搜索3结果：** [爆款标题3（前20条中选取）]
- **最终选定1个外网爆款：** [主题]
- **状态：** ✅ 已选定 / ➖ 无合适爆款（如取消）

### 子任务4：同质化检查
- **已有脚本数量：** [数量]
- **脚本详情：** [标题+主题列表]
- **需避开方向：** [方向1]、[方向2]...

### 子任务5：格式检查
- **实际格式参数：** [字体、颜色、边框等]
- **确认结果：** ✅ 已确认

### 子任务6：生成脚本
- **生成脚本数量：** [4条/5条]
- **脚本主题清单：**
  - 脚本1：[主题1] - 基于[爆款1]
  - 脚本2：[主题2] - 基于[爆款2]
  - 脚本3：[主题3] - 基于[爆款3]
  - 脚本4：[主题4] - 基于[爆款4]
  - 脚本5：[主题5] - 基于[外网爆款]（如适用）

### 子任务7：合理性检查
- **检查结果：** ✅ 通过 / ❌ 修改
- **修改记录：**
  - 脚本[X]：[修改内容]
  - ...

### 子任务8：更新文案库
- **写入脚本数量：** [4条/5条]
- **写入位置：**
  - 脚本1：第[X]行 - 第[Y]行
  - 脚本2：第[X]行 - 第[Y]行
  - ...
- **写入状态：** ✅ 成功

### 子任务9：全面检查对比
- **格式正确性：** ✅ 通过
- **内容完整性：** ✅ 通过
- **写入位置正确性：** ✅ 通过
- **整体结果：** ✅ 通过

---

## 执行过程记录

### 时间线
| 时间 | 事件 |
|:---:|:---|
| [开始时间] | 任务启动 |
| [时间1] | 子任务1完成 |
| [时间2] | 子任务2完成 |
| ... | ... |
| [结束时间] | 任务完成 |

### 遇到的问题
| 问题 | 解决方案 |
|:---|:---|
| [问题描述] | [如何解决] |

### 修改记录
| 位置 | 原内容 | 修改后 | 原因 |
|:---:|:---|:---|:---|
| [位置] | [原内容] | [新内容] | [原因] |

---

## 最终交付

### 生成脚本汇总

| 序号 | 主题 | Excel位置 | 状态 |
|:---:|:---|:---:|:---:|
| 1 | [主题1] | 第[X-Y]行 | ✅ 已写入 |
| 2 | [主题2] | 第[X-Y]行 | ✅ 已写入 |
| 3 | [主题3] | 第[X-Y]行 | ✅ 已写入 |
| 4 | [主题4] | 第[X-Y]行 | ✅ 已写入 |
| 5 | [主题5] | 第[X-Y]行 | ✅ 已写入/➖ 无 |

### 文件位置
- **文案库：** {{excel_path}}
- **本报告：** {{report_space_id}}/{{task_date}}-快导-{{platform_name}}.md

---

## 附录

### 平台配置快照
{{platform_config_json}}

### 规则摘要快照
{{rules_summary_json}}

### 生成脚本快照
{{generated_scripts_json}}
```

## 保存到飞书

### 命令

```bash
lark-cli docs +create \
  --title "{{task_date}}-快导-{{platform_name}}" \
  --wiki-space "{{report_space_id}}" \
  --markdown "[报告内容]" \
  --as user
```

### 保存位置

- **知识库：** 用户配置的 `report_space_id`
- **文档标题：** `YYYY-MM-DD-快导-平台名称`
- **文档格式：** Markdown

## 报告用途

1. **任务记录** - 完整记录本次执行过程
2. **问题追溯** - 出现问题时可查看历史执行
3. **经验积累** - 多次执行后分析优化点
4. **团队协作** - 分享给团队成员参考

## 注意事项

1. ✅ 包含**每个子任务**的关键输出
2. ✅ 记录**执行过程**（时间、问题、修改）
3. ✅ 保存到**飞书知识库**
4. ✅ 使用**标准命名格式**
5. ❌ 不要省略关键步骤的记录
6. ❌ 不要只记录成功，失败和问题也要记录

## 错误处理

```
如果 飞书保存失败:
    本地保存报告到：reports/{{task_date}}-快导-{{platform_name}}.md
    提示用户手动上传
    记录错误原因
    
如果 报告生成失败:
    输出简要执行摘要
    提示用户查看各子任务的单独输出
```

## 报告查看命令

```bash
# 查看最近报告
kd report list --limit 5

# 查看指定日期报告
kd report show --date {{task_date}} --platform {{platform}}

# 下载报告到本地
kd report download --date {{task_date}} --platform {{platform}} --output ./reports/
```


path: prompts/step1_search_trending.md
content: # 子任务1：搜索目标平台爆款

## 任务目标
从用户设置的关键词池中随机抽取3个，分别搜索目标平台的爆款内容，最终选定4个最优爆款作为脚本生成参考。

## 输入变量

| 变量名 | 说明 | 来源 | 如何设置 |
|:---|:---|:---|:---|
| `{{platform}}` | 目标平台名称 | 子任务参数 | 执行时传入，如：xiaohongshu |
| `{{platform_en}}` | 平台英文标识 | 子任务参数 | 执行时传入，如：xiaohongshu |
| `{{keywords_pool}}` | 用户设置的关键词池 | 用户配置 | `kd config set-keywords` 或编辑 platforms.json |
| `{{search_count}}` | 每个关键词搜索结果数 | 用户配置 | 默认20，可配置 |
| `{{select_count}}` | 最终选定爆款数 | 用户配置 | 默认4，可配置 |

## 变量设置说明

### 如何设置关键词池

**方式1：使用命令行**
```bash
kd config set-keywords --platform xiaohongshu --keywords "关键词1,关键词2,关键词3"
```

**方式2：直接编辑配置文件**
编辑 `config/platforms.json`：
```json
{
  "platforms": {
    "xiaohongshu": {
      "keywords": ["美食", "探店", "农家菜", "采摘"]
    }
  }
}
```

**方式3：在Python脚本中设置**
```python
from config_manager import ConfigManager
config = ConfigManager()
config.set_platform_keywords("xiaohongshu", ["美食", "探店", "农家菜"])
```

### 关键词池为空时的处理

**如果 `{{keywords_pool}}` 为空数组 `[]`：**
- ⚠️ 输出警告："关键词池为空，无法进行搜索"
- ❌ 终止子任务1
- 💡 提示用户先配置关键词池

**用户配置示例：**
```bash
# 配置小红书关键词池
kd config set-keywords --platform xiaohongshu \
  --keywords "美食,探店,农家菜,采摘,生活,乡村,慢生活,周末"
```

## 执行流程

1. 检查 `{{keywords_pool}}` 是否为空
2. 如为空，输出警告并终止
3. 从关键词池中**随机抽取3个**
4. 用"平台 + 关键词"分别搜索3次
5. 每个关键词取前 `{{search_count}}` 条结果（默认20）
6. 从结果中选取最优的 `{{select_count}}` 个爆款（默认4）
7. 记录最终选中的爆款

## 输出格式

```markdown
## 搜索结果

### 关键词池状态
- 平台：{{platform}}
- 关键词池：{{keywords_pool}}
- 状态：[✅ 已配置 / ❌ 为空]

### 抽取的关键词
关键词1、关键词2、关键词3

### 搜索1结果（关键词1）
| 排名 | 标题 | 播放量/互动量 | 选择理由 |
|:---:|:---|:---|:---|
| 1 | [标题] | [数据] | [原因] |
| 2 | [标题] | [数据] | |
| ... | ... | ... | |

### 搜索2结果（关键词2）
（同上格式）

### 搜索3结果（关键词3）
（同上格式）

## 最终选定的{{select_count}}个爆款
| 序号 | 标题 | 来源关键词 | 核心亮点 |
|:---:|:---|:---|:---|
| 1 | [爆款标题1] | [关键词] | [亮点] |
| 2 | [爆款标题2] | [关键词] | [亮点] |
| 3 | [爆款标题3] | [关键词] | [亮点] |
| 4 | [爆款标题4] | [关键词] | [亮点] |

## 主题提取
基于{{select_count}}个爆款，提取以下主题方向：
1. [主题1] - 基于[爆款标题]
2. [主题2] - 基于[爆款标题]
3. [主题3] - 基于[爆款标题]
4. [主题4] - 基于[爆款标题]
```

## 选择标准

| 维度 | 权重 | 说明 |
|:---|:---:|:---|
| 播放量/互动量 | 40% | 数据表现好 |
| 内容质量 | 30% | 制作精良、有创意 |
| 与品牌相关性 | 20% | 与嘉泰苑业务相关 |
| 可复制性 | 10% | 可借鉴但非抄袭 |

## 注意事项

1. ✅ **随机抽取**关键词，不固定顺序
2. ✅ 记录抽取过程，确保可追溯
3. ✅ 爆款选择需说明理由
4. ❌ 不要只选数据最高的，要综合考虑
5. ❌ 避免选择与已有脚本雷同的主题

## 使用示例

**场景1：关键词池已配置**

输入：
- platform: xiaohongshu
- keywords_pool: ["美食", "探店", "农家菜", "采摘", "生活", "乡村"]
- search_count: 20
- select_count: 4

输出：
```
## 搜索结果

### 关键词池状态
- 平台：xiaohongshu
- 关键词池：["美食", "探店", "农家菜", "采摘", "生活", "乡村"]
- 状态：✅ 已配置（6个关键词）

### 抽取的关键词
采摘、美食、乡村

搜索1结果（采摘）：
...

最终选定4个爆款：
...
```

**场景2：关键词池为空**

输出：
```
## 搜索结果

### 关键词池状态
- 平台：xiaohongshu
- 关键词池：[]
- 状态：❌ 为空

### 错误
⚠️ 关键词池为空，无法进行搜索

### 解决方法
请配置关键词池：
kd config set-keywords --platform xiaohongshu \
  --keywords "关键词1,关键词2,关键词3"
```


path: prompts/step2_read_rules.md
content: # 子任务2：读取平台规则

## 任务目标
读取目标平台运营规则文档，输出关键规则摘要（7项），用于指导脚本生成。

## 输入变量

| 变量名 | 说明 | 来源 | 如何设置 |
|:---|:---|:---|:---|
| `{{platform}}` | 目标平台名称 | 子任务参数 | 执行时传入，如：xiaohongshu |
| `{{platform_en}}` | 平台英文标识 | 子任务参数 | 执行时传入，如：xiaohongshu |
| `{{rules_file}}` | 规则文档路径 | 用户配置 | 默认：`references/platform_rules/{platform}_rules.md` |
| `{{rules_exists}}` | 规则文档是否存在 | 自动检测 | 系统自动检查文件是否存在 |

## 变量设置说明

### 如何设置规则文档

**方式1：使用命令行生成规则**
```bash
# 生成小红书规则
kd rules --platform xiaohongshu

# 生成抖音规则
kd rules --platform douyin

# 生成视频号规则
kd rules --platform shipinhao
```

**方式2：直接编辑规则文档**
```bash
nano references/platform_rules/xiaohongshu_rules.md
```

**方式3：在Python脚本中设置**
```python
from config_manager import ConfigManager
config = ConfigManager()
config.set_rules_path("references/platform_rules/")
```

### 规则文档不存在时的处理

**如果 `{{rules_exists}}` 为 false：**
- ⚠️ 输出警告："规则文档不存在，请先运行规则更新系列"
- ❌ 终止子任务2
- 💡 提示用户生成规则文档

**用户生成规则示例：**
```bash
kd rules --platform xiaohongshu
```

## 规则文档格式（用户自定义）

规则文档由用户自行定义，建议包含以下内容：

```markdown
# 小红书平台运营规则

## 平台基础信息
- 用户画像：女性、种草决策
- 内容风格：攻略型、图文结合
- 总时长：2-3分钟
- 分镜时长：6-12秒

## 7项关键规则

| 规则项 | 内容 |
|:---|:---|
| 时长要求 | 2-3分钟，单分镜6-12秒 |
| 核心指标 | 完播率>40%，互动率>5% |
| 引流限制 | 允许主页引流，禁止直接留微信 |
| 原创要求 | 原创占比≥60% |
| 互动率要求 | 冷启动需≥5% |
| 违规红线 | 虚假宣传、侵权内容 |
| 文案要求 | 攻略感强，可用表情符号 |
```

**注意：** 以上为示例格式，内容由用户根据实际运营经验填写

## 执行流程

1. 检查 `{{rules_file}}` 是否存在
2. 如不存在，输出警告并终止
3. 读取规则文档内容
4. 提取7项关键规则
5. 输出规则摘要

## 输出格式

```markdown
## 平台规则摘要

### 文档来源
- 平台：{{platform}}
- 规则文档：{{rules_file}}
- 文档存在：{{rules_exists}}
- 生成日期：[文档中的日期，如不存在则为空]
- 版本：[文档中的版本，如不存在则为空]

### 7项关键规则

| 规则项 | 内容 |
|:---|:---|
| **时长要求** | [从规则文档提取] |
| **核心指标** | [从规则文档提取] |
| **引流限制** | [从规则文档提取] |
| **原创要求** | [从规则文档提取] |
| **互动率要求** | [从规则文档提取] |
| **违规红线** | [从规则文档提取] |
| **文案要求** | [从规则文档提取] |

### 平台特殊限制

| 限制项 | 要求 |
|:---|:---|
| [从规则文档提取] | [说明] |

## 脚本生成指导

基于以上规则，脚本生成应注意：
1. [从规则文档提取注意事项]
2. ...
```

## 7项关键规则说明

由用户自行定义，通常包括：

1. **时长要求** - 总时长、单分镜时长、分镜数量
2. **核心指标** - 完播率、互动率标准、优先级排序
3. **引流限制** - 允许和禁止的引流方式
4. **原创要求** - 原创占比、内容重复判定
5. **互动率要求** - 冷启动标准、互动类型优先级
6. **违规红线** - 绝对禁止内容、谨慎处理内容
7. **文案要求** - 标题字数限制、正文风格、禁忌词汇

## 注意事项

1. ✅ 如规则文档不存在，必须提示用户先生成
2. ✅ 摘要要精炼，只保留关键信息
3. ✅ 特殊限制必须突出提示
4. ❌ 不要复制整个规则文档，只提取7项关键规则

## 使用示例

**场景1：规则文档已存在**

输入：
- platform: xiaohongshu
- rules_file: references/platform_rules/xiaohongshu_rules.md
- rules_exists: true

输出：
```markdown
## 平台规则摘要

### 文档来源
- 平台：xiaohongshu
- 规则文档：references/platform_rules/xiaohongshu_rules.md
- 文档存在：true
- 生成日期：2026-04-22
- 版本：v1.0.0

### 7项关键规则

| 规则项 | 内容 |
|:---|:---|
| 时长要求 | 2-3分钟，单分镜6-12秒 |
| 核心指标 | 完播率>40%，互动率>5% |
| 引流限制 | 允许主页引流，禁止直接留微信 |
| 原创要求 | 原创占比≥60% |
| 互动率要求 | 冷启动需≥5% |
| 违规红线 | 虚假宣传、侵权内容 |
| 文案要求 | 攻略感强，可用表情符号 |

### 平台特殊限制

| 限制项 | 要求 |
|:---|:---|
| 无特殊限制 | - |

## 脚本生成指导

基于以上规则，脚本生成应注意：
1. 时长控制在2-3分钟
2. 单分镜6-12秒
3. 攻略型内容优先
```

**场景2：规则文档不存在**

输出：
```
## 平台规则摘要

### 文档来源
- 平台：xiaohongshu
- 规则文档：references/platform_rules/xiaohongshu_rules.md
- 文档存在：false

### 错误
⚠️ 规则文档不存在，请先运行规则更新系列

### 解决方法
请生成规则文档：
kd rules --platform xiaohongshu

或手动创建：
nano references/platform_rules/xiaohongshu_rules.md
```


path: prompts/step3_search_external.md
content: # 子任务3：搜索外网平台

## 任务目标
从用户设置的外网关键词池中随机抽取3个，搜索TikTok/YouTube爆款，最终选定1个外网爆款作为创意参考。

## 输入变量

| 变量名 | 说明 | 来源 | 如何设置 |
|:---|:---|:---|:---|
| `{{platform}}` | 目标平台名称 | 子任务参数 | 执行时传入，如：xiaohongshu |
| `{{external_keywords_pool}}` | 用户设置的外网关键词池 | 用户配置 | `kd config set-external-keywords` 或编辑配置文件 |
| `{{search_count}}` | 每个关键词搜索结果数 | 用户配置 | 默认20，可配置 |
| `{{select_count}}` | 最终选定爆款数 | 用户配置 | 默认1，可配置 |

## 变量设置说明

### 如何设置外网关键词池

**方式1：使用命令行**
```bash
kd config set-external-keywords --keywords "关键词1,关键词2,关键词3"
```

**方式2：直接编辑配置文件**
编辑 `config/platforms.json` 或用户配置文件：
```json
{
  "external_keywords": ["food", "cooking", "life", "vlog", "story"]
}
```

**方式3：在Python脚本中设置**
```python
from config_manager import ConfigManager
config = ConfigManager()
config.set_external_keywords(["food", "cooking", "life", "vlog", "story"])
```

### 外网关键词池为空时的处理

**如果 `{{external_keywords_pool}}` 为空数组 `[]`：**
- ⚠️ 输出提示："外网关键词池为空，跳过外网搜索"
- ⏭️ 直接跳到子任务4（不终止任务）
- 💡 提示用户可配置外网关键词（可选）

**注意：** 外网搜索是可选步骤，即使为空也不影响主流程

**用户配置示例（可选）：**
```bash
# 配置外网关键词池（可选）
kd config set-external-keywords \
  --keywords "food,cooking,life,vlog,story,family,memory"
```

## 执行流程

1. 检查 `{{external_keywords_pool}}` 是否为空
2. 如为空，输出提示并跳到子任务4
3. 从外网关键词池中**随机抽取3个**
4. 用"TikTok/YouTube + 关键词"分别搜索3次
5. 每个关键词取前 `{{search_count}}` 条结果（默认20）
6. 从结果中选取最优的 `{{select_count}}` 个爆款（默认1）
7. 记录最终选中的外网爆款

## 输出格式

```markdown
## 外网搜索结果

### 关键词池状态
- 外网关键词池：{{external_keywords_pool}}
- 状态：[✅ 已配置 / ➖ 为空]

### 抽取的关键词（如已配置）
关键词1、关键词2、关键词3

### 搜索1结果（TikTok - 关键词1）
| 排名 | 标题 | 播放量 | 创意亮点 |
|:---:|:---|:---:|:---|
| 1 | [标题] | [数据] | [亮点] |
| 2 | [标题] | [数据] | |
| ... | ... | ... | |

### 搜索2结果（YouTube - 关键词2）
（同上格式）

### 搜索3结果（TikTok - 关键词3）
（同上格式）

## 最终选定的{{select_count}}个外网爆款（如已配置）
| 平台 | 标题 | 关键词 | 创意亮点 | 可借鉴点 |
|:---|:---|:---|:---|:---|
| TikTok/YouTube | [爆款标题] | [关键词] | [亮点] | [借鉴思路] |

## 创意提取（如已配置）
基于外网爆款，提取以下创意元素：
- 叙事结构: [结构类型]
- 视觉风格: [风格描述]
- 情绪节奏: [节奏特点]
- 可本土化适配: [适配建议]
```

## 选择标准

| 维度 | 权重 | 说明 |
|:---|:---:|:---|
| 创意新颖度 | 40% | 创意独特、有启发性 |
| 制作水准 | 30% | 拍摄、剪辑精良 |
| 情感共鸣 | 20% | 有情感感染力 |
| 可本土化 | 10% | 可适配到国内平台 |

## 注意事项

1. ✅ **随机抽取**关键词，不固定顺序
2. ✅ 重点关注创意和叙事手法，非直接搬运
3. ✅ 记录可本土化的创意点
4. ❌ 如无合适爆款可选，可取消本次外网搜索
5. ❌ 避免选择与目标平台风格差异过大的内容

## 使用示例

**场景1：外网关键词池已配置**

输入：
- platform: xiaohongshu
- external_keywords_pool: ["food", "cooking", "life", "vlog", "story"]
- search_count: 20
- select_count: 1

输出：
```markdown
## 外网搜索结果

### 关键词池状态
- 外网关键词池：["food", "cooking", "life", "vlog", "story"]
- 状态：✅ 已配置（5个关键词）

### 抽取的关键词
life, vlog, story

搜索1结果（TikTok - life）:
...

最终选定1个外网爆款：
- 平台: TikTok
- 标题: 「A day in my countryside life」
- 关键词: life
- 创意亮点: 乡村慢生活vlog风格
- 可借鉴点: 可本土化为嘉泰苑慢生活场景

创意提取：
- 叙事结构: 一天时间线叙事
- 视觉风格: 自然光、暖色调
- 情绪节奏: 舒缓、放松
- 可本土化适配: 嘉泰苑的一天（采摘+就餐+休闲）
```

**场景2：外网关键词池为空**

输出：
```markdown
## 外网搜索结果

### 关键词池状态
- 外网关键词池：[]
- 状态：➖ 为空（跳过此步骤）

### 提示
⏭️ 外网关键词池为空，跳过外网搜索

### 可选配置
如需启用外网搜索，可配置关键词池：
kd config set-external-keywords \
  --keywords "food,cooking,life,vlog,story"

### 后续流程
直接跳转到子任务4：同质化检查
```


path: prompts/step4_check_duplicates.md
content: # 子任务4：同质化检查

## 任务目标
读取现有文案库，输出已有脚本详情，确定需避开的主题方向，避免生成重复或雷同的脚本。

## 输入变量

| 变量名 | 说明 | 示例 |
|:---|:---|:---|
| `{{platform}}` | 目标平台名称 | 小红书、抖音、视频号 |
| `{{excel_path}}` | 文案库Excel路径 | [用户配置的路径] |
| `{{sheet_name}}` | 工作表名称 | 文案库 |

## 执行流程

1. 读取文案库Excel文件
2. 提取所有已有脚本的标题和主题
3. 分析主题分布
4. 确定需避开的方向
5. 输出同质化检查报告

## 输出格式

```markdown
## 同质化检查报告

### 已有脚本统计
| 项目 | 数值 |
|:---|:---:|
| 总脚本数 | {{total_scripts}} |
| 本月新增 | {{monthly_new}} |
| 待使用脚本 | {{pending_scripts}} |
| 已使用脚本 | {{used_scripts}} |

### 已有脚本列表

| 序号 | 标题 | 主题 | 状态 | 发布日期 |
|:---:|:---|:---|:---:|:---:|
| 1 | [脚本标题1] | [主题1] | 待使用/已使用 | 2026-04-15 |
| 2 | [脚本标题2] | [主题2] | 待使用/已使用 | 2026-04-10 |
| ... | ... | ... | ... | ... |

### 主题分布分析

| 主题类别 | 脚本数量 | 占比 | 趋势 |
|:---|:---:|:---:|:---:|
| [主题类别1] | [数量] | [百分比] | 饱和/正常/稀少 |
| [主题类别2] | [数量] | [百分比] | 饱和/正常/稀少 |
| ... | ... | ... | ... |

### 需避开的主题方向

以下主题已有多条脚本，建议避开：

| 主题 | 已有脚本数 | 建议 |
|:---|:---:|:---|
| [主题1] | [数量] | ⚠️ 饱和，建议避开 |
| [主题2] | [数量] | ⚠️ 饱和，建议避开 |
| [主题3] | [数量] | ⚠️ 相似度高，建议避开 |

### 推荐的主题方向

以下主题暂无或较少，可优先考虑：

| 主题 | 当前数量 | 建议 |
|:---|:---:|:---|
| [主题A] | 0 | ✅ 空白，可优先 |
| [主题B] | 1 | ✅ 较少，可考虑 |
| [主题C] | 2 | ✅ 适中，可补充 |

### 差异化建议

基于子任务1和3确定的爆款主题，建议：

1. **爆款主题**: [主题1]
   - 已有脚本: [数量]
   - 差异化方向: [具体建议]

2. **爆款主题**: [主题2]
   - 已有脚本: [数量]
   - 差异化方向: [具体建议]

3. **外网爆款**: [主题]
   - 本土化方向: [具体建议]

## 主题判定标准

### 饱和判定
- 同一主题 ≥ 3条脚本 → 饱和，建议避开
- 相似主题 ≥ 5条脚本 → 饱和，建议避开

### 相似度判定
- 标题相似度 ≥ 70% → 视为相似
- 核心场景/人物相同 → 视为相似

## 注意事项

1. ✅ 使用Python openpyxl读取，禁止凭记忆
2. ✅ 只读取A列（标题）和主题列
3. ✅ 相似度判定要客观
4. ❌ 不要因1-2条相似就判定为饱和
5. ❌ 避免过度避开的导致主题单一

## 错误处理

```
如果 Excel文件不存在:
    输出: "⚠️ 文案库不存在，路径: {{excel_path}}"
    输出: "请确认路径配置正确：kd config set copy_library_path "你的路径""
    终止任务（可选继续，但提示风险）

如果 文案库为空:
    输出: "✅ 文案库为空，无同质化风险"
    继续执行
```


path: prompts/step5_scan_format.md
content: # 子任务5：格式检查

## 任务目标
现场读取Excel实际格式，记录实际格式参数，输出格式确认清单，确保后续写入格式正确。

## 输入变量

| 变量名 | 说明 | 示例 |
|:---|:---|:---|
| `{{platform}}` | 目标平台名称 | 小红书、抖音、视频号 |
| `{{excel_path}}` | 文案库Excel路径 | [用户配置的路径] |
| `{{sheet_name}}` | 工作表名称 | 文案库 |

## 执行流程

1. 使用Python openpyxl读取Excel文件
2. 扫描标题行格式（字体、颜色、边框等）
3. 扫描数据行格式（A列、B-H列、I-N列）
4. 记录合并单元格规则
5. 输出格式确认清单

## 输出格式

```markdown
## 格式检查报告

### 基本信息
| 项目 | 数值 |
|:---|:---:|
| 文件路径 | {{excel_path}} |
| 工作表名 | {{sheet_name}} |
| 总行数 | {{total_rows}} |
| 总列数 | {{total_columns}} |
| 标题行 | 第1行 |
| 数据起始行 | 第2行 |

### 标题行格式（第1行）

| 参数 | 实际值 |
|:---|:---|
| 字体 | [微软雅黑/宋体/etc] |
| 字号 | [14/12/etc] |
| 粗体 | [是/否] |
| 字体颜色 | [RGB值] |
| 填充类型 | [solid/pattern] |
| 填充颜色 | [RGB值] |
| 水平对齐 | [center/left/right] |
| 垂直对齐 | [center/top/bottom] |
| 自动换行 | [True/False] |
| 边框 | [thin/medium/none] |
| 行高 | [20.4/etc] |

### 数据行A列格式（视频文案列）

| 参数 | 实际值 |
|:---|:---|
| 字体 | [宋体/etc] |
| 字号 | [11/etc] |
| 粗体 | [是/否] |
| 填充类型 | [solid/none] |
| 填充颜色 | [RGB值] |
| 水平对齐 | [left/center/right] |
| 垂直对齐 | [center/top/bottom] |
| 自动换行 | [True/False] |
| 边框 | [thin/etc] |
| 行高 | [49.95/etc] |
| 合并规则 | [跨行合并/不合并] |

### 数据行B-H列格式（分镜详情列）

| 参数 | 实际值 |
|:---|:---|
| 字体 | [宋体/etc] |
| 字号 | [11/etc] |
| 粗体 | [是/否] |
| 填充类型 | [solid/none] |
| 填充颜色 | [RGB值/无] |
| 水平对齐 | [left/center/right] |
| 垂直对齐 | [center/top/bottom] |
| 自动换行 | [True/False] |
| 边框 | [thin/etc] |
| 行高 | [49.95/etc] |
| 合并规则 | [每行独立/跨行合并] |

### 数据行I-N列格式（BGM等列）

| 参数 | 实际值 |
|:---|:---|
| 字体 | [宋体/etc] |
| 字号 | [11/etc] |
| 粗体 | [是/否] |
| 填充类型 | [solid/none] |
| 填充颜色 | [RGB值/无] |
| 水平对齐 | [left/center/right] |
| 垂直对齐 | [center/top/bottom] |
| 自动换行 | [True/False] |
| 边框 | [thin/etc] |
| 行高 | [49.95/etc] |
| 合并规则 | [跨行合并/不合并] |

### 合并单元格规则

| 列范围 | 合并方式 | 说明 |
|:---|:---|:---|
| A列 (1) | [跨行合并/不合并] | 视频文案列 |
| B-H列 (2-8) | [每行独立] | 分镜详情列 |
| I-N列 (9-14) | [跨行合并/不合并] | BGM等列 |

### 格式确认清单

| 检查项 | 结果 | 说明 |
|:---:|:---:|:---|
| 标题行格式确认 | ✅/❌ | [说明] |
| 数据行A列格式确认 | ✅/❌ | [说明] |
| 数据行B-H列格式确认 | ✅/❌ | [说明] |
| 数据行I-N列格式确认 | ✅/❌ | [说明] |
| 合并单元格规则确认 | ✅/❌ | [说明] |
| **整体格式确认** | ✅/❌ | [说明] |

## 完整格式参数（用于子任务6）

```python
format_params = {
    "header_row": {
        "font": "[字体]",
        "size": [字号],
        "bold": [True/False],
        "font_color": "[RGB]",
        "fill_type": "[类型]",
        "fill_color": "[RGB]",
        "align_horizontal": "[对齐]",
        "align_vertical": "[对齐]",
        "wrap_text": [True/False],
        "border": "[样式]",
        "row_height": [高度]
    },
    "data_row_A": { ... },
    "data_row_B_H": { ... },
    "data_row_I_N": { ... },
    "merge_rules": {
        "A": [True/False],
        "B_H": [False],
        "I_N": [True/False]
    }
}
```

## 注意事项

1. ✅ **必须现场读取**，禁止凭记忆
2. ✅ 记录每个细节（行高、对齐、边框等）
3. ✅ 确认合并单元格的实际规则
4. ❌ 不要假设格式与标准一致
5. ❌ 不要省略任何格式参数

## 常见格式差异

| 项 | 可能差异 | 处理方式 |
|:---|:---|:---|
| 字体 | 微软雅黑/宋体 | 记录实际值 |
| 字号 | 10/11/12 | 记录实际值 |
| 颜色 | RGB值差异 | 记录实际RGB |
| 合并 | 跨1行/多行 | 现场确认 |

## 错误处理

```
如果 Excel文件不存在:
    输出: "⚠️ Excel文件不存在: {{excel_path}}"
    终止任务

如果 格式读取失败:
    输出: "⚠️ 格式读取失败: [错误详情]"
    尝试使用默认格式（提示风险）
```


path: prompts/step6_generate_scripts.md
content: # 子任务6：生成脚本

## 任务目标
基于子任务1和3确定的主题，基于子任务2的规则，生成差异化的短视频脚本。

## 输入变量

| 变量名 | 说明 | 来源 |
|:---|:---|:---|
| `{{platform}}` | 目标平台 | 子任务2 |
| `{{platform_config}}` | 平台配置 | config/platforms.json |
| `{{trending_titles}}` | 4个爆款标题 | 子任务1 |
| `{{external_title}}` | 1个外网爆款 | 子任务3 |
| `{{rules_summary}}` | 7项关键规则 | 子任务2 |
| `{{avoid_themes}}` | 需避开主题 | 子任务4 |
| `{{format_params}}` | Excel格式参数 | 子任务5 |
| `{{count}}` | 生成脚本数 | 平台配置（4-5条） |

## 生成要求

### 数量要求
- 基于子任务1的4个爆款 → 生成**4条脚本**（不同主题）
- 基于子任务3的1个外网爆款 → 生成**1条脚本**（如无则只生成4条）
- **总计：4条或5条脚本**

### 差异化要求
**5条脚本必须差异化**，包括但不限于：
- 不同主题方向
- 不同叙事角度
- 不同场景设置
- 不同情感基调
- 不同目标受众

## 提示词模板

```
【角色设定】(Role)
你是一位拥有5年经验的资深短视频编导，擅长{{platform}}平台内容创作。

【任务目标】(Task)
请为我撰写{{count}}份关于[主题]的短视频完整脚本。

【输入来源】
- 主题来源：{{trending_titles}}（4个）+ {{external_title}}（1个）
- 平台规则：{{rules_summary}}
- 需避开：{{avoid_themes}}
- 平台配置：{{platform_config}}

【核心要素】
- 目标平台：{{platform}}
- 视频时长：{{platform_config.duration.total}}
- 分镜数量：{{platform_config.duration.segments_count}}
- 单分镜时长：{{platform_config.duration.segment}}

【时长匹配要求】（系统自动处理）

### 时间段标注（系统自动计算）

**默认行为：系统自动计算并调整时间段**

生成脚本时，系统会：
1. 根据台词字数计算台词时长（0.25秒/字）
2. 根据运镜方式计算运镜时长（固定2秒、推拉3秒、摇移4秒、复杂6秒、航拍8秒）
3. 取最大值 + 1秒缓冲 = 建议时长
4. **自动更新时间段为建议时长**（累加计算：0-Xs, X-Ys, Y-Zs...）

**用户操作：**
- ✅ 无需手动计算，系统自动优化
- ✅ 生成的B列时间段仅作为初始参考
- ⚠️ 如需关闭自动调整，见SKILL.md配置说明

### 平台时长标准

| 平台 | 总时长 | 分镜数 | 分镜时长范围 | 说明 |
|:---|:---:|:---:|:---:|:---|
| 抖音 | 45-60秒 | 12个 | 3-8秒 | 节奏快，切换频繁 |
| 小红书 | 120-180秒 | 18个 | 6-12秒 | 内容详细，时长较长 |
| 视频号 | 60-180秒 | 15个 | 5-10秒 | 叙事性强，节奏适中 |

### 分镜时长分配模式

遵循"开头快、中间稳、结尾慢"原则：
- **开场**（前20%分镜）：短时长，快速切入
- **主体**（中间60%分镜）：标准时长，内容展开
- **结尾**（后20%分镜）：稍长，升华收尾

**提示：** 系统会自动计算并调整(auto_adjust)，无需手动控制时间段。如需关闭自动调整，在 platforms.json 中设置 `"auto_adjust": false`。

【脚本要求】
1. 数量：{{count}}条
2. 关系：{{count}}条脚本必须差异化
3. 差异化维度：主题、角度、场景、情感、受众
4. 避开：{{avoid_themes}}
5. 符合：{{rules_summary}}

【结构与约束】
- 结构框架：黄金3秒钩子 → 痛点引入 → 核心内容 → 互动引导
- 内容约束：
  * 禁用"首先、其次、因此"等书面连接词
  * 必须包含一个反常识观点或冲突
  * 标题符合{{platform_config.title_rules}}
  * 避开{{avoid_themes}}
  * 符合{{rules_summary.违规红线}}

【输出格式】
按照{{format_params}}输出14列，每条脚本包含{{platform_config.duration.segments_count}}个分镜：

列A - 视频文案：
标题：[符合平台规则的标题]
故事：[200字以上的完整故事，起承转合]
标签：[#标签1 #标签2 #标签3]

【分镜内容详细格式】(必须遵守)

**C列-镜头描述**（最少{{platform_config.content_requirements.columns.C.min_chars}}字）：
- 设备/焦段/内容    （如：索尼A7M4 / 24-70mm / 果园全景）
- 示例：大疆Air3航拍 / 4K 30fps / 俯瞰太平镇枇杷园全貌，展现整片金黄

**D列-运镜描述**（最少{{platform_config.content_requirements.columns.D.min_chars}}字）：
- 方式/轨迹/速度    （如：向前推进 / 直线 / 缓慢）
- 示例：环绕跟拍 / 弧线 / 中速，跟随采摘动作360度展示

**E列-拍摄技巧**（最少{{platform_config.content_requirements.columns.E.min_chars}}字）：
- 光线/ISO/对焦/色调（如：自然光 / ISO100 / 自动对焦 / 暖色调）
- 示例：侧逆光+反光板补光 / ISO200 / 人脸追踪对焦 / 高饱和度暖黄

**F列-画面描述**（最少{{platform_config.content_requirements.columns.F.min_chars}}字）：
- 场景/构图/色彩/氛围（如：枇杷树下 / 三分法构图 / 金黄翠绿 / 温馨田园）
- 示例：木质凉亭内 / 对角线构图 / 暖黄灯光+深绿背景 / 家庭聚餐温馨感

**G列-台词**（最少{{platform_config.content_requirements.columns.G.min_chars}}字）：
- 要求：口语化、真实感、无书面语
- 禁忌：❌"首先、其次、综上所述" → ✅"先、再说、所以说"

**H列-音效**（最少{{platform_config.content_requirements.columns.H.min_chars}}字）：
- 环境音/音乐/节奏  （如：鸟鸣虫叫 / 轻快吉他 / 跟随画面节奏）
- 示例：风吹树叶沙沙声+远处狗吠 / 民谣风格 / 渐强后淡出

**I列-BGM**（必须详细）：
- 格式：音乐名：XXX，风格：XXX，使用时机：XXX
- 示例：
  * 音乐名：《稻香》周杰伦
  * 风格：田园治愈、轻快温暖
  * 使用时机：0-30秒前奏铺垫，30-60秒主歌展开，60-90秒副歌高潮

**L列-关联活动**（自动匹配或默认）：
- 系统会根据脚本主题自动匹配活动配置
- 如无匹配："日常推广"
- 如未配置活动："日常推广，当前未设置activities"

列I-N（跨行合并）：
I-BGM：[推荐音乐名称、风格、卡点位置]
J-标签：[#话题标签，附选择理由]
K-状态：待使用
L-活动：[关联活动（如有）]
M-日期：[计划发布日期]
N-备注：[拍摄注意事项、替代方案等]

【质量检查】(Quality Check)
生成后自检以下项：
- [ ] 标题是否符合平台限制
- [ ] 时长是否控制在规定范围
- [ ] 台词是否口语化（非书面化）
- [ ] B-C列时间段与镜头是否设计合理
- [ ] 内容是否与已有脚本不重复
- [ ] {{count}}条脚本是否差异化
```

## 输出格式

```markdown
## 脚本生成报告

### 生成概览
| 项目 | 数值 |
|:---|:---:|
| 生成脚本数 | {{count}} |
| 平台 | {{platform}} |
| 总时长 | {{platform_config.duration.total}} |
| 分镜数/脚本 | {{platform_config.duration.segments_count}} |

### 脚本列表

#### 脚本1：[主题]
**主题来源：** [来源爆款标题]
**差异化点：** [与其他的区别]

| 列 | 内容 |
|:---|:---|
| A-视频文案 | [标题]\n[故事]\n[标签] |
| B-时间段 | 0-{{duration1}}秒 |
| C-镜头 | [详细描述] |
| D-运镜 | [详细描述] |
| E-拍摄技巧 | [详细描述] |
| F-画面 | [详细描述] |
| G-台词 | [口语化台词] |
| H-音效 | [音效描述] |
| I-BGM | [音乐信息] |
| J-标签 | #标签 |
| K-状态 | 待使用 |
| L-活动 | [活动] |
| M-日期 | [日期] |
| N-备注 | [备注] |

... 分镜2、3、...、{{platform_config.duration.segments_count}} ...

#### 脚本2：[主题]
...

#### 脚本3：[主题]
...

#### 脚本4：[主题]
...

#### 脚本5：[主题]（如适用）
...

### 差异化说明

| 脚本 | 主题 | 角度 | 场景 | 情感 | 受众 |
|:---:|:---|:---|:---|:---|:---|
| 1 | [主题1] | [角度1] | [场景1] | [情感1] | [受众1] |
| 2 | [主题2] | [角度2] | [场景2] | [情感2] | [受众2] |
| ... | ... | ... | ... | ... | ... |

### 与爆款的关系

| 脚本 | 参考爆款 | 创新点 |
|:---:|:---|:---|
| 1 | [爆款1] | [创新说明] |
| 2 | [爆款2] | [创新说明] |
| ... | ... | ... |
```

## 注意事项

1. ✅ **必须差异化**，不能只是改标题
2. ✅ 基于平台规则设计内容
3. ✅ B-C列时间段与镜头必须合理匹配
4. ✅ 每个分镜内容必须丰富详细
5. ❌ 禁止使用书面连接词
6. ❌ 避开已饱和的主题

## 特殊平台要求

### 视频号（重要）
- **标题 ≤ 16字**（硬性限制）
- **标题不能含标点**（硬性限制）
- 示例：「樱桃园里吃到饱这口甜等了一年」（12字）✅

## 错误处理

```
如果 生成脚本数 ≠ {{count}}:
    补充生成缺失的脚本
    
如果 某条脚本不符合规则:
    重新生成该条脚本
    
如果 差异化检查未通过:
    修改脚本，确保差异化
```


path: prompts/step7_validate_scripts.md
content: # 子任务7：合理性检查

## 任务目标
对子任务6生成的5条（或4条）脚本进行批量检查，检查7项合理性，输出检查清单，直接修改不合理项。

## 输入变量

| 变量名 | 说明 | 来源 |
|:---|:---|:---|
| `{{scripts}}` | 生成的脚本列表 | 子任务6 |
| `{{count}}` | 脚本数量 | 4或5 |
| `{{platform}}` | 目标平台 | 子任务2 |
| `{{rules_summary}}` | 平台规则摘要 | 子任务2 |
| `{{format_params}}` | Excel格式参数 | 子任务5 |

## 检查维度（7项）

| 检查项 | 检查内容 | 权重 |
|:---|:---|:---:|
| **时间合理性** | 时间段分配是否合理，总时长是否符合 | 20% |
| **内容合理性** | 内容是否连贯，逻辑是否通顺 | 15% |
| **场景合理性** | 场景是否真实可拍（嘉泰苑实际场景） | 15% |
| **台词合理性** | 台词是否口语化，是否符合人设 | 15% |
| **时长合理性** | 总时长是否在规则范围内 | 15% |
| **标题合理性** | 标题是否符合平台限制（视频号16字） | 10% |
| **格式合理性** | 14列内容是否完整，格式是否正确 | 10% |

## 检查细则

### 1. 时间合理性

**检查点：**
- 时间段是否连续无重叠
- 总时长是否符合平台要求
- 单分镜时长是否在允许范围

**标准：**
- 小红书：6-12秒/分镜
- 抖音：3-5秒/分镜
- 视频号：5-10秒/分镜

### 2. 内容合理性

**检查点：**
- 故事是否有起承转合
- 分镜之间是否连贯
- 是否存在逻辑漏洞

**标准：**
- 故事完整，≥200字
- 逻辑通顺，无跳跃
- 有情感递进

### 3. 场景合理性

**检查点：**
- 场景是否在嘉泰苑存在
- 场景是否可实际拍摄
- 画面描述是否可实现

**嘉泰苑实际场景：**
- 8亩枇杷园
- 5亩樱桃园
- 3亩葡萄园
- 4亩桃园
- 6个包间（含2个高档包间）
- 麻将、赏花、萌宠区域

### 4. 台词合理性

**检查点：**
- 是否口语化（非书面语）
- 是否符合人设
- 字数是否达标

**禁忌词汇：**
- ❌ "首先"、"其次"、"因此"、"综上所述"
- ❌ 过于书面化的表达
- ❌ 过于生硬的转折

### 5. 时长合理性

**检查点：**
- 总时长是否在范围内
- 各分镜时长分配是否合理

**标准：**
- 小红书：2-3分钟
- 抖音：≤1分钟
- 视频号：1-3分钟

### 6. 标题合理性

**检查点（视频号特别重要）：**
- 字数是否符合限制
- 是否包含标点（视频号禁止）
- 是否吸睛、有吸引力

**限制：**
- 视频号：≤16字，无标点
- 小红书：建议≤20字
- 抖音：建议≤15字

### 7. 格式合理性

**检查点：**
- 14列是否都有数据
- 合并单元格规则是否正确
- 格式参数是否符合

## 输出格式

```markdown
## 合理性检查报告

### 检查概览
| 项目 | 数值 |
|:---|:---:|
| 检查脚本数 | {{count}} |
| 通过脚本数 | [数量] |
| 需修改脚本数 | [数量] |
| 整体结果 | ✅通过/❌需修改 |

### 详细检查结果

| 脚本 | 时间 | 内容 | 场景 | 台词 | 时长 | 标题 | 格式 | 结果 | 修改说明 |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---|
| 脚本1 | ✅/❌ | ✅/❌ | ✅/❌ | ✅/❌ | ✅/❌ | ✅/❌ | ✅/❌ | 通过/不通过 | [修改内容] |
| 脚本2 | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 脚本3 | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 脚本4 | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 脚本5 | ... | ... | ... | ... | ... | ... | ... | ... | ... |

### 问题汇总

#### 脚本[X]问题
| 检查项 | 问题描述 | 修改方案 | 修改后状态 |
|:---|:---|:---|:---:|
| [检查项] | [具体问题] | [如何修改] | ✅已修改 |

### 修改记录

#### 脚本1修改
**原问题：** [问题描述]
**修改内容：** [具体修改]
**修改后：** [修改后的内容]

#### 脚本2修改
...

### 最终脚本确认

| 脚本 | 主题 | 状态 | 备注 |
|:---:|:---|:---:|:---|
| 1 | [主题1] | ✅通过 | - |
| 2 | [主题2] | ✅通过 | [如有修改说明] |
| ... | ... | ... | ... |

### 与提示词模板【质量检查】的关系

- 【质量检查】= 生成时的自检（提示词内）
- 【合理性检查】= 生成后的复核（本子任务）
```

## 处理方式

```
发现不合理项 → 直接修改脚本 → 重新检查 → 记录修改
```

**修改原则：**
1. 小问题（格式、错别字）：直接修改
2. 中问题（时间、台词）：修改后标注
3. 大问题（主题、场景）：评估后决定是否重写

## 注意事项

1. ✅ 对5条（或4条）脚本**批量检查**
2. ✅ 检查7项**全部维度**
3. ✅ 发现不合理**直接修改**，不等待
4. ✅ 在"修改说明"列记录修改内容
5. ❌ 不要只检查不修改
6. ❌ 不要跳过任何一条脚本

## 错误处理

```
如果 某条脚本问题严重（如场景完全不存在）:
    标记为"需重写"
    提示用户决定是否继续
    
如果 多条脚本存在同类问题:
    批量修改
    记录共性问题
```


path: prompts/step8_append_to_excel.md
content: # 子任务8：更新文案库

## 任务目标
将子任务7检查通过的脚本写入文案库Excel。如果文案库不存在，按照示例格式创建。

## 输入变量

| 变量名 | 说明 | 来源 | 如何设置 |
|:---|:---|:---|:---|
| `{{scripts}}` | 检查通过的脚本列表 | 子任务7 | 上一步输出 |
| `{{count}}` | 脚本数量 | 子任务7 | 4或5 |
| `{{platform}}` | 目标平台 | 子任务2 | 执行时传入 |
| `{{excel_path}}` | 文案库Excel路径 | 用户配置 | `kd config set copy_library_path` |
| `{{format_params}}` | Excel格式参数 | 子任务5 | 现场扫描获取 |

## 变量设置说明

### 如何设置文案库路径

**方式1：使用命令行**
```bash
kd config set copy_library_path "F:\\vlog\\JT\\idea\\xiaohongshu_scripts.xlsx"
```

**方式2：直接编辑配置文件**
编辑 `config/user_config.json`：
```json
{
  "copy_library_path": "F:\\vlog\\JT\\idea\\xiaohongshu_scripts.xlsx"
}
```

**方式3：在Python脚本中设置**
```python
from config_manager import ConfigManager
config = ConfigManager()
config.set_copy_library_path("F:\\vlog\\JT\\idea\\xiaohongshu_scripts.xlsx")
```

### 文案库不存在时的处理

**如果 `{{excel_path}}` 指向的文件不存在：**
- 🆕 按照示例格式创建新的Excel文件
- ✅ 应用默认格式参数
- 💡 提示用户："文案库不存在，已按默认格式创建"

**默认格式示例：**
| 列 | 内容 | 格式 |
|:---|:---|:---|
| A | 视频文案 | 宋体，浅绿色背景，跨行合并 |
| B-H | 分镜详情 | 宋体，不合并 |
| I-N | BGM等 | 宋体，跨行合并 |

**注意：** 实际格式可在子任务5中扫描确认

## 执行流程

1. 检查 `{{excel_path}}` 是否存在
2. 如不存在，按示例格式创建新文件
3. 打开文案库Excel文件
4. 确定写入起始行（已有数据最后一行+1）
5. **拆分执行**：脚本分别独立写入
6. 每个脚本按格式参数写入14列
7. 处理合并单元格（A列、I-N列）
8. 保存文件

## 拆分执行方案

| 子任务 | 脚本 | 起始行 | 结束行 | 状态 |
|:---:|:---:|:---:|:---:|:---:|
| 8-1 | 脚本1 | 第X行 | 第X+Y行 | 待执行 |
| 8-2 | 脚本2 | 第X+Y+1行 | 第X+Y+Z+1行 | 待执行 |
| 8-3 | 脚本3 | ... | ... | 待执行 |
| 8-4 | 脚本4 | ... | ... | 待执行 |
| 8-5 | 脚本5（如有） | ... | ... | 待执行 |

**说明：**
- Y = 脚本1的分镜数 - 1
- Z = 脚本2的分镜数 - 1
- 以此类推

## 写入内容

### A列 - 视频文案（跨行合并）

```
[标题]
[故事内容，200字以上]
#[标签1] #[标签2] #[标签3]
```

**合并规则：**
- 起始行到结束行合并
- 垂直居中对齐
- 自动换行开启

### B-H列 - 分镜详情（每行独立）

每行一个分镜，不合并：

| 列 | 内容 |
|:---|:---|
| B-时间段 | 0-{{duration}}秒 |
| C-镜头 | [详细描述] |
| D-运镜 | [详细描述] |
| E-拍摄技巧 | [详细描述] |
| F-画面 | [详细描述] |
| G-台词 | [口语化台词] |
| H-音效 | [音效描述] |

### I-N列 - 附加信息（跨行合并）

| 列 | 内容 |
|:---|:---|
| I-BGM | [音乐信息] |
| J-标签 | #[标签] |
| K-状态 | 待使用 |
| L-活动 | [关联活动] |
| M-日期 | [计划发布日期] |
| N-备注 | [拍摄注意事项] |

**合并规则：**
- 起始行到结束行合并（I-N列一起合并）
- 垂直居中对齐
- 自动换行开启

## 格式应用

### 写入前
```python
# 应用A列格式
apply_format(format_params['data_row_A'], start_row, end_row, col=1)

# 应用B-H列格式
for row in range(start_row, end_row + 1):
    apply_format(format_params['data_row_B_H'], row, row, col=2, end_col=8)

# 应用I-N列格式
apply_format(format_params['data_row_I_N'], start_row, end_row, col=9, end_col=14)
```

## 输出格式

```markdown
## 文案库更新报告

### 文案库状态
| 项目 | 数值 |
|:---|:---|
| 文件路径 | {{excel_path}} |
| 文件存在 | [✅ 存在 / 🆕 新创建] |
| 创建时间 | [如新创建，显示时间] |

### 写入概览
| 项目 | 数值 |
|:---|:---:|
| 写入脚本数 | {{count}} |
| 起始行 | 第[起始]行 |
| 结束行 | 第[结束]行 |
| 总占用行数 | [行数] |

### 拆分执行详情

| 子任务 | 脚本 | 写入状态 | 起始行 | 结束行 | 分镜数 | 备注 |
|:---:|:---:|:---:|:---:|:---:|:---:|:---|
| 8-1 | 脚本1 | ✅成功/❌失败 | 第X行 | 第Y行 | [数量] | [备注] |
| 8-2 | 脚本2 | ✅成功/❌失败 | 第X行 | 第Y行 | [数量] | [备注] |
| 8-3 | 脚本3 | ✅成功/❌失败 | 第X行 | 第Y行 | [数量] | [备注] |
| 8-4 | 脚本4 | ✅成功/❌失败 | 第X行 | 第Y行 | [数量] | [备注] |
| 8-5 | 脚本5 | ✅成功/❌失败 | 第X行 | 第Y行 | [数量] | [备注] |

### 脚本位置确认

| 脚本 | 主题 | Excel行号 | 状态 |
|:---:|:---|:---:|:---:|
| 1 | [主题1] | 第X-Y行 | ✅已写入 |
| 2 | [主题2] | 第X-Y行 | ✅已写入 |
| 3 | [主题3] | 第X-Y行 | ✅已写入 |
| 4 | [主题4] | 第X-Y行 | ✅已写入 |
| 5 | [主题5] | 第X-Y行 | ✅已写入/➖无 |

### 格式应用确认

| 列范围 | 合并状态 | 格式状态 | 备注 |
|:---|:---:|:---:|:---|
| A列 | ✅已合并 | ✅已应用 | 视频文案 |
| B-H列 | ➖不合并 | ✅已应用 | 分镜详情 |
| I-N列 | ✅已合并 | ✅已应用 | 附加信息 |

### 写入后文件信息

| 项目 | 数值 |
|:---|:---|
| 文件路径 | {{excel_path}} |
| 总行数 | [更新后行数] |
| 总脚本数 | [更新后脚本数] |
| 文件大小 | [大小] |
```

## 备份说明

- 仅写入主文案库即可
- 不额外备份到"永久保存脚本库"
- 如需备份，用户可自行复制Excel文件

## 注意事项

1. ✅ **拆分执行**：脚本分别独立写入，避免超时
2. ✅ **追加写入**：在已有数据最后一行后追加，不删除、不覆盖
3. ✅ **格式保持**：严格按照子任务5确定的实际格式写入
4. ✅ **合并单元格**：按实际格式处理A列、I-N列的合并
5. ✅ **自动创建**：如文案库不存在，按默认格式创建
6. ❌ 不要一次性写入所有脚本
7. ❌ 不要改变已有数据的格式

## 首次使用配置

如文案库路径未配置，需先设置：

```bash
# 配置文案库路径（示例）
kd config set copy_library_path "F:\\vlog\\JT\\idea\\xiaohongshu_scripts.xlsx"
```

或创建新的文案库：
```bash
# 创建新的文案库（自动按默认格式创建）
kd excel create --platform xiaohongshu --output "F:\\vlog\\JT\\idea\\xiaohongshu_scripts.xlsx"
```

## 使用示例

**场景1：文案库已存在**

输入：
- excel_path: "F:\vlog\JT\idea\xiaohongshu_scripts.xlsx"
- scripts: [脚本1, 脚本2, 脚本3, 脚本4]
- count: 4

输出：
```
## 文案库更新报告

### 文案库状态
| 项目 | 数值 |
|:---|:---|
| 文件路径 | F:\vlog\JT\idea\xiaohongshu_scripts.xlsx |
| 文件存在 | ✅ 存在 |

### 写入概览
| 项目 | 数值 |
|:---|:---:|
| 写入脚本数 | 4 |
| 起始行 | 第156行 |
| 结束行 | 第212行 |
...
```

**场景2：文案库不存在（自动创建）**

输出：
```
## 文案库更新报告

### 文案库状态
| 项目 | 数值 |
|:---|:---|
| 文件路径 | F:\vlog\JT\idea\xiaohongshu_scripts.xlsx |
| 文件存在 | 🆕 新创建 |
| 创建时间 | 2026-04-22 14:30:00 |

### 提示
🆕 文案库不存在，已按默认格式创建

### 后续配置
如需自定义格式，可在子任务5中扫描现有格式
```


path: prompts/step9_verify_write.md
content: # 子任务9：全面检查对比

## 任务目标
检查写入后的Excel文件，验证3项正确性（格式、内容、位置），与子任务7原始脚本对比，确保无丢失、无变形。

## 输入变量

| 变量名 | 说明 | 来源 |
|:---|:---|:---|
| `{{excel_path}}` | 文案库Excel路径 | 用户配置 |
| `{{original_scripts}}` | 子任务7原始脚本 | 子任务7 |
| `{{write_positions}}` | 写入位置信息 | 子任务8 |
| `{{format_params}}` | Excel格式参数 | 子任务5 |

## 检查维度（3项）

| 检查项 | 检查内容 | 权重 |
|:---|:---|:---:|
| **格式正确性** | 是否与子任务5记录的格式一致 | 40% |
| **内容完整性** | 14列是否都有数据，合并单元格是否正确 | 40% |
| **写入位置正确性** | 是否按子任务8确认的起始/结束行号写入 | 20% |

## 检查细则

### 1. 格式正确性

**检查点：**
- 字体（名称、大小、颜色）
- 对齐方式（水平、垂直）
- 填充颜色（背景色RGB值）
- 边框（样式、颜色）
- 自动换行
- 行高

**对比对象：**
- 子任务5记录的格式参数
- 实际写入后的单元格格式

**通过标准：**
- 关键参数（字体、对齐、颜色）一致
- 次要参数（行高）允许微小偏差

### 2. 内容完整性

**检查点：**
- 14列是否都有数据
- 合并单元格范围是否正确
- 数据是否与原始脚本一致
- 有无丢失或变形

**验证方式：**
```python
# 读取写入后的内容
written_data = read_excel_rows(start_row, end_row)

# 对比原始数据
for i, script in enumerate(original_scripts):
    if written_data[i] != script:
        report_diff(i, script, written_data[i])
```

### 3. 写入位置正确性

**检查点：**
- 起始行号是否匹配
- 结束行号是否匹配
- 脚本间是否有重叠或间隙

**验证方式：**
```python
# 检查每个脚本的实际位置
for script_id, expected in write_positions.items():
    actual = find_script_in_excel(script_id)
    if actual != expected:
        report_position_error(script_id, expected, actual)
```

## 输出格式

```markdown
## 全面检查对比报告

### 检查概览
| 检查项 | 结果 | 说明 |
|:---:|:---:|:---|
| 格式正确性 | ✅通过/❌不通过 | [说明] |
| 内容完整性 | ✅通过/❌不通过 | [说明] |
| 写入位置正确性 | ✅通过/❌不通过 | [说明] |
| **整体结果** | ✅通过/❌不通过 | [说明] |

### 详细检查结果

#### 1. 格式正确性检查

| 检查项 | 预期值 | 实际值 | 状态 | 说明 |
|:---|:---|:---|:---:|:---|
| 标题行字体 | [预期] | [实际] | ✅/❌ | |
| 标题行颜色 | [预期] | [实际] | ✅/❌ | |
| 数据行A列字体 | [预期] | [实际] | ✅/❌ | |
| 数据行A列颜色 | [预期] | [实际] | ✅/❌ | |
| 数据行B-H列对齐 | [预期] | [实际] | ✅/❌ | |
| 数据行I-N列合并 | [预期] | [实际] | ✅/❌ | |
| ... | ... | ... | ... | |

#### 2. 内容完整性检查

| 脚本 | 标题 | 分镜数 | 内容检查 | 合并检查 | 结果 | 差异说明 |
|:---:|:---|:---:|:---:|:---:|:---:|:---|
| 脚本1 | [标题] | [数量] | ✅/❌ | ✅/❌ | 通过/不通过 | [差异] |
| 脚本2 | [标题] | [数量] | ✅/❌ | ✅/❌ | 通过/不通过 | [差异] |
| 脚本3 | [标题] | [数量] | ✅/❌ | ✅/❌ | 通过/不通过 | [差异] |
| 脚本4 | [标题] | [数量] | ✅/❌ | ✅/❌ | 通过/不通过 | [差异] |
| 脚本5 | [标题] | [数量] | ✅/❌ | ✅/❌ | 通过/不通过 | [差异] |

##### 内容对比详情（脚本1）

| 列 | 原始内容 | 写入后内容 | 状态 |
|:---:|:---|:---|:---:|
| A | [原始] | [实际] | ✅/❌ |
| B | [原始] | [实际] | ✅/❌ |
| C | [原始] | [实际] | ✅/❌ |
| ... | ... | ... | ... |

#### 3. 写入位置正确性检查

| 脚本 | 预期起始行 | 预期结束行 | 实际起始行 | 实际结束行 | 状态 | 偏差 |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| 脚本1 | [行号] | [行号] | [行号] | [行号] | ✅/❌ | [说明] |
| 脚本2 | [行号] | [行号] | [行号] | [行号] | ✅/❌ | [说明] |
| 脚本3 | [行号] | [行号] | [行号] | [行号] | ✅/❌ | [说明] |
| 脚本4 | [行号] | [行号] | [行号] | [行号] | ✅/❌ | [说明] |
| 脚本5 | [行号] | [行号] | [行号] | [行号] | ✅/❌ | [说明] |

### 差异汇总

#### 严重差异（需修正）
| 类型 | 位置 | 问题 | 建议 |
|:---|:---|:---|:---|
| [类型] | [位置] | [问题] | [建议] |

#### 轻微差异（可接受）
| 类型 | 位置 | 问题 | 说明 |
|:---|:---|:---|:---|
| [类型] | [位置] | [问题] | [说明] |

## 3层错误恢复机制

如检查发现错误，按以下层级处理：

### 第1层：自动修复

**适用场景：** 格式小问题（如边框、对齐）

**处理方式：**
```python
# 自动修复格式问题
for issue in format_issues:
    if issue.can_auto_fix:
        auto_fix(issue)
        log_fix(issue)
```

### 第2层：重新验证

**适用场景：** 自动修复后

**处理方式：**
```python
# 重新执行全面检查
re_check_result = run_full_check()
if re_check_result.passed:
    continue_to_step_10()
else:
    goto_layer_3()
```

### 第3层：删除回退

**适用场景：** 严重错误无法自动修复

**处理方式：**
```python
# 删除已写入的行
delete_rows(start_row, end_row)

# 回退到子任务8
rollback_to_step_8()

# 提示用户
notify_user("发现严重错误，已回退到子任务8，请修正后重新执行")
```

## 与子任务7的区别

| 维度 | 子任务7 | 子任务9 |
|:---|:---|:---|
| **检查对象** | 生成的脚本内容 | 写入Excel后的实际数据 |
| **检查层面** | 内容层面（时间、场景、台词） | 技术层面（格式、数据完整性、位置） |
| **对比基准** | 平台规则和合理标准 | 子任务7原始脚本和子任务5格式参数 |
| **发现问题** | 内容问题 | 写入过程中的技术问题 |
| **处理方式** | 直接修改脚本 | 自动修复或回退重写 |

## 注意事项

1. ✅ 检查3项**全部维度**
2. ✅ **对比原始脚本**，确保无丢失、无变形
3. ✅ 执行3层错误恢复机制
4. ✅ 错误严重时**回退到子任务8**
5. ❌ 不要忽略轻微差异（可能累积成大问题）
6. ❌ 不要跳过任何一条脚本的检查

## 通过标准

**全部通过条件：**
- 格式正确性：≥90%一致
- 内容完整性：100%无丢失
- 写入位置正确性：100%准确

**部分通过处理：**
- 轻微差异：记录并继续
- 严重差异：执行3层恢复机制


path: README.md
content: # 快导 (KD) - 短视频脚本批量生成

**版本：** 1.1.0（2026年4月更新）

快导(KD)是一个跨平台、跨行业的短视频脚本批量生成与管理工具，支持单次任务执行。

---

## ⚠️ 安装前必读（安全检查清单）

在安装和运行快导之前，请确认以下事项：

### 1. 依赖检查
- [ ] Python 3.7+ 已安装
- [ ] `openpyxl` 已安装 (`pip install openpyxl`)
- [ ] `web_search` skill 可用（用于搜索平台爆款）
- [ ] 可选：`lark-cli`（仅当需要飞书上传功能时）

### 2. 路径配置安全
- [ ] `copy_library_path` 指向你**控制的目录**
- [ ] `rules_path` 指向你**控制的目录**  
- [ ] 避免使用系统关键目录（如 C:\Windows, /usr/bin 等）

### 3. 飞书上传（可选）
- [ ] 了解 `feishu_permissions.json` 中的 36 个权限 scope
- [ ] 仅提供 `LARK_CLI_TOKEN` 如果你**确实需要**上传报告
- [ ] token 将存储在 `lark-cli` 配置中，**不在快导内**

### 4. 示例脚本安全
- [ ] `entry_template.py` 包含**占位符路径**（YOUR_USERNAME）
- [ ] **运行前必须修改**路径配置
- [ ] 首次运行时会提示确认路径

### 5. 网络行为知情
- [ ] `web_search` 会发送搜索查询到外部服务
- [ ] `external_search.auto_collect` 启用时会自动搜索热门
- [ ] 不会自动上传任何数据到第三方服务

**确认以上事项后，再继续安装。**

---

## 项目结构

```
kd/
├── kd.py                          # 主入口文件
├── test_workflow.py               # 工作流测试脚本
├── entry_template.py              # 入口模板示例
├── config/                        # 配置文件目录
│   ├── platforms.json             # 平台参数配置（时长、关键词等）
│   ├── workflow.json              # 工作流配置（10步流程定义）
│   ├── templates.json             # 模板配置（提示词模板）
│   ├── user_config.json           # 用户配置（文案库路径、飞书空间ID等）
│   └── feishu_permissions.json    # 飞书权限配置
├── scripts/                       # 核心模块
│   ├── __init__.py                # 模块初始化，导出核心类
│   ├── config_manager.py          # 配置管理（ConfigManager）
│   ├── excel_manager.py           # Excel操作（ExcelManager）
│   ├── script_generator.py        # 脚本生成（ScriptGenerator）
│   ├── workflow_manager.py        # 工作流管理（WorkflowManager）
│   ├── format_checker.py          # 格式检查（FormatChecker）
│   └── feishu_permission_helper.py # 飞书权限开通助手
├── prompts/                       # 提示词模板
│   ├── step6_generate_scripts.md  # 子任务6：生成脚本提示词
│   └── step7_validate_scripts.md  # 子任务7：合理性检查提示词
├── references/                    # 参考文档
│   ├── platform_rules/            # 平台规则文档（自动生成）
│   │   ├── xiaohongshu_rules.md
│   │   ├── douyin_rules.md
│   │   └── shipinhao_rules.md
│   └── README.md                  # 参考资料说明
├── tests/                         # 测试脚本
│   ├── config_manager_win.py      # Windows配置管理测试
│   ├── excel_manager_win.py       # Windows Excel操作测试
│   ├── format_checker_win.py      # Windows格式检查测试
│   ├── script_generator_win.py    # Windows脚本生成测试
│   ├── __init__.py
│   ├── mac/                       # macOS测试脚本
│   │   ├── config_manager_mac.py
│   │   ├── excel_manager_mac.py
│   │   ├── format_checker_mac.py
│   │   └── script_generator_mac.py
│   └── linux/                     # Linux测试脚本
│       ├── config_manager_linux.py
│       ├── excel_manager_linux.py
│       ├── format_checker_linux.py
│       └── script_generator_linux.py
├── requirements.txt               # Python依赖
├── setup.py                       # 安装配置
├── .gitignore                     # Git忽略配置
├── SKILL.md                       # OpenClaw Skill文档
└── README.md                      # 本文件（用户使用手册）
```

---

## 核心类说明

| 类名 | 文件 | 用途 |
|:---|:---|:---|
| `ConfigManager` | `config_manager.py` | 管理所有配置文件（platforms.json、user_config.json等） |
| `ExcelManager` | `excel_manager.py` | 读写Excel文案库，格式扫描与保持 |
| `ScriptGenerator` | `script_generator.py` | 生成短视频脚本内容 |
| `WorkflowManager` | `workflow_manager.py` | 协调执行10步快导流程 |
| `FormatChecker` | `format_checker.py` | 检查Excel格式、内容合理性 |

---

---

## ⚠️ CRITICAL — 首次使用必读

**用户：**"我要用快导生成小红书脚本"

**我：**好的，使用快导之前，需要先完成几项配置。我来引导你：

---

### 第0步：开通飞书机器人权限（如使用飞书功能）

**用户：**"我需要保存报告到飞书吗？"

**我：**"如果你希望自动上传执行报告到飞书知识库，需要先开通机器人权限。如果只用本地保存，可以跳过这步。"

**开通权限（可选）：**

```bash
# 运行权限开通助手
python scripts/feishu_permission_helper.py
```

或手动开通：
1. 进入飞书开发者后台：https://open.feishu.cn/app
2. 选择你的应用 → 权限管理 → 开通权限
3. 点击"批量导入/导出权限"
4. 粘贴 `config/feishu_permissions.json` 中的内容
5. 申请开通并发布应用

**需要的权限包括：**
- 云文档读写（保存报告）
- 知识库访问（上传到 wiki）
- 消息发送（通知功能）

---

### 第1步：安装依赖

**用户：**"我已经装好了 Python，接下来呢？"

**我：**安装 openpyxl，用于操作 Excel 文案库：

```bash
pip install openpyxl
```

---

### 第2步：配置搜索关键词和主题方向

**用户：**"我是做农家乐的，怎么配置？"

**我：**请告诉我你的搜索关键词和创作主题方向：

- **搜索关键词：** 用于搜索平台爆款视频（例如：农家乐、采摘、成都周边、周末去哪）
- **主题方向：** 你希望创作的内容方向（可选，为空则不限制主题。例如：采摘攻略、亲子游玩、美食探店）

我会帮你配置到 `config/platforms.json` 中。

**示例：**
```json
{
  "platforms": {
    "xiaohongshu": {
      "keywords": ["农家乐", "采摘", "成都周边"],
      "theme_direction": ["采摘攻略", "亲子游玩"]
    }
  }
}
```

**注意：** `theme_direction`（主题方向）可为空，不填则不限制创作主题。

---

### 第3步：设置文案库保存位置

**用户：**"生成的脚本保存在哪里？"

**我：**请告诉我你希望保存到哪个文件夹，例如：

> "保存到 F:\\vlog\\JT\\idea\\ 目录，文件名叫小红书文案库.xlsx"

我会帮你配置到 `config/user_config.json` 中。

**配置项说明：**
| 配置项 | 你要告诉我的内容 | 用途 |
|:---|:---|:---|
| 文案库路径 | "F:\\vlog\\JT\\idea\\小红书文案库.xlsx" | 保存生成的脚本 |
| 飞书空间ID | 你的飞书知识库空间ID（可选）| 自动上传报告到飞书 |
| 规则文档路径 | 留空即可（可选）| 保存平台规则文档 |

---

### 第4步：生成平台规则（可选）

**用户：**"什么是平台规则？需要吗？"

**我：**平台规则包含小红书的运营规范，例如：
- 视频时长要求（2-3分钟）
- 标题字数限制（20字以内）
- 违规内容红线

**你可以选择：**
- ✅ **帮我生成默认规则** — 我基于平台通用规则创建
- ❌ **先跳过** — 后续在生成的脚本中手动调整

如果选择生成，告诉我："帮我生成小红书规则文档"

---

### 完成！现在可以开始使用了

**用户：**"配置好了，开始生成脚本吧"

**我：**好的，执行快导系列任务，告诉我：
1. 目标平台（小红书/抖音/视频号）
2. 生成几条脚本（默认5条）

我们开始吧！

---

## ⚠️ 安全与隐私说明

### 数据存储
- **所有生成的脚本**保存在本地配置的 Excel 文件路径
- **执行报告**默认保存到本地 `reports/` 目录
- **不会自动上传到任何云服务**

### 飞书上传（可选）
- 如需上传报告到飞书知识库，**需手动配置**
- 步骤：
  1. 安装并配置 `lark-cli`（见下方"飞书权限开通"章节）
  2. 手动运行上传命令
- **默认不上传**，仅在用户明确要求时才执行

### 网络访问
- **web_search**：搜索平台爆款时使用（必需）
- **无其他外部网络调用**
- 所有脚本执行在本地完成

### 敏感信息
- 如需配置飞书认证，token 保存在 `lark-cli` 的配置中
- 快导 skill **不存储任何凭证**

---

## 使用说明（重要）

**当前版本状态：**
- ✅ **Python API**：完整可用，推荐通过 Python 代码调用
- 🚧 **CLI 命令行**：框架已搭建，具体功能开发中

**建议使用方式：** 直接导入 Python 模块使用（见下方"Python API 使用"章节）

---

## 快导十步流程说明

### 简略版（默认）

**用户：**"快导的十步分别是什么？"

**我：**快导系列包含10个步骤：

| 步骤 | 名称 | 一句话说明 |
|:---:|:---|:---|
| 1 | 搜索平台爆款 | 搜你行业的爆款视频参考 |
| 2 | 读取平台规则 | 读取平台运营规范 |
| 3 | 搜外网爆款 | 搜TikTok/YouTube灵感 |
| 4 | 查重复 | 避开已有脚本主题 |
| 5 | 查格式 | 扫描Excel实际格式 |
| 6 | 写脚本 | 生成差异化脚本 |
| 7 | 检查 | 检查脚本合理性 |
| 8 | 保存 | 写入Excel文案库 |
| 9 | 验证 | 验证写入结果 |
| 10 | 出报告 | 生成执行报告 |

完整执行就是走这10步，也可以单独执行某一步。

---

### 详细版

**用户：**"详细说说每一步做什么？"

**我：**

**第1步：搜索平台爆款**
- 用你配置的关键词搜小红书/抖音/视频号
- 随机抽3个关键词，各搜20条
- 最终选定4个最优爆款

**第2步：读取平台规则**
- 读取平台运营规范（时长、标题、违规红线等）
- 输出7项关键规则摘要

**第3步：搜外网爆款**
- 搜TikTok/YouTube找灵感
- **三种模式：**
  1. 使用 `external_keywords` 配置的关键词搜索
  2. 使用 `default_keywords` 预设默认关键词搜索  
  3. `auto_collect=true` 时自动获取当前热门视频（无需关键词）
- 最终选定1个外网爆款

**配置方式：** 在 `user_config.json` 中配置 `external_search`

**第4步：查重复**
- 读取你文案库已有脚本
- 确定需避开的主题方向

**第5步：查格式**
- 扫描Excel实际格式（字体、颜色、边框等）
- 记录格式参数，确保写入时格式一致

**第6步：写脚本**
- 基于第1、3步的爆款，生成差异化脚本
- 每个脚本包含完整的分镜、台词、BGM等14列

**第7步：检查**
- 检查时长、内容、场景、台词、格式等合理性
- 发现问题直接修改

**第8步：保存**
- 将脚本写入Excel文案库
- 严格按第5步记录的格式写入

**第9步：验证**
- 用Python读取Excel验证
- 检查格式、内容、位置正确性

**第10步：出报告**
- 生成Markdown执行报告
- 保存到飞书知识库（如配置了空间ID）

---

## 安装

### 方式1：通过 clawhub 安装（推荐）

```bash
# 安装 skill
clawhub install kd

# 进入 skill 目录
cd ~/.agents/skills/kd

# 安装依赖
pip install -r requirements.txt
```

### 方式2：手动下载

```bash
# 下载到本地
cd ~/.agents/skills/
git clone <repository-url> kd

# 安装依赖
cd kd
pip install -r requirements.txt
```

---

## Python API 使用（推荐）

### 快导系列 - 生成脚本

```python
from kd.scripts import ScriptGenerator, ExcelManager, ConfigManager

# 1. 加载配置
config = ConfigManager()
config.load_platform('xiaohongshu')  # 或 'douyin', 'shipinhao'

# 2. 生成脚本
generator = ScriptGenerator(platform='xiaohongshu')
scripts = generator.generate(
    trending_titles=['爆款标题1', '爆款标题2'],  # 子任务1结果
    rules_summary={...},  # 子任务2结果
    avoid_themes=['已有主题1'],  # 子任务4结果
    count=5
)

# 3. 写入文案库
with ExcelManager('path/to/文案库.xlsx') as em:
    format_info = em.scan_format()  # 子任务5
    for script in scripts:
        em.append_script(script)  # 子任务8
```

### 规则更新系列

```python
from kd.scripts import ConfigManager

# 读取平台规则（需用户自行创建规则文档）
config = ConfigManager()
rules = config.load_rules('xiaohongshu')
```

---

## Shortcuts（快速使用参考）

| 用户说 | 我执行 | 对应模块 |
|:---|:---|:---|
| "帮我配置小红书关键词" | 引导配置 platforms.json | config_manager |
| "设置文案库路径" | 引导配置 user_config.json | config_manager |
| "生成小红书规则" | 创建 xiaohongshu_rules.md | rules_update |
| "快导小红书，生成5条" | 执行完整10步流程 | 快导系列 |
| "快导第6步，生成脚本" | 执行单步子任务6 | step6_generate |
| "检查文案库格式" | 执行 step5 格式检查 | excel_manager |
| "验证写入结果" | 执行 step9 验证 | excel_manager |

### 额外问答

**用户：**"快导的十步分别是什么？"

**我：**（提供简略版或详细版，见上方"快导十步流程说明"章节）

---

## 执行模式

### 自动模式（默认）

**说明：** 连续执行所有步骤，完成后一次性返回结果。

```python
from kd.scripts import WorkflowManager

# 创建实例
workflow = WorkflowManager('xiaohongshu')

# 执行完整流程
result = workflow.run_full()

if result['success']:
    print(f"✅ 完成！生成 {len(result['completed_steps'])} 步")
else:
    print(f"❌ 失败：{result.get('error', '未知错误')}")
```

---

### 交互模式

**说明：** 每完成一步后暂停，等待用户确认后再继续。

```python
from kd.scripts import WorkflowManager

# 启用交互模式
workflow = WorkflowManager('xiaohongshu', interactive=True)

# 执行
result = workflow.run_full()

# 如果暂停了，提示用户
if result.get('paused'):
    print(result['message'])
    # 输出示例: "Step 1 完成，是否继续执行 Step 2？"
    
    # 用户回复后继续
    workflow.resume()
```

**用户交互示例：**

| Agent 回复 | 用户回复 | 说明 |
|:---|:---|:---|
| "Step 1 完成，选定4个爆款。继续？" | "继续" / "跳过" / "停止" | 选择继续执行、跳过下一步、或停止 |
| "Step 6 完成，生成5条脚本。继续？" | "继续" | 进入检查和保存阶段 |

---

### 回调模式（即时回复）

**说明：** 每完成一步立即回调，适合需要即时向用户展示进度的场景。

```python
from kd.scripts import WorkflowManager

def on_step_complete(step_num, result, should_pause):
    """每步完成后的回调"""
    print(f"✅ Step {step_num} 完成")
    
    # 如果是关键步骤，展示更多信息
    if step_num == 1:
        trending = result.get('final_selection', [])
        print(f"   选定爆款: {len(trending)} 个")
    elif step_num == 6:
        scripts = result.get('scripts', [])
        print(f"   生成脚本: {len(scripts)} 条")
    
    # 如果需要暂停，提示用户
    if should_pause:
        print("   输入 '继续' 执行下一步")

# 执行，使用回调
workflow = WorkflowManager('xiaohongshu')
result = workflow.run_full(callback=on_step_complete)
```

---

## 详细命令示例

### 示例1：完整快导流程

**用户：**"快导小红书，生成5条脚本"

**我：**执行完整10步流程：

```python
from kd.scripts import ConfigManager, ScriptGenerator, ExcelManager

# Step 1-5: 准备阶段
config = ConfigManager()
platform_config = config.load_platform('xiaohongshu')

# Step 6: 生成脚本
generator = ScriptGenerator(platform='xiaohongshu')
scripts = generator.generate(
    trending_titles=['爆款标题1', '爆款标题2', '爆款标题3', '爆款标题4'],
    external_title='外网爆款标题',
    rules_summary={...},
    avoid_themes=['已有主题'],
    count=5
)

# Step 7: 合理性检查（自动生成时已完成）

# Step 8-9: 写入并验证
with ExcelManager('path/to/文案库.xlsx') as em:
    for script in scripts:
        em.append_script(script)
    em.validate_write()

# Step 10: 生成报告
print(f"✅ 成功生成 {len(scripts)} 条脚本")
```

---

### 示例2：单步执行

**用户：**"快导第6步，生成脚本"

**我：**仅执行脚本生成：

```python
from kd.scripts import ScriptGenerator

generator = ScriptGenerator(platform='xiaohongshu')
scripts = generator.generate(
    trending_titles=[...],  # 用户需提供
    count=5
)
```

---

### 示例3：检查文案库格式

**用户：**"检查文案库格式"

**我：**扫描Excel格式：

```python
from kd.scripts import ExcelManager

with ExcelManager('path/to/文案库.xlsx') as em:
    format_info = em.scan_format()
    print(format_info)
```

---

### 示例4：配置搜索关键词

**用户：**"帮我配置小红书关键词"

**我：**更新 platforms.json：

```python
from kd.scripts import ConfigManager

config = ConfigManager()
config.set_platform_keywords(
    platform='xiaohongshu',
    keywords=['农家乐', '采摘', '成都周边'],
    theme_direction=['采摘攻略', '亲子游玩']  # 可选
)
```

---

## 常见错误处理

### 配置类错误

**错误1：关键词未配置**
- **用户：**"快导小红书"
- **报错：**`"keywords is empty"`
- **我：**"先告诉我你的搜索关键词，例如：农家乐、采摘、成都周边..."

**错误2：文案库路径未设置**
- **用户：**"开始生成"
- **报错：**`"copy_library_path not set"`
- **我：**"请告诉我文案库保存到哪里，例如：F:\\vlog\\JT\\idea\\小红书文案库.xlsx"

---

### Step 1 错误：搜索平台爆款

**错误1：没有搜索 skill**
- **报错：**`"web_search skill not available"`
- **我：**"当前没有配置搜索功能，请手动提供4个爆款标题，或者安装 web_search skill"

**错误2：搜索返回空结果**
- **报错：**`"no trending videos found"`
- **我：**"用你配置的关键词没搜到爆款，要不要换几个关键词试试？"

---

### Step 2 错误：读取平台规则

**错误1：规则文档不存在**
- **报错：**`"rules file not found: xiaohongshu_rules.md"`
- **我：**"规则文档不存在，要我帮你生成默认规则吗？"

---

### Step 3 错误：搜索外网爆款

**错误1：没有外网搜索 skill**
- **报错：**`"external search not available"`
- **我：**"当前无法搜索外网爆款（需要相应skill），可以继续用平台爆款生成，或者你提供一个外网参考链接？"

**错误2：网络问题**
- **报错：**`"network error: cannot access TikTok/YouTube"`
- **我：**"网络访问受限，搜不到外网爆款。这一步可以跳过，继续用平台爆款生成脚本？"

**错误3：外网关键词未配置**
- **报错：**`"external_keywords is empty"`
- **我：**"没有配置外网搜索关键词，告诉我几个英文关键词，例如：food, farm, family？或者直接跳过这步？"

---

### Step 4 错误：同质化检查

**错误1：文案库文件不存在**
- **报错：**`"copy library file not found"`
- **我：**"文案库文件还没创建，第一次使用吧？直接生成新脚本，不用查重复了"

---

### Step 5 错误：格式检查

**错误1：Excel 格式异常**
- **报错：**`"cannot read Excel format: file corrupted"`
- **我：**"Excel文件读取失败，可能是格式问题。要不要我创建一个新的标准格式文案库？"

---

### Step 6 错误：生成脚本

**错误1：生成超时**
- **报错：**`"script generation timeout"`
- **我：**"生成脚本超时了，可能是网络问题。要不要减少生成数量再试？"

**错误2：内容不合规**
- **报错：**`"generated content violates platform rules"`
- **我：**"生成的内容可能不符合平台规范，需要我调整后再生成吗？"

---

### Step 7 错误：合理性检查

**错误1：时长不达标**
- **报错：**`"total duration mismatch: expected 120-180s, got 90s"`
- **我：**"总时长不够，需要增加分镜或延长单镜时长，要我自动调整吗？"

**错误2：内容同质化**
- **报错：**`"scripts are not differentiated enough"`
- **我：**"脚本差异化不够，重新生成一批？"

---

### Step 8 错误：更新文案库

**错误1：写入失败**
- **报错：**`"failed to write to Excel: permission denied"`
- **我：**"Excel文件被占用了（可能你正在打开），关闭Excel后再试？"

**错误2：格式不匹配**
- **报错：**`"format mismatch with step5 scan result"`
- **我：**"写入格式和扫描的格式不一致，需要我重新扫描再写入？"

---

### Step 9 错误：全面检查对比

**错误1：内容丢失**
- **报错：**`"content validation failed: missing columns"`
- **我：**"验证发现内容有缺失，回退到Step 8重新写入？"

**错误2：位置错误**
- **报错：**`"position mismatch: expected row 15, found row 14"`
- **我：**"写入位置不对，检查后发现偏移了一行，需要修正？"

---

### Step 10 错误：提交报告

**错误1：飞书空间未配置**
- **报错：**`"report_space_id not set"`
- **我：**"没有配置飞书空间ID，报告保存到本地目录可以吗？"

**错误2：保存失败**
- **报错：**`"failed to upload to lark wiki"`
- **我：**"飞书上传失败了，报告已保存到本地，需要手动上传吗？"

---

## v1.1.0 新功能说明（2026年4月更新）

### 1. 智能时长计算（auto_adjust）

**功能：** 根据台词字数自动计算并调整分镜时长

**配置：**
```json
// config/platforms.json
{
  "duration_policy": {
    "xiaohongshu": {
      "target_duration": {"min": 120, "max": 180},
      "segment_duration": {"min": 6, "max": 15},
      "auto_adjust": true,  // 开启自动调整
      "calculation_rules": {
        "speech_rate": 0.25,  // 0.25秒/字
        "motion_base": {...},  // 运镜基础时长
        "buffer_seconds": 1     // 缓冲时间
      }
    }
  }
}
```

**说明：**
- `auto_adjust: true` → 系统自动计算（默认）
- `auto_adjust: false` → 完全手动控制时间段
- 台词时长 = 字数 × speech_rate（0.25秒/字）
- 总时长必须 ≥ 台词时长的60%

---

### 2. 活动配置管理（Activity Manager）

**功能：** 自动匹配脚本关联活动

**配置方式1：自然语言**
```
用户："添加活动：春节特惠，关键词：春节、过年、团圆"
Agent：✓ 活动"春节特惠"已添加，包含3个关键词

用户："列出所有活动"
Agent：当前有2个活动：春节特惠、五一采摘节

用户："删除活动：春节特惠"
Agent：✓ 已删除
```

**配置方式2：直接编辑JSON**
```json
// config/platforms.json
{
  "activities": {
    "list": [
      {
        "id": "spring_festival",
        "name": "春节特惠",
        "keywords": ["春节", "过年", "团圆", "年夜饭"],
        "applicable_platforms": ["xiaohongshu", "douyin"]
      },
      {
        "id": "labor_day",
        "name": "五一采摘节",
        "keywords": ["五一", "采摘", "出游"],
        "applicable_platforms": ["xiaohongshu", "douyin", "shipinhao"]
      }
    ],
    "default": "日常推广"
  }
}
```

**自动匹配规则：**
1. 关键词匹配 → 脚本内容包含活动关键词
2. 时间匹配 → 当前日期在活动有效期内
3. 平台匹配 → 活动适用于当前平台

**无匹配时：** 自动填写"日常推广"

---

### 3. BGM详细生成

**功能：** 生成具体的音乐名称、风格和使用时机

**配置：**
```json
// config/platforms.json
{
  "bgm_library": {
    "categories": {
      "food_display": {
        "name": "美食展示",
        "tracks": [
          {"name": "《小美满》周深", "style": "治愈轻快", "suitable": "全程"}
        ]
      },
      "emotional_narrative": {
        "name": "情感叙事",
        "tracks": [...]
      }
    }
  }
}
```

**输出格式：**
```
I列（推荐音乐/BGM）：
音乐名：《小美满》周深
风格：治愈轻快
使用时机：全程
```

---

### 4. Excel行高统一100

**功能：** 数据行统一设置为100，标题行20.4

**配置：**
```json
// config/platforms.json
{
  "global_settings": {
    "row_height": {
      "title_row": 20.4,
      "data_row": 100
    }
  }
}
```

---

### 5. 外网搜索自动收集（auto_collect）

**功能：** `external_keywords` 为空时，自动获取热门视频

**配置：**
```json
// config/user_config.json
{
  "external_search": {
    "auto_collect": true,      // 开启自动收集
    "collect_count": 20,
    "platforms": ["TikTok", "YouTube"],
    "default_keywords": []       // 为空时自动获取
  }
}
```

**三种使用场景：**
1. **手动配置** → `external_keywords: ["food", "cooking"]` → 使用这些关键词
2. **默认预设** → `default_keywords: ["viral food"]` → 使用预设关键词
3. **完全自动** → 两者都为空 + `auto_collect: true` → 自动获取热门

---

## 参考文档

### references/ 目录说明

`references/` 目录存放快导运行过程中生成的参考文档：

| 子目录 | 用途 | 生成方式 |
|:---|:---|:---|
| `platform_rules/` | 平台运营规则文档 | 规则更新系列生成 |
| `trending/` | 平台爆款缓存 | 快导系列自动保存 |
| `external/` | 外网爆款参考 | 快导系列自动保存 |

**用户：**"references 目录是干什么的？"

**我：**"这是存放规则文档和数据缓存的地方。platform_rules/ 存平台规则，trending/ 存搜到的爆款，external/ 存外网参考。具体说明可以看 references/README.md"

---

### 规则文档位置

**用户：**"平台规则存在哪里？"

**我：**"默认保存在 `references/platform_rules/` 目录，包含：
- `xiaohongshu_rules.md` - 小红书规则
- `douyin_rules.md` - 抖音规则  
- `shipinhao_rules.md` - 视频号规则

可以修改保存路径：
```python
config.set_rules_path("你的自定义路径")
```"

---

## CLI 命令行（开发中）

CLI 功能当前仅作为框架存在，具体功能正在开发中。

```bash
# 查看帮助（可用）
kd --help

# 以下命令框架存在，功能开发中：
kd run --platform xiaohongshu      # 执行完整快导系列
kd step --platform xiaohongshu --step 6  # 执行单步
kd rules --platform xiaohongshu    # 规则更新
kd config show                     # 配置管理
```

**当前推荐使用 Python API 直接调用。**

---

| 软件 | 用途 | 安装命令 |
|:---|:---|:---|
| **Python 3.7+** | 运行脚本 | [官网下载](https://www.python.org/downloads/) |
| **lark-cli** | 飞书API操作 | `npm install -g @larksuite/cli` |

### Python依赖包

| 包名 | 用途 | 安装命令 |
|:---|:---|:---|
| **openpyxl** | Excel文件操作 | `pip install openpyxl` |

### 自动安装

如检测到未安装依赖，系统将提示并协助安装：

```bash
# 检查并安装Python依赖
kd setup --check-deps

# 自动安装（需用户确认）
kd setup --install-deps
```

**注意：** 首次使用前请确保已安装Python和lark-cli。

## 系统支持

| 系统 | 支持状态 | 测试脚本位置 |
|:---|:---:|:---|
| **Windows** | ✅ 默认支持 | `tests/` |
| **macOS** | ✅ 支持 | `tests/mac/` |
| **Linux** | ✅ 支持 | `tests/linux/` |

**注意：** Windows版本默认已配置UTF-8编码支持。macOS和Linux用户使用对应目录下的测试脚本。

## 软件依赖

### 必需软件

| 软件 | 用途 | 安装命令 |
|:---|:---|:---|
| **Python 3.7+** | 运行脚本 | [官网下载](https://www.python.org/downloads/) |
| **lark-cli** | 飞书API操作 | `npm install -g @larksuite/cli` |

### Python依赖包

| 包名 | 用途 | 安装命令 |
|:---|:---|:---|
| **openpyxl** | Excel文件操作 | `pip install openpyxl` |

### 自动安装

如检测到未安装依赖，系统将提示并协助安装：

```bash
# 检查并安装Python依赖
kd setup --check-deps

# 自动安装（需用户确认）
kd setup --install-deps
```

**注意：** 首次使用前请确保已安装Python和lark-cli。

## 功能模块

| 模块 | 说明 | 触发命令 |
|:---|:---|:---|
| **快导系列** | 生成多平台短视频脚本（10步流程） | `kd run --platform <平台>` |
| **规则更新系列** | 更新平台运营规则文档 | `kd rules --platform <平台>` |

## 支持平台

| 平台 | 标识 | 总时长 | 分镜数 |
|:---|:---|:---:|:---:|
| 小红书 | `xiaohongshu` | 2-3分钟 | 自动计算 |
| 抖音 | `douyin` | 1分钟内 | 自动计算 |
| 视频号 | `shipinhao` | 1-3分钟 | 自动计算 |

**平台基础信息**（可修改：`config/platforms.json`）
- 小红书：女性、种草决策、攻略型
- 抖音：年轻人、公域流量、快节奏
- 视频号：中老年、私域社交、温情叙事

## 用户配置变量说明

### 配置变量总览

| 变量名 | 用途 | 是否必需 | 为空时的处理 |
|:---|:---|:---:|:---|
| `copy_library_path` | 文案库Excel路径 | ✅ 必需 | 提示用户配置 |
| `report_space_id` | 飞书知识库空间ID | ✅ 必需 | 提示用户配置 |
| `rules_path` | 规则文档保存路径 | ⚠️ 建议配置 | 使用默认值 `references/platform_rules/` |
| `platform_keywords` | 平台搜索关键词池 | ⚠️ 建议配置 | 子任务1终止，提示配置 |
| `external_keywords` | 外网搜索关键词池 | ❌ 可选 | 子任务3跳过（不影响主流程） |
| `theme_direction` | 内容主题方向 | ❌ 可选 | 脚本生成时不限制主题 |

### 变量详细说明

#### 1. copy_library_path（文案库路径）

**用途：** 指定文案库Excel文件的保存位置

**配置方式：**
```bash
# 方式1：命令行
kd config set copy_library_path "F:\\vlog\\JT\\idea\\xiaohongshu_scripts.xlsx"

# 方式2：编辑配置文件
# 编辑 config/user_config.json
{
  "copy_library_path": "F:\\vlog\\JT\\idea\\xiaohongshu_scripts.xlsx"
}

# 方式3：Python脚本
from kd import ConfigManager
config = ConfigManager()
config.set_copy_library_path("F:\\vlog\\JT\\idea\\xiaohongshu_scripts.xlsx")
```

**文件不存在时的处理：**
- 如文件不存在，自动按默认格式创建新的Excel文件
- 默认格式包含14列（A-N），带标题行格式
- 提示用户："文案库不存在，已按默认格式创建"

#### 2. report_space_id（飞书空间ID）

**用途：** 指定执行报告保存的飞书知识库空间

**配置方式：**
```bash
kd config set report_space_id "你的空间ID"
```

**获取方式：**
1. 打开飞书知识库
2. 进入目标空间
3. 空间设置 → 复制空间ID

**为空时的处理：**
- 子任务10提示用户配置
- 可选择保存到本地目录：`reports/`

#### 3. rules_path（规则文档路径）

**用途：** 指定平台规则文档的保存位置

**配置方式：**
```bash
kd config set rules_path "F:\\我的规则\\"
```

**为空时的处理：**
- 使用默认值：`references/platform_rules/`

**规则文档不存在时的处理：**
- 子任务2提示用户先生成规则
- 提供生成命令：`kd rules --platform xiaohongshu`

#### 4. platform_keywords（平台关键词池）

**用途：** 子任务1搜索目标平台爆款时使用

**配置方式：**
```bash
# 方式1：命令行
kd config set-keywords --platform xiaohongshu \
  --keywords "美食,探店,农家菜,采摘,生活,乡村,慢生活,周末"

# 方式2：编辑配置文件
# 编辑 config/platforms.json
{
  "platforms": {
    "xiaohongshu": {
      "keywords": ["美食", "探店", "农家菜", "采摘"]
    }
  }
}
```

**为空时的处理：**
- 子任务1输出警告："关键词池为空，无法进行搜索"
- 终止子任务1
- 提示用户配置关键词池

#### 5. external_keywords（外网关键词池）

**用途：** 子任务3搜索外网平台爆款时使用（可选）

**配置方式：**
```bash
kd config set-external-keywords \
  --keywords "food,cooking,life,vlog,story,family,memory"
```

**为空时的处理：**
- 子任务3输出提示："外网关键词池为空，跳过外网搜索"
- 跳过子任务3，直接执行子任务4
- 不影响主流程执行

#### 6. theme_direction（内容主题方向）

**用途：** 指导脚本生成的主题方向（可选）

**配置方式：**
```bash
# 编辑 config/platforms.json
{
  "platforms": {
    "xiaohongshu": {
      "theme_direction": ["采摘攻略", "美食探店", "慢生活体验"]
    }
  }
}
```

**为空时的处理：**
- 脚本生成时不限制主题方向
- 完全基于爆款和外网参考生成

### 首次使用配置流程

```bash
# 步骤1：设置文案库路径（必需）
kd config set copy_library_path "你的文案库路径"

# 步骤2：设置飞书空间ID（必需）
kd config set report_space_id "你的空间ID"

# 步骤3：配置平台关键词池（建议）
kd config set-keywords --platform xiaohongshu \
  --keywords "关键词1,关键词2,关键词3"

# 步骤4：配置外网关键词池（可选）
kd config set-external-keywords \
  --keywords "food,cooking,life"

# 步骤5：验证配置
kd config validate
```

### 配置验证命令

```bash
# 验证所有配置
kd config validate

# 验证特定平台
kd config validate --platform xiaohongshu

# 查看当前配置
kd config show

# 查看特定平台配置
kd config show --platform xiaohongshu
```

## 首次使用配置

### 1. 设置文案库路径

```bash
kd config set copy_library_path "你的文案库目录"
# 示例：kd config set copy_library_path "D:\\我的文案\\"
```

### 2. 设置飞书报告空间

```bash
kd config set report_space_id "你的空间ID"
# 空间ID在飞书知识库设置中获取
```

### 3. 配置搜索关键词（可选）

编辑 `config/platforms.json` 中对应平台的 `keywords` 字段。

### 4. 设置规则文档路径

```bash
kd config set rules_path "你的规则文档目录"
# 示例：kd config set rules_path "D:\\我的规则\\"
# 默认：references/platform_rules/
```

### 5. 配置搜索关键词（可选）

编辑 `config/platforms.json` 中对应平台的 `keywords` 字段。

### 6. 设置行业场景（可选）

编辑 `config/platforms.json` 中 `industry_templates` 添加你的行业。

## 快速开始

### 执行完整任务链（10步）

```bash
# 执行小红书任务
kd run --platform xiaohongshu --duration "2-3min"

# 执行抖音任务
kd run --platform douyin --duration "1min"
```

### 执行单个子任务

```bash
# 仅执行子任务6：生成脚本
kd step --platform xiaohongshu --step 6

# 仅执行子任务7：合理性检查
kd step --platform xiaohongshu --step 7
```

### 批量生成脚本（仅子任务6）

```python
from kd import ScriptGenerator

gen = ScriptGenerator(
    platform="xiaohongshu",
    duration="2-3min",
    keywords=["采摘", "农家菜", "慢生活"]
)
scripts = gen.generate(count=5)
```

## 完整10步流程

| 步骤 | 名称 | 说明 | 输出 |
|:---:|:---|:---|:---|
| 1 | 搜索目标平台爆款 | 随机抽取关键词，搜索爆款 | 选定的爆款列表 |
| 2 | 读取平台规则 | 读取平台运营规则文档 | 关键规则摘要 |
| 3 | 搜索外网平台 | 搜索TikTok/YouTube爆款 | 外网爆款参考 |
| 4 | 同质化检查 | 检查避免与已有脚本重复 | 需避开主题清单 |
| 5 | 格式检查 | 现场读取Excel实际格式 | 格式确认清单 |
| 6 | 生成脚本 | 生成差异化脚本 | 完整脚本 |
| 7 | 合理性检查 | 多维度检查并修改 | 检查清单+修改记录 |
| 8 | 更新文案库 | 脚本写入Excel | 写入确认清单 |
| 9 | 全面检查对比 | Python验证写入结果 | 验证报告 |
| 10 | 提交报告 | 生成并保存执行报告 | Markdown报告 |

**注意：**
- 步骤1的关键词池：用户配置（`config/platforms.json`）
- 步骤2的平台规则：用户通过"规则更新系列"生成
- 步骤4的已有脚本：从用户配置的文案库路径读取

## 灵动参数配置

### 核心参数

| 参数 | 默认值 | 说明 | 配置位置 |
|:---|:---:|:---|:---|
| `total_duration` | "2-3min" | 总时长 | 命令行参数 |
| `segment_duration` | "3-12s" | 单分镜时长范围 | `config/platforms.json` |
| `segments_count` | 自动计算 | 分镜数量 | 根据时长自动计算 |

### 分镜时长分配模式

根据总时长自动分配，遵循"开头快、中间稳、结尾慢"原则：

**示例（小红书，2-3分钟）：**
- 开场：3-5秒（快速吸引）
- 主体：6-10秒（内容展开）
- 结尾：10-12秒（升华收尾）

### 内容详细度参数

| 参数 | 默认值 | 说明 |
|:---|:---:|:---|
| `shot_min_chars` | 20 | C列-镜头最少字数 |
| `movement_min_chars` | 15 | D列-运镜最少字数 |
| `technique_min_chars` | 15 | E列-技巧最少字数 |
| `scene_min_chars` | 20 | F列-画面最少字数 |
| `line_min_chars` | 30 | G列-台词最少字数 |
| `sound_min_chars` | 15 | H列-音效最少字数 |

**修改位置：** `config/platforms.json` → `content_requirements.columns`

## 文案库文件

**路径设置：** 首次使用需配置

```
你的文案库目录/
├── 小红书文案库.xlsx
├── 抖音文案库.xlsx
└── 视频号文案库.xlsx
```

**配置命令：**
```bash
kd config set copy_library_path "路径"
```

## 飞书报告保存

**空间ID设置：** 首次使用需配置

- **配置命令：** `kd config set report_space_id "你的空间ID"`
- **命名格式：** `YYYY-MM-DD-快导-平台名称`
- **示例：** `2026-04-22-快导-小红书`

**空间ID获取：** 飞书知识库 → 空间设置 → 复制空间ID

## 规则更新系列

**用途：** 生成/更新平台运营规则文档

```bash
# 更新小红书规则
kd rules --platform xiaohongshu

# 更新抖音规则
kd rules --platform douyin

# 更新视频号规则
kd rules --platform shipinhao
```

**规则文档位置：** `references/platform_rules/`

**初始状态：** 已提供3个平台的规则模板，用户可根据实际运营经验更新

### 规则文档说明

每个平台的规则文档包含：
- 平台基础信息（用户画像、内容风格）
- 核心规则（完播率、原创要求、违规红线）
- 文案规范（标题要求、字数要求、语言风格）
- 拍摄建议（画面要求、运镜技巧）

**查看规则：**
```bash
# 查看小红书规则
kd refs show --platform xiaohongshu

# 编辑规则（直接编辑文件）
nano references/platform_rules/xiaohongshu_rules.md
```

## 错误处理

- **单步超时：** 5分钟
- **出错处理：** 立即停止，通知用户错误详情
- **数据安全：** 写入前自动备份

## 跨平台使用说明

### 不同系统测试脚本使用

根据您的操作系统选择对应的测试脚本（文件名与scripts目录核心模块对应）：

| 核心模块 | Windows | macOS | Linux |
|:---|:---|:---|:---|
| `config_manager.py` | `config_manager_win.py` | `config_manager_mac.py` | `config_manager_linux.py` |
| `excel_manager.py` | `excel_manager_win.py` | `excel_manager_mac.py` | `excel_manager_linux.py` |
| `format_checker.py` | `format_checker_win.py` | `format_checker_mac.py` | `format_checker_linux.py` |
| `script_generator.py` | `script_generator_win.py` | `script_generator_mac.py` | `script_generator_linux.py` |

#### 使用步骤

**Windows用户（默认）：**
```bash
cd tests
python config_manager_win.py
python excel_manager_win.py
```

**macOS用户：**
```bash
cd tests
# 从mac目录复制到根目录
cp mac/config_manager_mac.py .
python config_manager_mac.py
```

**Linux用户：**
```bash
cd tests
# 从linux目录复制到根目录
cp linux/config_manager_linux.py .
python config_manager_linux.py
```

### 目录结构

```
tests/
├── config_manager_win.py      # Windows版本（默认）
├── excel_manager_win.py
├── format_checker_win.py
├── script_generator_win.py
├── __init__.py
├── mac/                         # macOS版本
│   ├── config_manager_mac.py
│   ├── excel_manager_mac.py
│   ├── format_checker_mac.py
│   └── script_generator_mac.py
└── linux/                       # Linux版本
    ├── config_manager_linux.py
    ├── excel_manager_linux.py
    ├── format_checker_linux.py
    └── script_generator_linux.py
```

**文件名对应规则：**
- Windows版本: `{模块名}_win.py`
- macOS版本: `{模块名}_mac.py`
- Linux版本: `{模块名}_linux.py`

**使用提示：** 根据系统复制对应版本的测试脚本到根目录即可直接使用。

## 版本历史

| 版本 | 日期 | 更新内容 |
|:---:|:---:|:---|
| 1.0.0 | 2026-04-22 | 初始版本，支持3平台，单次任务模式 |

## 配置文件说明

| 文件 | 用途 | 可修改内容 |
|:---|:---|:---|
| `config/platforms.json` | 平台参数 | 时长、字数、关键词、行业模板 |
| `config/workflow.json` | 流程配置 | 步骤定义、超时设置 |
| `config/templates.json` | 生成模板 | 提示词、时长分配模式 |

## 更多帮助

```bash
# 查看帮助
kd --help

# 查看平台配置
kd config show --platform xiaohongshu

# 验证配置
kd config validate
```

---

## 快速故障排查

| 问题 | 可能原因 | 解决方案 |
|:---|:---|:---|
| 导入错误 `ModuleNotFoundError: No module named 'openpyxl'` | 未安装依赖 | `pip install -r requirements.txt` 或 `pip install openpyxl` |
| 导入错误 `ModuleNotFoundError: No module named 'scripts'` | Python路径问题 | 确保在 `kd/` 根目录运行，或添加 `sys.path.insert(0, r'C:\\Users\\kkk49\\.agents\\skills\\kd')` |
| Excel写入失败 `Permission denied` | Excel文件被占用 | 关闭Excel后再重试 |
| Excel写入失败 `FileNotFoundError` | 目录不存在 | 确保路径存在，或让程序自动创建 |
| 配置未生效 `KeyError: 'copy_library_path'` | 配置文件未初始化 | 运行配置设置命令或检查 `config/user_config.json` 是否存在 |
| 飞书上传失败 `Permission denied` | 权限未开通 | 运行 `python scripts/feishu_permission_helper.py` 开通权限 |
| 飞书上传失败 `Space not found` | 空间ID错误 | 检查 `config/user_config.json` 中的 `report_space_id` 是否正确 |
| 搜索超时 `TimeoutError` | 网络不稳定 | 检查网络连接，或跳过搜索手动提供爆款标题 |
| 生成脚本为空 `scripts is empty` | 提示词参数缺失 | 检查 `config/templates.json` 和 `prompts/` 目录下模板文件是否完整 |
| 格式检查失败 `Format mismatch` | Excel格式变更 | 重新执行 Step 5 格式扫描 |
| 中文乱码 | 编码问题（Windows） | 使用 Python 脚本读取文件，而非直接查看 |
| Python版本不兼容 | Python < 3.7 | 升级到 Python 3.7+ |

### Windows 用户特别提醒

1. **路径分隔符**：使用双反斜杠 `\\` 或原始字符串 `r'C:\path'`
   ```python
   # ❌ 错误
   path = "C:\\Users\\name\\file.xlsx"
   
   # ✅ 正确
   path = r"C:\\Users\\name\\file.xlsx"
   path = "C:\\\\Users\\\\name\\\\file.xlsx"
   ```

2. **中文文件名**：PowerShell 可能显示乱码，使用 Python 脚本读取
   ```python
   import os
   files = os.listdir(r"F:\\vlog\\JT\\idea")
   for f in files:
       print(f)  # 正确显示中文
   ```

3. **Excel被占用**：确保生成脚本时 Excel 文件已关闭

### 调试模式

如需详细输出调试信息，在 Python 代码中添加：

```python
import logging
logging.basicConfig(level=logging.DEBUG)
```

---

## 活动配置（v1.1.0新增）

快导支持通过自然语言管理活动，用于自动匹配脚本关联活动。

### 配置方式

#### 方式1：自然语言命令（推荐）

```python
from scripts.activity_manager import ActivityManager

manager = ActivityManager()

# 添加活动
manager.execute_command(
    manager.parse_natural_language("添加活动：春节特惠，关键词：春节、过年、团圆")
)

# 列出所有活动
manager.execute_command(
    manager.parse_natural_language("列出所有活动")
)

# 查询活动
manager.execute_command(
    manager.parse_natural_language("查询活动：春节")
)

# 删除活动
manager.execute_command(
    manager.parse_natural_language("删除活动：春节特惠")
)
```

#### 方式2：直接编辑配置文件

编辑 `config/platforms.json`，在 `activities` 部分添加：

```json
"activities": {
  "list": [
    {
      "id": "act_1",
      "name": "春节特惠",
      "keywords": ["春节", "过年", "团圆"],
      "applicable_platforms": ["xiaohongshu", "douyin", "shipinhao", "pyq"],
      "note": "春节期间推广活动"
    },
    {
      "id": "act_2", 
      "name": "枇杷采摘季",
      "keywords": ["枇杷", "采摘", "太平镇"],
      "applicable_platforms": ["xiaohongshu", "douyin"],
      "note": "5-6月枇杷采摘活动"
    }
  ],
  "user_configured": true
}
```

### 自动匹配规则

生成脚本时，系统会根据脚本主题自动匹配活动：
- 活动名称匹配：+10分
- 关键词匹配：每个+5分
- 平台不匹配：0分（排除）

得分最高的活动会被自动填入Excel的L列（关联活动）。

### 默认显示

如未配置任何活动，L列显示：
```
日常推广，当前未设置activities
```

---

## 联系我们

如有问题或建议，欢迎交流：

- **微信号：** huitouyoujianta
- **用途：** 快导(KD)技能使用咨询、功能建议、技术交流

欢迎加微信交流学习！


path: references/platform_rules/README.md
content: # 平台规则文档索引

本目录存放各平台的运营规则文档，用于快导系列任务执行时的规则参考。

---

## ⚠️ 初始状态

**本目录初始为空，没有预设规则文档。**

规则文档需要用户自行创建或生成。

---

## 规则文档位置

| 平台 | 文件名 |
|:---|:---|
| 小红书 | `xiaohongshu_rules.md` |
| 抖音 | `douyin_rules.md` |
| 视频号 | `shipinhao_rules.md` |

---

## 规则文档内容建议

规则文档建议包含以下内容：

1. **时长要求** - 总时长、分镜时长、分镜数量
2. **核心指标** - 完播率、点赞、评论、转发、收藏优先级
3. **引流限制** - 平台允许的引流方式
4. **原创要求** - 原创内容占比、真人出镜等
5. **互动率要求** - 冷启动期互动率标准
6. **违规红线** - 禁止内容、敏感话题
7. **文案要求** - 标题规则、内容风格、标签建议

---

## 使用方式

快导系列任务会自动读取本目录的规则文档（如存在）：

```
子任务2：读取平台规则
    ↓
检查 references/platform_rules/<platform>_rules.md 是否存在
    ↓
如存在：读取并输出7项关键规则摘要
如不存在：提示用户创建规则文档
```

---

## 目录路径

`references/platform_rules/`

---

**注意：** 本目录不包含预设规则，由用户根据实际运营需求自行创建。


path: references/README.md
content: # References 目录说明

本目录用于存放快导(KD) Skill运行过程中生成的参考文档和数据文件。

## 目录结构

```
references/
├── platform_rules/          # 平台运营规则文档
│   ├── xiaohongshu_rules.md
│   ├── douyin_rules.md
│   └── shipinhao_rules.md
├── trending/                # 爆款内容缓存
│   ├── xiaohongshu_trending.json
│   ├── douyin_trending.json
│   └── shipinhao_trending.json
├── external/                # 外网爆款参考
│   └── tiktok_trending.json
└── README.md               # 本文件
```

## 子目录说明

### platform_rules/ - 平台运营规则

**用途：** 存放各平台运营规则文档

**生成方式：** 通过 `kd rules` 命令生成/更新

**文件格式：** Markdown文档

**内容示例：**
```markdown
# 小红书平台运营规则（2026年4月）

## 核心规则
- 时长要求: 2-3分钟
- 完播率: > 40%
- 原创要求: > 60%
- 违规红线: 虚假宣传、侵权问题

## 内容建议
- 攻略型内容优先
- 图文结合形式
- 实用价值导向
```

**初始状态：** 空目录，首次运行规则更新系列时自动生成

### trending/ - 爆款内容缓存

**用途：** 缓存搜索到的平台爆款内容

**生成方式：** 快导系列任务执行时自动保存

**文件格式：** JSON

**缓存策略：**
- 保留最近30天的爆款数据
- 超过30天自动清理
- 用于避免重复搜索相同内容

### external/ - 外网爆款参考

**用途：** 存放TikTok/YouTube等平台爆款参考

**生成方式：** 快导系列子任务3执行时保存

**文件格式：** JSON

**使用场景：**
- 获取外网创意灵感
- 参考国际化内容趋势

## 文件命名规范

| 类型 | 命名格式 | 示例 |
|:---|:---|:---|
| 规则文档 | `{platform}_rules.md` | `xiaohongshu_rules.md` |
| 爆款缓存 | `{platform}_trending_{YYYYMMDD}.json` | `douyin_trending_20260422.json` |
| 外网参考 | `tiktok_trending_{YYYYMMDD}.json` | `tiktok_trending_20260422.json` |

## 自动管理

### 数据保留策略

| 数据类型 | 保留时间 | 清理方式 |
|:---|:---:|:---|
| 规则文档 | 永久 | 手动管理 |
| 爆款缓存 | 30天 | 自动清理 |
| 外网参考 | 30天 | 自动清理 |

### 手动清理命令

```bash
# 清理所有过期的缓存文件
kd refs clean --expired

# 清理指定平台的缓存
kd refs clean --platform xiaohongshu

# 查看缓存占用空间
kd refs size
```

## 配置说明

### 规则文档保存路径

默认路径：`references/platform_rules/`

自定义路径：
```bash
kd config set rules_path "你的自定义路径"
```

### 缓存路径

默认路径：`references/trending/` 和 `references/external/`

**注意：** 缓存路径不支持自定义，固定在本目录下

## 备份建议

**重要数据：**
- ✅ 规则文档（建议备份）
- ⚠️ 爆款缓存（可选备份）
- ⚠️ 外网参考（可选备份）

**备份命令：**
```bash
# 备份规则文档
kd refs backup --platform xiaohongshu

# 备份所有数据
kd refs backup --all
```

## 注意事项

1. **不要手动删除** `platform_rules/` 中的规则文档，可能导致任务失败
2. **定期清理** 过期缓存，避免占用过多磁盘空间
3. **规则文档** 建议定期备份，防止误删

## 版本历史

| 版本 | 日期 | 说明 |
|:---:|:---:|:---|
| 1.0.0 | 2026-04-22 | 初始版本，支持3平台规则存储 |


path: requirements.txt
content: # 快导(KD) - Python依赖
# 安装: pip install -r requirements.txt

# Excel文件操作
openpyxl>=3.0.0

# 可选依赖（用于增强功能）
# requests>=2.25.0  # HTTP请求（如需要网络搜索API）
# python-dotenv>=0.19.0  # 环境变量管理


path: scripts/activity_manager.py
content: """
活动管理器 - 自然语言活动配置管理
支持用户通过自然语言添加、删除、查询活动
"""

import json
import re
from typing import Dict, List, Any, Optional
from pathlib import Path


class ActivityManager:
    """活动配置管理器"""
    
    def __init__(self, config_path: str = None):
        """
        初始化活动管理器
        
        Args:
            config_path: 配置文件路径，默认为平台配置文件
        """
        if config_path:
            self.config_path = Path(config_path)
        else:
            # 默认路径：技能目录下的 config/platforms.json
            self.config_path = Path(__file__).parent.parent / 'config' / 'platforms.json'
        
        self.config = self._load_config()
        self.activities = self.config.get('activities', {})
        self.activity_list = self.activities.get('list', [])
    
    def _load_config(self) -> dict:
        """加载配置文件"""
        if not self.config_path.exists():
            return {'activities': {'list': []}}
        
        try:
            with open(self.config_path, 'r', encoding='utf-8') as f:
                return json.load(f)
        except Exception as e:
            print(f"加载配置失败: {e}")
            return {'activities': {'list': []}}
    
    def _save_config(self):
        """保存配置到文件"""
        try:
            # 更新配置
            self.config['activities'] = self.activities
            
            # 写入文件
            with open(self.config_path, 'w', encoding='utf-8') as f:
                json.dump(self.config, f, ensure_ascii=False, indent=2)
            
            return True
        except Exception as e:
            print(f"保存配置失败: {e}")
            return False
    
    def parse_natural_language(self, command: str) -> dict:
        """
        解析自然语言命令
        
        支持的命令格式：
        - "添加活动：春节特惠，关键词：春节、过年、团圆"
        - "删除活动：春节特惠"
        - "列出所有活动"
        - "查询活动：春节"
        
        Args:
            command: 用户输入的自然语言命令
            
        Returns:
            解析结果字典
        """
        command = command.strip()
        
        # 识别命令类型
        patterns = {
            'add': r'(?:添加|新建|创建|增加)(?:一个)?(?:活动|推广|促销)[：:]?\s*(.+)',
            'delete': r'(?:删除|移除|去掉)(?:活动|推广|促销)[：:]?\s*(.+)',
            'list': r'(?:列出|查看|显示|查询)(?:所有)?(?:的)?(?:活动|推广|促销)',
            'query': r'(?:查询|查找|搜索)(?:活动|推广|促销)[：:]?\s*(.+)'
        }
        
        for action, pattern in patterns.items():
            match = re.search(pattern, command, re.IGNORECASE)
            if match:
                if action in ['add']:
                    return self._parse_add_command(match.group(1))
                elif action == 'delete':
                    return {'action': 'delete', 'name': match.group(1).strip()}
                elif action == 'list':
                    return {'action': 'list'}
                elif action == 'query':
                    return {'action': 'query', 'name': match.group(1).strip()}
        
        return {'action': 'unknown', 'error': '无法识别命令，请使用"添加活动"、"删除活动"、"列出活动"或"查询活动"'}
    
    def _parse_add_command(self, content: str) -> dict:
        """解析添加命令"""
        # 提取活动名称
        name_match = re.search(r'^([^，,]+)', content)
        if not name_match:
            return {'action': 'error', 'error': '无法提取活动名称'}
        
        name = name_match.group(1).strip()
        
        # 提取关键词
        keywords = []
        keyword_patterns = [
            r'(?:关键词|关键字|标签)[：:]\s*([^，,]+(?:[，,][^，,]+)*)',
            r'(?:关键词|关键字|标签)[:=]\s*([^，,]+(?:[，,][^，,]+)*)'
        ]
        
        for pattern in keyword_patterns:
            kw_match = re.search(pattern, content)
            if kw_match:
                kw_text = kw_match.group(1)
                keywords = [k.strip() for k in re.split(r'[，,、]', kw_text)]
                break
        
        # 提取适用平台
        platforms = ['xiaohongshu', 'douyin', 'shipinhao', 'pyq']  # 默认全平台
        platform_patterns = [
            r'(?:适用平台|平台)[：:]\s*([^，,]+(?:[，,][^，,]+)*)',
            r'(?:适用|用于)[：:]\s*([^，,]+(?:[，,][^，,]+)*)'
        ]
        
        for pattern in platform_patterns:
            pf_match = re.search(pattern, content)
            if pf_match:
                pf_text = pf_match.group(1)
                platforms = self._parse_platforms(pf_text)
                break
        
        return {
            'action': 'add',
            'name': name,
            'keywords': keywords,
            'platforms': platforms
        }
    
    def _parse_platforms(self, text: str) -> List[str]:
        """解析平台名称"""
        platform_mapping = {
            '小红书': 'xiaohongshu',
            '抖音': 'douyin',
            '视频号': 'shipinhao',
            '朋友圈': 'pyq',
            '小红': 'xiaohongshu',
            '抖': 'douyin',
            '视': 'shipinhao',
            'pyq': 'pyq',
            '小红book': 'xiaohongshu'
        }
        
        result = []
        for name, code in platform_mapping.items():
            if name in text:
                result.append(code)
        
        # 如果没匹配到任何平台，默认全平台
        return result if result else ['xiaohongshu', 'douyin', 'shipinhao', 'pyq']
    
    def execute_command(self, parsed: dict) -> dict:
        """
        执行解析后的命令
        
        Args:
            parsed: parse_natural_language 返回的解析结果
            
        Returns:
            执行结果
        """
        action = parsed.get('action')
        
        if action == 'add':
            return self.add_activity(
                name=parsed.get('name'),
                keywords=parsed.get('keywords', []),
                platforms=parsed.get('platforms', ['xiaohongshu', 'douyin', 'shipinhao', 'pyq'])
            )
        elif action == 'delete':
            return self.delete_activity(parsed.get('name'))
        elif action == 'list':
            return self.list_activities()
        elif action == 'query':
            return self.query_activity(parsed.get('name'))
        else:
            return {'success': False, 'error': parsed.get('error', '未知命令')}
    
    def add_activity(self, name: str, keywords: List[str] = None, 
                    platforms: List[str] = None) -> dict:
        """
        添加活动
        
        Args:
            name: 活动名称
            keywords: 关键词列表
            platforms: 适用平台列表
            
        Returns:
            结果字典
        """
        # 检查是否已存在
        for act in self.activity_list:
            if act.get('name') == name:
                return {'success': False, 'error': f'活动"{name}"已存在'}
        
        # 生成ID
        activity_id = f"act_{len(self.activity_list) + 1}"
        
        # 创建活动
        new_activity = {
            'id': activity_id,
            'name': name,
            'keywords': keywords or [],
            'applicable_platforms': platforms or ['xiaohongshu', 'douyin', 'shipinhao', 'pyq'],
            'note': ''
        }
        
        self.activity_list.append(new_activity)
        
        # 标记为用户已配置
        self.activities['user_configured'] = True
        
        # 保存
        if self._save_config():
            return {
                'success': True,
                'message': f'活动"{name}"添加成功',
                'activity': new_activity
            }
        else:
            return {'success': False, 'error': '保存配置失败'}
    
    def delete_activity(self, name: str) -> dict:
        """
        删除活动
        
        Args:
            name: 活动名称
            
        Returns:
            结果字典
        """
        # 查找活动
        for i, act in enumerate(self.activity_list):
            if act.get('name') == name:
                # 删除
                del self.activity_list[i]
                
                # 保存
                if self._save_config():
                    return {
                        'success': True,
                        'message': f'活动"{name}"已删除'
                    }
                else:
                    return {'success': False, 'error': '保存配置失败'}
        
        return {'success': False, 'error': f'未找到活动"{name}"'}
    
    def list_activities(self) -> dict:
        """
        列出所有活动
        
        Returns:
            结果字典
        """
        # 过滤掉示例活动
        real_activities = [a for a in self.activity_list if a.get('id') != 'example']
        
        return {
            'success': True,
            'count': len(real_activities),
            'activities': real_activities,
            'message': f'共 {len(real_activities)} 个活动' if real_activities else '暂无配置的活动'
        }
    
    def query_activity(self, name: str) -> dict:
        """
        查询活动
        
        Args:
            name: 活动名称（支持模糊匹配）
            
        Returns:
            结果字典
        """
        matches = []
        
        for act in self.activity_list:
            if name.lower() in act.get('name', '').lower():
                matches.append(act)
        
        return {
            'success': True,
            'count': len(matches),
            'activities': matches,
            'message': f'找到 {len(matches)} 个匹配活动' if matches else '未找到匹配活动'
        }
    
    def match_activity(self, script_theme: str, platform: str = None) -> Optional[dict]:
        """
        根据脚本主题自动匹配活动
        
        Args:
            script_theme: 脚本主题
            platform: 当前平台（可选）
            
        Returns:
            匹配的活动，无匹配则返回 None
        """
        if not script_theme:
            return None
        
        script_theme = script_theme.lower()
        
        # 过滤掉示例活动
        real_activities = [a for a in self.activity_list if a.get('id') != 'example']
        
        if not real_activities:
            return None
        
        # 按关键词匹配度排序
        scored_activities = []
        
        for activity in real_activities:
            score = 0
            
            # 检查活动名称匹配
            if activity.get('name', '').lower() in script_theme:
                score += 10
            
            # 检查关键词匹配
            for keyword in activity.get('keywords', []):
                if keyword.lower() in script_theme:
                    score += 5
            
            # 平台过滤
            if platform:
                if platform not in activity.get('applicable_platforms', []):
                    score = 0  # 不匹配的平台得0分
            
            if score > 0:
                scored_activities.append((score, activity))
        
        # 返回得分最高的活动
        if scored_activities:
            scored_activities.sort(key=lambda x: x[0], reverse=True)
            return scored_activities[0][1]
        
        return None
    
    def get_default_activity(self) -> str:
        """获取默认活动显示文本"""
        real_activities = [a for a in self.activity_list if a.get('id') != 'example']
        
        if real_activities:
            return real_activities[0].get('name', '日常推广')
        
        return '日常推广，当前未设置activities'


# 便捷函数
def get_activity_manager(config_path: str = None) -> ActivityManager:
    """获取活动管理器实例"""
    return ActivityManager(config_path)


# 测试代码
if __name__ == "__main__":
    manager = ActivityManager()
    
    # 测试自然语言解析
    test_commands = [
        "添加活动：春节特惠，关键词：春节、过年、团圆、年夜饭",
        "添加活动：枇杷采摘季，关键词：枇杷、采摘、太平镇",
        "列出所有活动",
        "查询活动：枇杷",
        "删除活动：春节特惠"
    ]
    
    for cmd in test_commands:
        print(f"\n命令: {cmd}")
        parsed = manager.parse_natural_language(cmd)
        print(f"解析: {parsed}")
        
        if parsed.get('action') in ['add', 'delete', 'list', 'query']:
            result = manager.execute_command(parsed)
            print(f"执行: {result}")


path: scripts/config_manager.py
content: """
配置管理器 - 管理用户配置和平台参数
"""

import json
import os
from pathlib import Path
from typing import Dict, Any, Optional


class ConfigManager:
    """管理快导Skill的所有配置"""
    
    CONFIG_FILE = "config/platforms.json"
    
    def __init__(self, skill_path: str = None):
        """
        初始化配置管理器
        
        Args:
            skill_path: Skill根目录路径，默认从环境变量或推断
        """
        if skill_path is None:
            # 推断Skill路径
            current_file = Path(__file__).resolve()
            self.skill_path = current_file.parent.parent
        else:
            self.skill_path = Path(skill_path)
        
        self.config_path = self.skill_path / self.CONFIG_FILE
        self._config_cache = None
    
    def load_config(self) -> Dict[str, Any]:
        """加载完整配置"""
        if self._config_cache is None:
            with open(self.config_path, 'r', encoding='utf-8') as f:
                self._config_cache = json.load(f)
        return self._config_cache
    
    def get_platform_config(self, platform: str) -> Dict[str, Any]:
        """
        获取指定平台的配置
        
        Args:
            platform: 平台标识（xiaohongshu/douyin/shipinhao）
            
        Returns:
            平台配置字典
        """
        config = self.load_config()
        platform_config = config.get("platforms", {}).get(platform, {})
        
        if not platform_config:
            raise ValueError(f"未找到平台配置: {platform}")
        
        # 合并全局设置
        global_settings = config.get("global_settings", {})
        platform_config["_global"] = global_settings
        
        return platform_config
    
    def get_config(self) -> Dict[str, Any]:
        """
        获取完整配置
        
        Returns:
            完整配置字典
        """
        return self.load_config()
    
    def get_user_config(self, key: str) -> Any:
        """
        获取用户配置项
        
        Args:
            key: 配置项名称
            
        Returns:
            配置值
        """
        config = self.load_config()
        global_settings = config.get("global_settings", {})
        
        value = global_settings.get(key)
        
        # 检查必须配置项
        required_keys = [
            "copy_library_path",
            "report_space_id", 
            "rules_path"
        ]
        
        if key in required_keys and not value:
            raise ConfigNotSetError(
                f"配置项 '{key}' 未设置。\n"
                f"请运行: kd config set {key} '你的路径'"
            )
        
        return value
    
    def set_user_config(self, key: str, value: Any) -> bool:
        """
        设置用户配置项
        
        Args:
            key: 配置项名称
            value: 配置值
            
        Returns:
            是否设置成功
        """
        config = self.load_config()
        
        if key not in config.get("global_settings", {}):
            raise ValueError(f"未知的配置项: {key}")
        
        config["global_settings"][key] = value
        
        # 保存配置
        try:
            with open(self.config_path, 'w', encoding='utf-8') as f:
                json.dump(config, f, ensure_ascii=False, indent=2)
            self._config_cache = config
            return True
        except Exception as e:
            raise ConfigSaveError(f"保存配置失败: {e}")
    
    def validate_config(self) -> Dict[str, bool]:
        """
        验证所有必需配置是否已设置
        
        Returns:
            配置项验证结果字典
        """
        required_configs = [
            "copy_library_path",
            "report_space_id",
            "rules_path"
        ]
        
        results = {}
        for key in required_configs:
            try:
                value = self.get_user_config(key)
                results[key] = bool(value)
            except ConfigNotSetError:
                results[key] = False
        
        return results
    
    def get_excel_path(self, platform: str) -> str:
        """
        获取指定平台的文案库Excel路径
        
        Args:
            platform: 平台标识
            
        Returns:
            Excel文件完整路径
        """
        library_path = self.get_user_config("copy_library_path")
        config = self.load_config()
        file_naming = config.get("global_settings", {}).get(
            "file_naming", 
            "{platform}文案库.xlsx"
        )
        
        platform_name = config.get("platforms", {}).get(platform, {}).get("name", platform)
        filename = file_naming.format(platform=platform_name)
        
        return os.path.join(library_path, filename)
    
    def calculate_segments(self, platform: str, total_duration: str) -> int:
        """
        根据总时长计算分镜数量
        
        Args:
            platform: 平台标识
            total_duration: 总时长描述（如"2-3min"）
            
        Returns:
            分镜数量
        """
        platform_config = self.get_platform_config(platform)
        duration_config = platform_config.get("duration", {})
        
        segment_range = duration_config.get("segment_seconds", {})
        min_seg = segment_range.get("min", 3)
        max_seg = segment_range.get("max", 12)
        avg_seg = (min_seg + max_seg) / 2
        
        # 解析总时长
        total_config = duration_config.get("total_seconds", {})
        min_total = total_config.get("min", 120)
        max_total = total_config.get("max", 180)
        avg_total = (min_total + max_total) / 2
        
        # 计算分镜数量
        segments_count = int(avg_total / avg_seg)
        
        return segments_count


class ConfigNotSetError(Exception):
    """配置项未设置错误"""
    pass


class ConfigSaveError(Exception):
    """配置保存错误"""
    pass


# 便捷函数
def get_config_manager(skill_path: str = None) -> ConfigManager:
    """获取配置管理器实例"""
    return ConfigManager(skill_path)


def validate_platform_keywords(platform: str) -> bool:
    """
    验证平台关键词是否已配置
    
    Args:
        platform: 平台标识
        
    Returns:
        是否已配置关键词
    """
    config_mgr = get_config_manager()
    platform_config = config_mgr.get_platform_config(platform)
    keywords = platform_config.get("keywords", [])
    return len(keywords) > 0


path: scripts/duration_calculator.py
content: """
时长计算器 - 智能计算分镜建议时长
基于台词、运镜类型自动计算合理的分镜时长
"""

from typing import Dict, List, Any, Tuple


class DurationCalculator:
    """智能时长计算器"""
    
    def __init__(self, config: dict):
        """
        初始化时长计算器
        
        Args:
            config: 平台配置字典，包含 duration_policy 和 calculation_rules
        """
        self.config = config
        self.policy = config.get('duration_policy', config)  # 兼容两种配置结构
        self.rules = self.policy.get('calculation_rules', {
            'speech_rate': 0.25,
            'motion_base': {
                'static': 2,
                'push_pull': 3,
                'pan_tilt': 4,
                'complex': 6,
                'drone': 8
            },
            'buffer_seconds': 1,
            'min_motion_time': 2
        })
    
    def calculate_speech_time(self, line: str) -> float:
        """
        计算台词所需时长
        
        Args:
            line: 台词内容
            
        Returns:
            建议时长（秒）
        """
        if not line or not isinstance(line, str):
            return 0
        
        char_count = len(line.strip())
        speech_rate = self.rules.get('speech_rate', 0.25)
        
        return char_count * speech_rate
    
    def calculate_motion_time(self, movement: str) -> float:
        """
        根据运镜类型计算所需时长
        
        Args:
            movement: 运镜描述
            
        Returns:
            建议时长（秒）
        """
        if not movement or not isinstance(movement, str):
            return self.rules.get('motion_base', {}).get('static', 2)
        
        movement = movement.lower()
        motion_base = self.rules.get('motion_base', {})
        
        # 运镜类型匹配规则
        movement_patterns = {
            'static': ['固定', '定', '静止', 'static'],
            'push_pull': ['推', '拉', '推近', '推远', 'zoom'],
            'pan_tilt': ['摇', '移', '跟随', '跟随', 'pan', 'tilt'],
            'complex': ['环绕', '升降', '复杂', '复杂运镜', 'orbit', 'crane'],
            'drone': ['航拍', '俯视', '无人机', 'drone', 'aerial']
        }
        
        # 匹配运镜类型
        for motion_type, keywords in movement_patterns.items():
            for keyword in keywords:
                if keyword in movement:
                    return motion_base.get(motion_type, 3)
        
        # 默认使用固定镜头时长
        return motion_base.get('static', 2)
    
    def calculate_scene_duration(self, scene: dict) -> dict:
        """
        计算单个分镜的建议时长
        
        Args:
            scene: 分镜数据字典，包含 line, movement_desc, time 等字段
            
        Returns:
            计算结果字典
        """
        # 提取字段（支持多种字段名）
        line = scene.get('line', scene.get('台词', scene.get('narration', '')))
        movement = scene.get('movement_desc', scene.get('运镜', scene.get('movement', '')))
        time_str = scene.get('time', scene.get('时间段', ''))
        
        # 计算各项时长
        speech_time = self.calculate_speech_time(line)
        motion_time = self.calculate_motion_time(movement)
        
        # 基础时长 = max(台词时长, 运镜时长) + 缓冲
        buffer_seconds = self.rules.get('buffer_seconds', 1)
        base_duration = max(speech_time, motion_time) + buffer_seconds
        
        # 检查是否在平台限制范围内
        segment_limits = self.policy.get('segment_duration', {})
        min_duration = segment_limits.get('min', 3)
        max_duration = segment_limits.get('max', 12)
        
        # 最终建议时长
        recommended = max(min_duration, min(max_duration, base_duration))
        
        # 解析当前标注的时长
        labeled_duration = self._parse_labeled_duration(time_str)
        
        # 检查是否匹配
        match = self._check_duration_match(labeled_duration, recommended)
        
        return {
            'speech_time': round(speech_time, 1),
            'motion_time': round(motion_time, 1),
            'buffer': buffer_seconds,
            'recommended': round(recommended, 1),
            'labeled': labeled_duration,
            'match': match,
            'suggestion': self._generate_suggestion(labeled_duration, recommended, match)
        }
    
    def _parse_labeled_duration(self, time_str: str) -> float:
        """
        解析当前标注的时长
        
        Args:
            time_str: 时间段字符串，如 "0-5s", "5-10s"
            
        Returns:
            时长（秒）
        """
        if not time_str or not isinstance(time_str, str):
            return 0
        
        # 提取数字范围，如 "0-5s" -> [0, 5]
        import re
        numbers = re.findall(r'(\d+)', time_str)
        
        if len(numbers) >= 2:
            try:
                start = int(numbers[0])
                end = int(numbers[1])
                return end - start
            except (ValueError, IndexError):
                return 0
        
        return 0
    
    def _check_duration_match(self, labeled: float, recommended: float) -> bool:
        """
        检查标注时长是否与建议时长匹配
        
        规则：
        - 建议时长 ≥ 标注时长的60%
        - 建议时长可以更长（允许慢节奏）
        
        Args:
            labeled: 标注时长
            recommended: 建议时长
            
        Returns:
            是否匹配
        """
        if labeled == 0:
            return True  # 无标注时视为匹配
        
        return recommended >= labeled * 0.6
    
    def _generate_suggestion(self, labeled: float, recommended: float, match: bool) -> str:
        """生成调整建议"""
        if match:
            return "✓ 时长匹配"
        
        if labeled == 0:
            return f"建议设置为 {recommended}s"
        
        if recommended < labeled:
            return f"建议缩短至 {recommended}s 或补充内容以支撑 {labeled}s"
        
        return f"当前标注 {labeled}s，建议时长 {recommended}s"
    
    def optimize_script(self, scenes: List[dict], target_min: int = None, target_max: int = None) -> dict:
        """
        优化脚本时长 - 默认自动调整
        
        Args:
            scenes: 分镜列表
            target_min: 目标总时长最小值（可选）
            target_max: 目标总时长最大值（可选）
            
        Returns:
            优化结果字典
        """
        # 获取目标时长范围
        if target_min is None:
            target_min = self.policy.get('target_duration', {}).get('min', 120)
        if target_max is None:
            target_max = self.policy.get('target_duration', {}).get('max', 180)
        
        optimized_scenes = []
        current_time = 0
        total_labeled = 0
        
        for scene in scenes:
            calc = self.calculate_scene_duration(scene)
            
            # 自动调整：使用建议时长作为最终时间段
            if self.policy.get('auto_adjust', True):
                start_time = current_time
                end_time = current_time + int(calc['recommended'])
                
                # 更新时间段
                scene['time'] = f"{start_time}-{end_time}s"
                current_time = end_time
                
                # 保留计算详情到备注
                scene['_duration_calc'] = calc
            else:
                # 手动模式：仅添加计算结果
                scene['_duration_calc'] = calc
                current_time += calc['labeled'] if calc['labeled'] > 0 else calc['recommended']
            
            total_labeled += calc['labeled'] if calc['labeled'] > 0 else calc['recommended']
            optimized_scenes.append(scene)
        
        total_duration = current_time
        
        # 验证总时长
        total_match = target_min <= total_duration <= target_max
        
        # 生成建议
        suggestions = []
        if not total_match:
            if total_duration < target_min:
                suggestions.append(f"总时长 {total_duration}s 不足，建议增加分镜或延长单镜")
            elif total_duration > target_max:
                suggestions.append(f"总时长 {total_duration}s 超出，建议精简内容")
        
        return {
            'scenes': optimized_scenes,
            'total_duration': total_duration,
            'total_labeled': total_labeled,
            'target_range': f"{target_min}-{target_max}s",
            'match': total_match,
            'suggestions': suggestions
        }
    
    def get_duration_report(self, scenes: List[dict]) -> str:
        """
        生成时长计算报告
        
        Args:
            scenes: 分镜列表
            
        Returns:
            Markdown 格式报告
        """
        lines = [
            "## 时长计算报告",
            "",
            "| 分镜 | 台词(秒) | 运镜(秒) | 缓冲(秒) | 建议时长 | 标注时长 | 匹配 |",
            "|:---:|:---:|:---:|:---:|:---:|:---:|:---:|"
        ]
        
        total_recommended = 0
        total_labeled = 0
        all_match = True
        
        for i, scene in enumerate(scenes, 1):
            calc = self.calculate_scene_duration(scene)
            total_recommended += calc['recommended']
            total_labeled += calc['labeled'] if calc['labeled'] > 0 else calc['recommended']
            if not calc['match']:
                all_match = False
            
            lines.append(
                f"| {i} | {calc['speech_time']:.1f} | {calc['motion_time']:.1f} | {calc['buffer']} | "
                f"{calc['recommended']:.1f}s | {calc['labeled']:.1f}s | {'✓' if calc['match'] else '✗'} |"
            )
        
        lines.extend([
            "",
            f"**总计**: 建议 {total_recommended:.1f}s | 标注 {total_labeled:.1f}s | 整体 {'✓ 匹配' if all_match else '✗ 不匹配'}"
        ])
        
        return "\n".join(lines)


# 测试代码
if __name__ == "__main__":
    # 示例配置
    config = {
        'target_duration': {'min': 120, 'max': 180},
        'segment_duration': {'min': 6, 'max': 15},
        'auto_adjust': True,
        'calculation_rules': {
            'speech_rate': 0.25,
            'motion_base': {
                'static': 2,
                'push_pull': 3,
                'pan_tilt': 4,
                'complex': 6,
                'drone': 8
            },
            'buffer_seconds': 1
        }
    }
    
    calculator = DurationCalculator(config)
    
    # 示例分镜
    scenes = [
        {
            'line': '欢迎来到嘉泰苑，这里是太平枇杷第一镇。',
            'movement_desc': '固定镜头',
            'time': '0-5s'
        },
        {
            'line': '看这一树金黄的枇杷，又大又甜，每一颗都是阳光的味道。',
            'movement_desc': '缓慢推近特写',
            'time': '5-12s'
        }
    ]
    
    print(calculator.get_duration_report(scenes))
    print()
    print("优化结果:", calculator.optimize_script(scenes))


path: scripts/feishu_permission_helper.py
content: #!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
飞书权限批量开通助手
帮助用户一键生成权限配置并指导开通流程
"""

import json
import os
from pathlib import Path


class FeishuPermissionHelper:
    """飞书权限开通助手"""
    
    def __init__(self):
        self.skill_path = Path(__file__).parent.parent
        self.config_path = self.skill_path / "config" / "feishu_permissions.json"
        
    def load_permissions(self):
        """加载权限配置"""
        with open(self.config_path, 'r', encoding='utf-8') as f:
            return json.load(f)
    
    def generate_import_json(self):
        """生成飞书批量导入用的 JSON"""
        permissions = self.load_permissions()
        
        # 飞书批量导入格式
        import_data = {
            "scopes": permissions["scopes"]
        }
        
        return json.dumps(import_data, ensure_ascii=False, indent=2)
    
    def print_setup_guide(self):
        """打印开通指南"""
        permissions = self.load_permissions()
        
        guide = f"""
╔════════════════════════════════════════════════════════════════╗
║          快导(KD) - 飞书机器人权限开通指南                       ║
╚════════════════════════════════════════════════════════════════╝

📋 权限说明

本 Skill 需要以下飞书权限才能正常工作：

【应用身份权限 (tenant)】
{self._format_permissions(permissions['scopes']['tenant'])}

【用户身份权限 (user)】
{self._format_permissions(permissions['scopes']['user'])}

═══════════════════════════════════════════════════════════════════

🚀 开通步骤

步骤 1: 进入飞书开发者后台
  1. 打开 https://open.feishu.cn/app
  2. 选择你的应用

步骤 2: 批量导入权限
  1. 左侧导航 → "权限管理" → "开通权限"
  2. 点击 "批量导入/导出权限" 按钮
  3. 粘贴下方的 JSON 配置
  4. 点击 "下一步，确认新增权限"
  5. 确认无误后点击 "申请开通"

步骤 3: 发布应用
  1. 左侧导航 → "版本管理与发布" → "创建版本"
  2. 填写版本信息
  3. 点击 "保存" → "申请发布"

═══════════════════════════════════════════════════════════════════

📋 批量导入 JSON（复制以下内容）

{self.generate_import_json()}

═══════════════════════════════════════════════════════════════════

⚠️ 注意事项

1. 开通权限后需要等待审核（通常几分钟到几小时）
2. 如果权限不足，Step 10（保存报告到飞书）会失败
3. 失败时会自动保存到本地 reports/ 目录

🔧 验证权限

开通后运行以下命令验证：
  lark-cli auth login --as bot
  lark-cli wiki spaces list --as bot

如果命令成功执行，说明权限已正确开通。

═══════════════════════════════════════════════════════════════════
"""
        print(guide)
        
    def _format_permissions(self, permissions):
        """格式化权限列表"""
        lines = []
        for perm in permissions:
            lines.append(f"  • {perm}")
        return "\n".join(lines)
    
    def export_to_clipboard(self):
        """导出 JSON 到剪贴板（跨平台）"""
        import_data = self.generate_import_json()
        
        try:
            # Windows
            import subprocess
            subprocess.run(['clip'], input=import_data.encode('utf-8'), check=True)
            print("✅ 已复制到剪贴板")
        except:
            try:
                # macOS
                import subprocess
                subprocess.run(['pbcopy'], input=import_data.encode('utf-8'), check=True)
                print("✅ 已复制到剪贴板")
            except:
                # Linux 或其他
                print("⚠️ 请手动复制上面的 JSON 内容")


def main():
    """主函数"""
    helper = FeishuPermissionHelper()
    
    print("快导(KD) - 飞书权限开通助手\n")
    print("选择操作：")
    print("1. 显示完整开通指南")
    print("2. 仅显示批量导入 JSON")
    print("3. 导出 JSON 到剪贴板")
    print("4. 退出")
    
    choice = input("\n请输入选项 (1-4): ").strip()
    
    if choice == "1":
        helper.print_setup_guide()
    elif choice == "2":
        print("\n批量导入 JSON：\n")
        print(helper.generate_import_json())
    elif choice == "3":
        helper.export_to_clipboard()
    else:
        print("再见！")


if __name__ == "__main__":
    main()


path: scripts/__init__.py
content: """
快导(KD) Skill - Python工具脚本包
提供脚本生成、格式检查、Excel操作等功能
"""

import sys
import io

# Windows 编码修复 - 必须在所有导入之前
if sys.platform == 'win32':
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
    sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='replace')

__version__ = "1.0.0"
__author__ = "快导(KD)"

from .script_generator import ScriptGenerator
from .format_checker import FormatChecker
from .excel_manager import ExcelManager
from .config_manager import ConfigManager
from .feishu_permission_helper import FeishuPermissionHelper
from .workflow_manager import WorkflowManager

__all__ = [
    "ScriptGenerator",
    "FormatChecker",
    "ExcelManager",
    "ConfigManager",
    "FeishuPermissionHelper",
    "WorkflowManager"
]


path: setup.py
content: #!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
快导(KD) - 短视频脚本批量生成与管理
"""

from setuptools import setup, find_packages
from pathlib import Path

# 读取README
readme_path = Path(__file__).parent / "SKILL.md"
long_description = readme_path.read_text(encoding="utf-8") if readme_path.exists() else ""

setup(
    name="kd",
    version="1.0.0",
    description="快导(KD) - 短视频脚本批量生成与管理",
    long_description=long_description,
    long_description_content_type="text/markdown",
    author="User",
    python_requires=">=3.7",
    packages=find_packages(),
    install_requires=[
        "openpyxl>=3.0.0",
    ],
    extras_require={
        "dev": [
            "pytest>=6.0",
            "black>=21.0",
        ],
    },
    entry_points={
        "console_scripts": [
            "kd=kd:main",
        ],
    },
    classifiers=[
        "Development Status :: 4 - Beta",
        "Intended Audience :: End Users/Desktop",
        "License :: OSI Approved :: MIT License",
        "Programming Language :: Python :: 3",
        "Programming Language :: Python :: 3.7",
        "Programming Language :: Python :: 3.8",
        "Programming Language :: Python :: 3.9",
        "Programming Language :: Python :: 3.10",
    ],
)


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)