Skill: luckychay/xhs-text-cover (version 1.0.0)

--- name: xiaohongshu description: 小红书全能助手 — 文案生成、封面制作、内容发布与管理。当用户要求写小红书笔记、生成小红书文案/标题/封面、发小红书、搜索小红书、评论点赞收藏等任何小红书相关操作时使用。支持一站式从文案创作到自动发布的完整流程。封面图使用纯ImageMagick生成，无需API配置。 metadata: {"openclaw": {"emoji": "📕", "requires": {"bins": ["convert"], "anyBins": ["curl"]}}} --- # 📕 小红书全能助手 两大核心能力：**文案创作**（标题+正文+封面图）和 **平台操作**（发布+搜索+互动）。 文案创作默认使用当前对话的主模型，无需额外配置。 **重要提示**：当使用发布功能时，正文中不要包含以#开头的话题标签，所有话题标签都应通过`tags`参数传递给MCP服务。 --- ## 零、查看可用模型（仅当用户询问时） 当用户询问"有哪些模型"、"当前模型"、"可用模型"、"能用什么模型"时，读取配置文件展示： ```bash # 查看当前主模型 cat ~/.openclaw/openclaw.json | jq -r '.agents.defaults.model.primary // .agents.defaults.model // "未设置"' 2>/dev/null # 查看所有可用模型（提供商/模型ID - 名称） cat ~/.openclaw/openclaw.json | jq -r '.models.providers | to_entries[] | .key as $p | .value.models[]? | "\($p)/\(.id) - \(.name)"' 2>/dev/null ``` --- ## 一、文案创作流程 当用户要求写笔记、生成文案、创作小红书内容时，按 **标题 → 正文 → 封面图** 三步执行，每步需用户确认后再继续。 ### 1.1 生成标题 **优先使用当前对话模型直接生成**，参考 [references/title-guide.md]({baseDir}/references/title-guide.md) 中的规范生成5个不同风格的标题。 核心要求：每个标题使用不同风格，20字以内，含1-2个emoji，禁用平台禁忌词。 **备用方案**：如果用户明确配置了 `XHS_AI_API_KEY` 环境变量并要求使用指定 API，可调用脚本： ```bash bash {baseDir}/scripts/generate.sh title "内容摘要" ``` **输出后询问用户**：选择哪个标题？可修改或自定义。默认选第一个。 ### 1.2 生成正文 **优先使用当前对话模型直接生成**，参考 [references/content-guide.md]({baseDir}/references/content-guide.md) 中的规范，根据选定标题生成正文。 核心要求：600-800字，像朋友聊天的语气，禁用列表/编号，用自然段落呈现，文末5-10个#标签。 **备用方案**：如果用户明确配置了 `XHS_AI_API_KEY` 环境变量并要求使用指定 API，可调用脚本： ```bash bash {baseDir}/scripts/generate.sh content "完整内容" "选定标题" ``` **输出后询问用户**：是否满意？可要求修改。确认后进入封面图步骤。 ### 1.3 生成封面图 封面图使用纯 ImageMagick 生成，无需 API 配置。 #### 封面图特点 - **尺寸**：1080x1440（3:4比例，适合小红书） - **样式**：纯色背景 + 标题文字 - **字体**：固定 96px 大小，自动换行 - **颜色**：自动选择美观的浅色背景和深色文字组合 #### 使用方法 直接调用 cover.sh 脚本，仅需两个参数： ```bash bash {baseDir}/scripts/cover.sh "标题文字" [输出路径] ``` **参数说明**： 1. **标题文字**（必填）：封面显示的标题 2. **输出路径**（可选）：封面图保存路径，默认 `/tmp/xhs_cover.png` **示例**： ```bash # 基本用法 bash cover.sh "新加坡留学攻略" /tmp/cover.png # 使用默认输出路径 bash cover.sh "留学费用详解" ``` #### 封面图前置要求 - ImageMagick（`convert` 或 `magick`） - 中文字体（`fonts-noto-cjk`） ### 1.4 文案完成后 询问用户是否要直接发布到小红书。如果要发布，自动进入下方「平台操作」的发布流程。 --- ## 二、平台操作 当用户要求发帖、搜索、评论等小红书操作时使用。所有命令在云服务器本地执行，MCP 服务运行在 `http://localhost:18060/mcp`。 ### 2.1 前置检查 每次操作前必须先执行： ```bash bash {baseDir}/check_env.sh ``` 返回码：`0` = 正常已登录 → 调用工具；`1` = 未安装 → 安装 MCP 服务；`2` = 未登录 → 扫码登录流程。 ### 2.2 调用工具 **⚠️ 极其重要**：小红书 MCP 使用 Streamable HTTP 模式。每次调用都必须：初始化 → 获取 Session ID → 带 Session ID 调用工具。三步在同一个 exec 中执行。 ```bash MCP_URL="${XHS_MCP_URL:-http://localhost:18060/mcp}" # 初始化并获取 Session ID SESSION_ID=$(curl -s -D /tmp/xhs_headers -X POST "$MCP_URL" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"openclaw","version":"1.0"}},"id":1}' > /dev/null && grep -i 'Mcp-Session-Id' /tmp/xhs_headers | tr -d '\r' | awk '{print $2}') # 确认初始化 curl -s -X POST "$MCP_URL" \ -H "Content-Type: application/json" \ -H "Mcp-Session-Id: $SESSION_ID" \ -d '{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}' > /dev/null # 调用工具（替换 <工具名> 和 <参数>） curl -s -X POST "$MCP_URL" \ -H "Content-Type: application/json" \ -H "Mcp-Session-Id: $SESSION_ID" \ -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"<工具名>","arguments":{<参数>}},"id":2}' ``` 注意：每次调用都必须重新初始化获取新 Session ID，三步必须在同一个 exec 中顺序执行。 ### 2.3 可用工具 #### 1. check_login_status — 检查登录状态 - **触发词**: "检查登录"、"登录状态" - **参数**: 无 #### 2. get_login_qrcode — 获取登录二维码 - **触发词**: "获取二维码"、"扫码登录" - **参数**: 无 - **返回**: Base64 图片和超时时间 #### 3. delete_cookies — 重置登录状态 - **触发词**: "退出登录"、"重新登录"、"清除登录" - **参数**: 无 - **注意**: 删除后需要重新扫码登录 #### 4. publish_content — 发布图文内容 - **触发词**: "发小红书"、"发布笔记"、"发图文" - **参数**: - `title`: 标题，≤20字（必填） - `content`: 正文，≤1000字（必填），**注意：正文中不要包含以#开头的话题标签，所有话题标签都用tags参数来生成和提供即可** - `images`: 图片本地绝对路径数组（必填），如 `["/tmp/food1.jpg"]` - `tags`: 话题标签数组（可选），如 `["美食", "旅行", "生活"]` - `products`: 商品关键词列表（可选），用于绑定带货商品，填写商品名称或商品ID，系统会自动搜索并选择第一个匹配结果。需账号已开通商品功能。示例: ["面膜", "防晒霜SPF50"] - `schedule_at`: 定时发布时间（可选），ISO8601格式如 2024-01-20T10:30:00+08:00，支持1小时到14天内。不填则立即发布 - `visibility`: 可见范围（可选），支持: 公开可见(默认)、仅自己可见、仅互关好友可见。不填则默认公开可见 #### 5. publish_with_video — 发布视频内容 - **触发词**: "发视频"、"发布视频笔记" - **参数**: - `title`: 标题（必填） - `content`: 描述（必填），**注意：描述中不要包含以#开头的话题标签，所有话题标签都用tags参数来生成和提供即可** - `video`: 视频文件本地绝对路径（必填） - `tags`: 话题标签数组（可选），如 `["美食", "旅行", "生活"]` - `products`: 商品关键词列表（可选），用于绑定带货商品，填写商品名称或商品ID，系统会自动搜索并选择第一个匹配结果。需账号已开通商品功能。示例: ["面膜", "防晒霜SPF50"] - `schedule_at`: 定时发布时间（可选），ISO8601格式如 2024-01-20T10:30:00+08:00，支持1小时到14天内。不填则立即发布 - `visibility`: 可见范围（可选），支持: 公开可见(默认)、仅自己可见、仅互关好友可见。不填则默认公开可见 #### 6. search_feeds — 搜索内容 - **触发词**: "搜索小红书"、"找笔记"、"搜一下" - **参数**: - `keyword`: 搜索关键词（必填） #### 7. list_feeds — 获取推荐列表 - **触发词**: "推荐内容"、"首页推荐" - **参数**: 无 #### 8. get_feed_detail — 获取帖子详情 - **触发词**: "看看这个帖子"、"帖子详情" - **参数**: - `feed_id`: 帖子ID（从搜索/推荐结果获取，必填） - `xsec_token`: 安全token（从搜索/推荐结果获取，必填） - `load_all_comments`: 是否加载全部评论，默认 false 仅返回前 10 条（可选） - `click_more_replies`: 是否展开二级回复，仅 load_all_comments=true 时生效（可选） - `limit`: 限制加载的一级评论数量，默认 20（可选） - `reply_limit`: 跳过回复数过多的评论，默认 10（可选） - `scroll_speed`: 滚动速度 slow/normal/fast（可选） #### 9. like_feed — 点赞/取消点赞 - **触发词**: "点赞"、"取消点赞"、"喜欢这个" - **参数**: - `feed_id`: 帖子ID（必填） - `xsec_token`: 安全token（必填） - `unlike`: 是否取消点赞，true=取消，默认 false=点赞（可选） #### 10. favorite_feed — 收藏/取消收藏 - **触发词**: "收藏"、"取消收藏"、"收藏这个" - **参数**: - `feed_id`: 帖子ID（必填） - `xsec_token`: 安全token（必填） - `unfavorite`: 是否取消收藏，true=取消，默认 false=收藏（可选） #### 11. post_comment_to_feed — 发表评论 - **触发词**: "评论这个"、"发表评论" - **参数**: - `feed_id`: 帖子ID（必填） - `xsec_token`: 安全token（必填） - `content`: 评论内容（必填） #### 12. reply_comment_in_feed — 回复评论 - **触发词**: "回复评论"、"回复这条" - **参数**: - `feed_id`: 帖子ID（必填） - `xsec_token`: 安全token（必填） - `content`: 回复内容（必填） - `comment_id`: 目标评论ID，从评论列表获取（可选） - `user_id`: 目标评论用户ID，从评论列表获取（可选） #### 13. user_profile — 获取用户主页 - **触发词**: "看看这个博主"、"用户主页" - **参数**: - `user_id`: 用户ID（必填） - `xsec_token`: 安全token（必填） ### 2.4 使用示例 **搜索**： ```bash MCP_URL="http://localhost:18060/mcp" SESSION_ID=$(curl -s -D /tmp/xhs_headers -X POST "$MCP_URL" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"openclaw","version":"1.0"}},"id":1}' > /dev/null && grep -i 'Mcp-Session-Id' /tmp/xhs_headers | tr -d '\r' | awk '{print $2}') curl -s -X POST "$MCP_URL" -H "Content-Type: application/json" -H "Mcp-Session-Id: $SESSION_ID" \ -d '{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}' > /dev/null curl -s -X POST "$MCP_URL" -H "Content-Type: application/json" -H "Mcp-Session-Id: $SESSION_ID" \ -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"search_feeds","arguments":{"keyword":"美食探店"}},"id":2}' ``` **发布图文内容（带tags参数）**： ```bash MCP_URL="http://localhost:18060/mcp" SESSION_ID=$(curl -s -D /tmp/xhs_headers -X POST "$MCP_URL" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"openclaw","version":"1.0"}},"id":1}' > /dev/null && grep -i 'Mcp-Session-Id' /tmp/xhs_headers | tr -d '\r' | awk '{print $2}') curl -s -X POST "$MCP_URL" -H "Content-Type: application/json" -H "Mcp-Session-Id: $SESSION_ID" \ -d '{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}' > /dev/null curl -s -X POST "$MCP_URL" -H "Content-Type: application/json" -H "Mcp-Session-Id: $SESSION_ID" \ -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"publish_content","arguments":{"title":"新加坡私立大学留学指南","content":"分享新加坡私立大学的申请流程和注意事项，包括学校选择、申请材料准备、签证办理等实用信息。","images":["/path/to/image1.jpg","/path/to/image2.jpg"],"tags":["新加坡留学","新加坡私立大学","留学申请","国际教育","海外学习"]}},"id":2}' ``` **重要**：正文中不要包含以#开头的话题标签，所有话题标签都通过`tags`参数传递。 --- ## 三、登录流程 当前置检查返回 `2`（未登录）时，询问用户选择登录方式： > 需要登录小红书，请选择登录方式： > 1. **快捷扫码** — 直接获取二维码图片（推荐同城/常用设备） > 2. **截图扫码** — 通过登录工具截屏获取（推荐异地登录，支持短信验证码） > 3. **手动Cookie** — 直接粘贴浏览器Cookie字符串（推荐已在浏览器登录的用户） ### 方式一：快捷扫码（get_login_qrcode） 通过 MCP 工具直接获取二维码 Base64 图片，流程简洁，但**不支持输入验证码**。异地登录可能触发短信验证，此时需切换为方式二。 #### 步骤 1: 调用 get_login_qrcode 获取二维码 ```bash MCP_URL="${XHS_MCP_URL:-http://localhost:18060/mcp}" SESSION_ID=$(curl -s -D /tmp/xhs_headers -X POST "$MCP_URL" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"openclaw","version":"1.0"}},"id":1}' > /dev/null && grep -i 'Mcp-Session-Id' /tmp/xhs_headers | tr -d '\r' | awk '{print $2}') curl -s -X POST "$MCP_URL" -H "Content-Type: application/json" -H "Mcp-Session-Id: $SESSION_ID" \ -d '{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}' > /dev/null curl -s -X POST "$MCP_URL" -H "Content-Type: application/json" -H "Mcp-Session-Id: $SESSION_ID" \ -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"get_login_qrcode","arguments":{}},"id":2}' ``` #### 步骤 2: 将 Base64 转为图片文件 从返回结果中提取 Base64 字符串（去掉 `data:image/png;base64,` 前缀），保存为图片： ```bash # 假设 BASE64_STR 为提取到的 Base64 内容（不含 data:image/png;base64, 前缀） echo "$BASE64_STR" | base64 -d > /tmp/xhs_qr.png ``` #### 步骤 3: 发送二维码给用户 #### 步骤 4: 等待扫码并验证 告知用户扫码，扫码后用 `check_login_status` 工具验证是否登录成功。二维码过期则重新执行步骤 1-3。 --- ### 方式二：截图扫码（登录工具 + Xvfb 截屏） 通过 GUI 登录工具获取二维码，**支持异地登录时输入短信验证码**。 #### 步骤 1: 启动登录工具 所有命令必须用 nohup 后台运行，否则会因超时被中断。 ```bash pkill -f xiaohongshu-login 2>/dev/null sleep 1 cd ~/xiaohongshu-mcp && DISPLAY=:99 nohup ./xiaohongshu-login-linux-amd64 > login.log 2>&1 & sleep 5 ``` #### 步骤 2: 截取二维码 ```bash DISPLAY=:99 import -window root /tmp/xhs_qr.png ``` #### 步骤 2.1: 检测截图内是否有二维码 ```bash zbarimg -q /tmp/xhs_qr.png ``` - 无输出：二维码未加载，等待 5 秒后重新截图 - 有输出：二维码已生成，继续发送 #### 步骤 3: 发送二维码给用户 #### 步骤 4: 等待扫码 告知用户"已发送二维码，请用小红书APP扫码登录"，等待用户确认。 #### 步骤 4.1: 如提示输入验证码（异地登录常见） ```bash export DISPLAY=:99 WIN_ID=$(xdotool search --onlyvisible --name '小红书|xiaohongshu|Xiaohongshu' | head -n1) xdotool type --window "$WIN_ID" --delay 50 '<CODE>' xdotool key --window "$WIN_ID" Return ``` #### 步骤 5: 验证登录并启动 MCP ```bash cat ~/xiaohongshu-mcp/login.log | tail -5 # 如果显示 "Login successful"： pkill -f xiaohongshu 2>/dev/null cd ~/xiaohongshu-mcp && DISPLAY=:99 nohup ./xiaohongshu-mcp-linux-amd64 > mcp.log 2>&1 & ``` #### 二维码过期 如用户反馈扫码失败，重复步骤 1-3 获取新二维码。 --- ### 方式三：手动Cookie登录 当用户提供浏览器复制的 Cookie 字符串时，将其转换为 JSON 数组格式并保存到 `~/xiaohongshu-mcp/cookies.json`。 #### 步骤 1: 接收用户的 Cookie 字符串 用户会提供类似这样的字符串（从浏览器开发者工具复制）： ``` a1=19c464ed2df...; webId=807ede65b...; web_session=040069b4...; xsecappid=xhs-pc-web ``` #### 步骤 2: 转换并保存 将用户提供的 Cookie 字符串按 `;` 分割每个键值对，转换为如下 JSON 数组格式，保存到 `~/xiaohongshu-mcp/cookies.json`： ```python python3 -c " import json, sys cookie_str = sys.argv[1].strip() cookies = [] for pair in cookie_str.split(';'): pair = pair.strip() if '=' not in pair: continue name, value = pair.split('=', 1) cookies.append({ 'name': name.strip(), 'value': value.strip(), 'domain': '.xiaohongshu.com', 'path': '/', 'expires': -1, 'httpOnly': name.strip() in ('web_session', 'id_token', 'acw_tc'), 'secure': name.strip() in ('web_session', 'id_token'), 'session': False, 'priority': 'Medium', 'sameParty': False, 'sourceScheme': 'Secure', 'sourcePort': 443 }) with open('$HOME/xiaohongshu-mcp/cookies.json', 'w') as f: json.dump(cookies, f, ensure_ascii=False) print(f'✅ 已保存 {len(cookies)} 个 Cookie 到 cookies.json') " "用户提供的cookie字符串" ``` #### 步骤 3: 重启 MCP 服务使 Cookie 生效 ```bash pkill -f xiaohongshu-mcp-linux 2>/dev/null sleep 1 cd ~/xiaohongshu-mcp && DISPLAY=:99 nohup ./xiaohongshu-mcp-linux-amd64 > mcp.log 2>&1 & sleep 3 ``` #### 步骤 4: 验证登录状态 用 `check_login_status` 工具验证是否登录成功。如果失败，提示用户 Cookie 可能已过期，建议重新从浏览器获取或改用扫码登录。 **注意事项**： - Cookie 中最关键的字段是 `web_session` 和 `a1`，缺少这两个会导致登录失败 - 浏览器登录状态和 MCP 登录状态会互相覆盖，导入后建议不要在浏览器再登录同一账号 --- ## 四、安装 MCP 服务（仅首次） 当前置检查返回 `1` 时执行。 ### 确认系统环境 ```bash hostnamectl ``` 根据 `Operating System` 确定包管理器（apt/yum/dnf），根据 `Architecture` 确定二进制版本（x86_64=amd64, aarch64=arm64）。 ### 安装依赖 ```bash # Ubuntu/Debian sudo apt update && sudo apt install -y xvfb imagemagick zbar-tools xdotool fonts-noto-cjk # CentOS/RHEL sudo yum install -y xorg-x11-server-Xvfb ImageMagick zbar xdotool ``` ### 启动虚拟显示 ```bash # 快速启动 Xvfb :99 -screen 0 1920x1080x24 & # 或 systemd 服务（推荐，开机自启） cat > /etc/systemd/system/xvfb.service << 'EOF' [Unit] Description=X Virtual Frame Buffer After=network.target [Service] ExecStart=/usr/bin/Xvfb :99 -screen 0 1920x1080x24 Restart=always [Install] WantedBy=multi-user.target EOF sudo systemctl enable xvfb && sudo systemctl start xvfb ``` ### 下载 MCP 服务 项目地址：https://github.com/xpzouying/xiaohongshu-mcp/releases ```bash mkdir -p ~/xiaohongshu-mcp && cd ~/xiaohongshu-mcp # 根据架构选择（云服务器通常是 x86_64 = amd64） ARCH="amd64" # 如果是 ARM 服务器改为 arm64 wget https://github.com/xpzouying/xiaohongshu-mcp/releases/latest/download/xiaohongshu-mcp-linux-${ARCH}.tar.gz tar xzf xiaohongshu-mcp-linux-${ARCH}.tar.gz chmod +x xiaohongshu-* ``` ### 启动 MCP 服务 **推荐使用 systemd 守护（崩溃自动重启 + 开机自启）：** ```bash cat > /etc/systemd/system/xhs-mcp.service << 'EOF' [Unit] Description=Xiaohongshu MCP Service After=network.target xvfb.service Requires=xvfb.service [Service] Environment=DISPLAY=:99 WorkingDirectory=/root/xiaohongshu-mcp ExecStart=/root/xiaohongshu-mcp/xiaohongshu-mcp-linux-amd64 Restart=always RestartSec=5 [Install] WantedBy=multi-user.target EOF sudo systemctl daemon-reload sudo systemctl enable xhs-mcp && sudo systemctl start xhs-mcp systemctl status xhs-mcp ``` **或手动启动（不推荐，进程退出不会自动恢复）：** ```bash cd ~/xiaohongshu-mcp DISPLAY=:99 nohup ./xiaohongshu-mcp-linux-amd64 > mcp.log 2>&1 & sleep 3 pgrep -f xiaohongshu-mcp && echo "✅ 启动成功" || echo "❌ 启动失败，查看 mcp.log" ``` 安装完成后，回到登录流程完成首次登录。 --- ## 五、响应处理 成功：解析 `result.content[0].text` 获取数据。 错误： - `Not logged in`: 未登录，走扫码流程 - `Session expired`: 会话过期，重新登录 - `Rate limited`: 频率限制，稍后重试 ## 六、注意事项 1. 标题不超过 **20 字**，正文不超过 **1000 字** 2. 图片/视频必须使用**服务器上的本地绝对路径** 3. 小红书**不支持多设备同时登录**，登录后不要在浏览器再登录 4. 评论间隔建议 > 30 秒，避免频率限制 5. 所有带 GUI 的进程（login、mcp）**必须用 nohup 后台运行**，否则会被 exec 超时中断 ## 七、故障排查 ```bash # MCP 服务是否运行 pgrep -f xiaohongshu-mcp-linux # Xvfb 是否运行 pgrep -x Xvfb # 查看 MCP 日志 tail -20 ~/xiaohongshu-mcp/mcp.log # 查看登录日志 tail -20 ~/xiaohongshu-mcp/login.log # 检查端口 lsof -i :18060 ```

path: _meta.json
content: ownerId: kn7a27xrmzhej6xbc8450fdt5h801j5n
slug: xhs
version: 1.2.5
publishedAt: 1772260865501

path: check_env.sh
content: #!/bin/bash
# 小红书 MCP 环境检查脚本
# 用法: bash ~/.openclaw/skills/xiaohongshu/check_env.sh

MCP_URL="${XHS_MCP_URL:-http://localhost:18060/mcp}"
MCP_BIN=~/xiaohongshu-mcp/xiaohongshu-mcp-linux-amd64

echo "=== 1. 检查 MCP 是否安装 ==="
if [ -x "$MCP_BIN" ]; then
  echo "✅ MCP 已安装"
else
  echo "❌ MCP 未安装，请先执行安装流程"
  exit 1
fi

echo "=== 2. 检查 Xvfb 虚拟显示 ==="
if systemctl is-active --quiet xvfb 2>/dev/null; then
  echo "✅ Xvfb 服务运行中 (systemd)"
elif pgrep -x Xvfb > /dev/null; then
  echo "✅ Xvfb 运行中 (手动)"
else
  echo "⚠️ Xvfb 未运行，尝试启动 systemd 服务..."
  systemctl start xvfb 2>/dev/null
  sleep 1
  if systemctl is-active --quiet xvfb 2>/dev/null; then
    echo "✅ Xvfb 服务已启动"
  else
    echo "⚠️ systemd 服务不存在，手动启动..."
    Xvfb :99 -screen 0 1920x1080x24 &
    sleep 1
    echo "✅ Xvfb 已启动（非守护模式）"
  fi
fi

echo "=== 3. 检查 MCP 服务是否运行 ==="
if systemctl is-active --quiet xhs-mcp 2>/dev/null; then
  echo "✅ MCP 服务运行中 (systemd 守护)"
elif pgrep -f xiaohongshu-mcp-linux > /dev/null; then
  echo "✅ MCP 服务运行中 (手动)"
else
  echo "⚠️ MCP 服务未运行，尝试启动 systemd 服务..."
  systemctl start xhs-mcp 2>/dev/null
  sleep 2
  if systemctl is-active --quiet xhs-mcp 2>/dev/null; then
    echo "✅ MCP 服务已启动 (systemd)"
  else
    echo "⚠️ systemd 服务不存在，手动启动..."
    cd ~/xiaohongshu-mcp && DISPLAY=:99 nohup ./xiaohongshu-mcp-linux-amd64 > mcp.log 2>&1 &
    sleep 3
    if pgrep -f xiaohongshu-mcp-linux > /dev/null; then
      echo "✅ MCP 服务已启动（非守护模式）"
    else
      echo "❌ MCP 服务启动失败，请检查 ~/xiaohongshu-mcp/mcp.log"
      exit 1
    fi
  fi
fi

echo "=== 4. 检查生图 API 配置 ==="
IMG_API_TYPE="${IMG_API_TYPE:-gemini}"
IMG_OK=false

case "$IMG_API_TYPE" in
  gemini)
    if [ -n "${GEMINI_API_KEY:-}" ]; then
      echo "✅ Gemini API Key 已配置 (IMG_API_TYPE=gemini)"
      IMG_OK=true
    else
      echo "❌ Gemini API Key 未配置（需设置 GEMINI_API_KEY）"
    fi
    ;;
  openai)
    if [ -n "${IMG_API_KEY:-}" ]; then
      echo "✅ OpenAI 兼容 API Key 已配置 (IMG_API_TYPE=openai, BASE=${IMG_API_BASE:-https://api.openai.com/v1})"
      IMG_OK=true
    else
      echo "❌ OpenAI 兼容 API Key 未配置（需设置 IMG_API_KEY）"
    fi
    ;;
  hunyuan)
    if [ -n "${HUNYUAN_SECRET_ID:-}" ] && [ -n "${HUNYUAN_SECRET_KEY:-}" ]; then
      echo "✅ 腾讯云混元 API 已配置 (IMG_API_TYPE=hunyuan)"
      IMG_OK=true
    else
      echo "❌ 腾讯云混元 API 未配置（需设置 HUNYUAN_SECRET_ID 和 HUNYUAN_SECRET_KEY）"
    fi
    ;;
  *)
    echo "⚠️ 未知的 IMG_API_TYPE: $IMG_API_TYPE（支持 gemini/openai/hunyuan）"
    ;;
esac

# 如果当前类型未配置，检查是否有其他可用的
if [ "$IMG_OK" = false ]; then
  FALLBACKS=""
  [ -n "${GEMINI_API_KEY:-}" ] && FALLBACKS="${FALLBACKS} gemini(GEMINI_API_KEY)"
  [ -n "${IMG_API_KEY:-}" ] && FALLBACKS="${FALLBACKS} openai(IMG_API_KEY)"
  [ -n "${HUNYUAN_SECRET_ID:-}" ] && [ -n "${HUNYUAN_SECRET_KEY:-}" ] && FALLBACKS="${FALLBACKS} hunyuan(HUNYUAN_SECRET_ID+KEY)"
  if [ -n "$FALLBACKS" ]; then
    echo "💡 检测到其他可用的生图 API:$FALLBACKS"
    echo "   可通过 export IMG_API_TYPE=xxx 切换"
  else
    echo "⚠️ 未配置任何生图 API，封面生成功能不可用"
    echo "   请设置以下任一组环境变量："
    echo "   - GEMINI_API_KEY（推荐）"
    echo "   - IMG_API_KEY + IMG_API_BASE"
    echo "   - HUNYUAN_SECRET_ID + HUNYUAN_SECRET_KEY"
  fi
fi

echo "=== 5. 检查登录状态 ==="
SESSION_ID=$(curl -s -D /tmp/xhs_headers -X POST "$MCP_URL" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"openclaw","version":"1.0"}},"id":1}' > /dev/null && grep -i 'Mcp-Session-Id' /tmp/xhs_headers | tr -d '\r' | awk '{print $2}')

curl -s -X POST "$MCP_URL" \
  -H "Content-Type: application/json" \
  -H "Mcp-Session-Id: $SESSION_ID" \
  -d '{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}' > /dev/null

LOGIN_RESULT=$(curl -s -X POST "$MCP_URL" \
  -H "Content-Type: application/json" \
  -H "Mcp-Session-Id: $SESSION_ID" \
  -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"check_login_status","arguments":{}},"id":2}')

echo "$LOGIN_RESULT"

if echo "$LOGIN_RESULT" | grep -q "未登录"; then
  echo "❌ 未登录，需要扫码登录"
  exit 2
else
  echo "✅ 已登录，可以正常使用"
  exit 0
fi


path: references/content-guide.md
content: # 小红书爆款正文创作详细指南

## 角色设定

你是一名资深的小红书爆款文案写手。你精通小红书平台的内容创作规则。你擅长创作高互动、高转化的种草文案。

## 写作风格

- **语言风格**：像朋友聊天，真诚、直接、有温度
- **句式结构**：简单明了，主谓宾清晰，一句话一个意思
- **词汇选择**：大白话优先，专业术语必须解释
- **段落节奏**：每段2-3句，保持呼吸感

## 写作开篇方法（选择1种）

- **金句开场**：用一句话抓住注意力
- **痛点切入**：直接说出用户困扰
- **反转开场**：先说常见误区，再给出正确方法
- **故事引入**：用个人经历引发共鸣

## 文本结构

- **开头**：emoji+金句/痛点（1-2句话）
- **主体**：分点叙述，每点前加emoji，3-5个要点，用段落展开
- **每个要点包含**：具体方法+个人体验+效果说明
- **结尾**：总结+互动引导

## 互动引导方法

- **提问式**："你们有遇到这种情况吗？"
- **征集式**："评论区说说你的方法～"
- **行动式**："赶紧收藏起来！"
- **共鸣式**："姐妹们懂我的扣1！"

## 小技巧

- 使用"姐妹们"、"宝子们"等亲昵称呼
- 适当使用网络流行语和梗
- 多用"你、我、他"，少用"其、该、此、彼"
- 多用"真的"、"绝了"、"爱了"等语气词
- 用"第一、第二、第三"而不是"首先、其次、最后"

## 爆炸词库

- **情绪类**：绝了、爱了、yyds、无敌、炸裂、疯狂、上头、氛围感
- **效果类**：秒杀、碾压、吊打、神仙、手残党必备
- **程度类**：超级、巨、狂、暴、极致
- **共鸣类**：懂的都懂、破防了、DNA动了、真实、太真实了

## 写作约束（严格执行）

**禁止**：
1. 绝对不使用任何形式的项目符号或编号列表（不用 *、-、1.2.3. 等列表形式）
2. 不使用破折号（——）
3. 禁用"A而且B"的对仗结构
4. 尽量避免使用冒号（：），用句号代替
5. 开头不用设问句
6. 一句话只表达一个完整意思
7. 每段不超过3句话
8. 避免嵌套从句和复合句
9. 所有内容都用自然段落呈现，用"第一"、"第二"、"第三"等词语自然串联

**改写策略**：
1. **长句拆短**：把复合句拆成多个简单句
2. **术语翻译**：把专业词汇翻译成大白话
3. **增加温度**：适当加入个人感受和真实体验
4. **逻辑清晰**：用"第一、第二、第三"标注顺序

## 正文创作要求

1. 内容真诚可信，把"真诚"摆在第一位
2. 避免假大空，花里胡哨的内容
3. 保持小红书社区调性，注重用户体验
4. 正文控制在600-800字之间
5. **⚠️ 话题标签格式**：文末添加5-10个相关标签，**必须用 #标签名[话题]# 格式**，如 `#千问[话题]# #AI[话题]# #大模型[话题]#`
6. 在正文中自然穿插2-3处互动问句


path: references/cover-guide.md
content: # 小红书封面图生成详细指南

## 封面图结构（3:4 = 1080x1440）

```
┌──────────────────┐
│                  │
│  AI 生成图片      │  上半部分 1080x720 (3:2)
│  (根据主题生成)    │
│                  │
├──────────────────┤
│                  │
│  纯色底 + 标题    │  下半部分 1080x720 (3:2)
│  「标题文字」      │
│                  │
└──────────────────┘
```

## AI 图片 Prompt 编写规范

- **风格关键词**：`clean, minimal, aesthetic, soft lighting, pastel colors, cozy atmosphere`
- **场景描述**：根据文案主题描述具体场景（如收纳→整洁的房间，美食→精致的摆盘）
- **禁止内容**：不包含文字、水印、人脸特写、logo
- **质量词**：`high quality, professional photography, 4k, detailed`
- **构图词**：`centered composition, top-down view, flat lay`（根据主题选择）
- **色调提示**：prompt 中要指明整体色调（如 warm tones、cool tones、pastel pink），方便后续底色与图片色调呼应

### Prompt 示例

- 居家收纳 → `A clean and organized living room with minimal furniture, soft natural lighting, warm beige and white tones, cozy aesthetic, high quality photography, no text no watermark`
- 美食探店 → `Delicious gourmet food beautifully plated on a wooden table, warm golden lighting, top-down flat lay photography, rich warm color palette, aesthetic food photography, no text no watermark`
- 穿搭分享 → `Stylish outfit flat lay on a cream linen sheet, aesthetic fashion photography, soft natural light, minimal composition, dusty rose and beige tones, no text no watermark`

## 配色搭配规则（重要）

Agent 必须根据主题和图片色调主动搭配底色与字色，不要用默认白底黑字。

### 原则

1. **底色与图片色调呼应**：底色应从 AI 图片的主色调中提取同色系的浅色/淡色
2. **字色与底色形成对比**：字色要在底色上清晰可读
3. **整体风格一致**：暖色主题用暖色搭配，冷色主题用冷色搭配
4. **小红书审美偏好**：偏向柔和、温暖、高级感的色调

### 配色参考库

底色必须有明显视觉辨识度，不能接近纯白。浅色底色明度控制在 75%-90% 之间。

| 风格 | 底色 | 字色 | 适用场景 | 视觉感受 |
|------|------|------|---------|---------|
| 奶油温暖 | `#F5E6D0` | `#6B4226` | 美食、烘焙、咖啡、家居 | 温馨舒适 |
| 蜜桃甜美 | `#FCDBD3` | `#D4545B` | 美妆、护肤、穿搭、恋爱 | 少女心 |
| 薄荷清新 | `#D4EDDF` | `#1B5E40` | 健身、户外、植物、环保 | 清新自然 |
| 雾蓝理性 | `#CEDAEB` | `#2B4A7C` | 科技、效率、学习、职场 | 专业冷静 |
| 薰衣草梦幻 | `#DDD0F0` | `#5A3A8A` | 旅行、艺术、香氛、冥想 | 浪漫高级 |
| 鹅黄活力 | `#F5ECC8` | `#8B6D0B` | 育儿、宠物、手工、日常 | 明亮温暖 |
| 烟粉优雅 | `#F2D5E5` | `#8B1C4E` | 婚礼、花艺、甜品、仪式感 | 精致浪漫 |
| 暗夜高级 | `#1C1C1E` | `#E8C872` | 奢侈品、数码、夜景、酒 | 高级沉稳 |
| 莫兰迪灰 | `#D5D0C8` | `#4A453F` | 极简、设计、建筑、摄影 | 高级克制 |
| 珊瑚活力 | `#FBCEC5` | `#C04030` | 运动、夏日、派对、潮流 | 热情洋溢 |

### 自定义搭配原则

- 浅色底色明度控制在 75%-90%，不能接近纯白（≥95%会显得平淡）
- 字色与底色需形成强对比，确保清晰可读
- 暗色底色（如暗夜高级）配亮色/金色字
- 底色饱和度适中（15%-35%），太低会像灰色，太高会抢 AI 图片视线
- 推荐从 AI 图片的主色调中吸色，降低饱和度作为底色


path: references/title-guide.md
content: # 小红书爆款标题创作详细指南

## 标题创作方法（5种）

1. **数字法则**：用具体数字增加可信度（如"7天"、"3个方法"）
2. **二极管标题**：制造强烈反差和对比效果
3. **疑问句式**：激发好奇心（如"为什么..."、"怎么..."）
4. **情绪共鸣**：使用高唤起情绪词，瞬间唤醒用户共鸣
5. **利益驱动**：直击痛点或利益点

## 7大爆款标题风格

- 数字悬念型：【3个懒人收纳法，房间一周不乱！】
- 情感共鸣型：【谁懂啊！这碗面直接治愈了我的周一！】
- 结果导向型：【跟着博主做，7天搞定Python基础！】
- 反差对比型：【从烂脸到水光肌，我只做了这两件事】
- 稀缺信息型：【这10个上海小众秘境，90%的人没去过】
- 对话互动型：【你的枕头选对了吗？快来对照这份指南！】
- 价值宣言型：【2025年投资自己，这3项技能最值钱】

## 平台禁忌词（严禁使用）

- 【诱导类】速来、必看、必收、千万不要、马上、抓紧、最后一波
- 【夸大类】全网第一、最全、最强、史上、终极、完美、天花板、封神
- 【营销类】免费送、0元购、薅羊毛、福利、红包、点击领取、价格感人
- 【负面类】丑哭、踩雷、血亏、别买、避坑、垃圾、后悔、翻车

## 标题创作要求

1. 生成5个标题，每个使用不同的爆款标题风格
2. 严禁使用平台禁忌词
3. emoji优先用✨🔥✅💡❗️😭🤔💪，每个标题最多2个
4. 避免"XX分享""XX笔记"等无效词
5. 使用"亲测""试过""我发现"等真实感表述
6. 每个标题字数控制在20字以内
7. 标题要有吸引力，让人忍不住点进来看
8. 直接输出5个标题，每行一个，不要添加序号和说明

## 标题示例

```
数字迷雾大揭秘✨3个方法让你秒懂数字陷阱！
谁懂啊🤔这些数字问题把我绕晕了！
从被骗到透视💡7天学会识破数字套路
你真的懂数字吗❗️90%人都答错的题！
2025必学技能🔥数字思维让你更聪明
```


path: scripts/cover.sh
content: #!/bin/bash
# 小红书封面图生成脚本（纯ImageMagick版本）
# 功能：使用ImageMagick的caption功能生成3:4封面图
# 自动选择美观的颜色组合，保持浅色和深色对比，固定字体大小80px
#
# 用法:
#   bash cover.sh "标题文字" [输出路径]
#
# 参数:
#   $1 - 标题文字（必填）
#   $2 - 输出路径（可选，默认 /tmp/xhs_cover.png）
#
# 最终封面尺寸: 1080x1440 (3:4)

set -e

TITLE="${1:-}"
OUTPUT="${2:-/tmp/xhs_cover.png}"

# 尺寸定义
COVER_W=1080
COVER_H=1440

# 固定字体大小
FONT_SIZE=96

# 临时文件
TMP_DIR=$(mktemp -d)

cleanup() {
  rm -rf "$TMP_DIR"
}
trap cleanup EXIT

# ==================== 参数检查 ====================

if [ -z "$TITLE" ]; then
  echo "❌ 错误: 请提供标题文字"
  echo "用法: bash $0 \"标题文字\" [输出路径]"
  exit 1
fi

# 检查 ImageMagick
if ! command -v magick &> /dev/null && ! command -v convert &> /dev/null; then
  echo "❌ 错误: 未安装 ImageMagick，请先执行: apt install -y imagemagick"
  exit 1
fi

# 确定 ImageMagick 命令
if command -v magick &> /dev/null; then
  MAGICK="magick"
  IDENTIFY="magick identify"
else
  MAGICK="convert"
  IDENTIFY="identify"
fi

# ==================== 自动颜色选择 ====================

# 基于标题内容生成一个简单的哈希值来决定颜色组合
TITLE_HASH=$(echo -n "$TITLE" | md5sum | cut -c1-8)
HASH_NUM=$((0x$TITLE_HASH % 100))

# 定义美观的颜色组合库
# 格式: 背景颜色,文字颜色,组合名称
COLOR_COMBINATIONS=(
  "#FFFFFF,#000000,经典白黑"
  "#F8F9FA,#2C3E50,专业灰蓝"
  "#E3F2FD,#1565C0,清新蓝调"
  "#E8F5E9,#2E7D32,自然绿意"
  "#FCE4EC,#C2185B,温馨粉红"
  "#FFFDE7,#F57C00,活力橙黄"
  "#F3E5F5,#7B1FA2,优雅紫韵"
  "#FFF3E0,#EF6C00,温暖橙调"
  "#E0F2F1,#00695C,薄荷绿意"
  "#F5F0FF,#6A1B9A,梦幻紫罗兰"
  "#FFEBEE,#D32F2F,热情红调"
  "#FFF8E1,#FF8F00,阳光橙黄"
  "#EDE7F6,#512DA8,淡紫深紫"
  "#E1F5FE,#0277BD,天空蓝调"
  "#F1F8E9,#558B2F,春意盎然"
  "#FBE9E7,#D84315,珊瑚橙红"
  "#F5F5F5,#424242,高级灰黑"
  "#E8EAF6,#283593,宁静蓝紫"
  "#FFE5E5,#C62828,甜美红粉"
  "#F0F4C3,#827717,嫩黄橄榄"
)

# 选择颜色组合
COLOR_INDEX=$((HASH_NUM % ${#COLOR_COMBINATIONS[@]}))
SELECTED_COMBO="${COLOR_COMBINATIONS[$COLOR_INDEX]}"

# 解析颜色组合
BG_COLOR=$(echo "$SELECTED_COMBO" | cut -d',' -f1)
TEXT_COLOR=$(echo "$SELECTED_COMBO" | cut -d',' -f2)
COMBO_NAME=$(echo "$SELECTED_COMBO" | cut -d',' -f3)

echo "🎨 开始生成小红书封面图（纯ImageMagick版本）..."
echo "   标题: ${TITLE}"
echo "   输出: ${OUTPUT}"
echo "   颜色组合: ${COMBO_NAME}"
echo "   背景色: ${BG_COLOR}"
echo "   文字色: ${TEXT_COLOR}"
echo "   比例: 3:4 (1080x1440)"
echo "   字体大小: 固定 ${FONT_SIZE}px"
echo "   功能: 使用caption功能（自动换行）"
echo "   选择方式: 基于标题内容自动选择"
echo ""

# ==================== 生成封面图 ====================

echo "🔄 生成封面图..."

# 查找可用的中文字体（优先粗体）
FONT=""
for f in \
  "/usr/share/fonts/truetype/noto/NotoSansCJK-Bold.ttc" \
  "/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc" \
  "/usr/share/fonts/noto-cjk/NotoSansCJK-Bold.ttc" \
  "/usr/share/fonts/google-noto-cjk/NotoSansCJK-Bold.ttc" \
  "/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc" \
  "/usr/share/fonts/wqy-zenhei/wqy-zenhei.ttc" \
  "/usr/share/fonts/truetype/droid/DroidSansFallbackFull.ttf" \
  "/usr/share/fonts/noto/NotoSansSC-Bold.ttf" \
  "/usr/share/fonts/truetype/noto/NotoSansSC-Bold.ttf"; do
  if [ -f "$f" ]; then
    FONT="$f"
    break
  fi
done

# 如果没有找到中文字体，尝试用 fc-list 搜索
if [ -z "$FONT" ]; then
  FONT=$(fc-list :lang=zh -f "%{file}\n" 2>/dev/null | head -1)
fi

FONT_ARG=""
if [ -n "$FONT" ]; then
  FONT_ARG="-font $FONT"
  echo "   使用字体: $(basename "$FONT")"
else
  echo "   ⚠️ 未找到中文字体，使用系统默认字体（中文可能显示为方块）"
  echo "   建议安装: apt install -y fonts-noto-cjk"
fi

# 使用ImageMagick的caption功能生成封面
# caption会自动换行以适应宽度
echo "   使用caption功能生成（自动换行）..."
$MAGICK -background "$BG_COLOR" \
  -fill "$TEXT_COLOR" \
  $FONT_ARG \
  -pointsize "$FONT_SIZE" \
  -gravity center \
  -size "${COVER_W}x${COVER_H}" \
  caption:"$TITLE" \
  "$OUTPUT"

# 验证最终尺寸
FINAL_SIZE=$($IDENTIFY -format "%wx%h" "$OUTPUT" 2>/dev/null)
COLOR_DEPTH=$($IDENTIFY -format "%q-bit" "$OUTPUT" 2>/dev/null)

echo ""
echo "✅ 封面图生成完成！"
echo "   路径: ${OUTPUT}"
echo "   尺寸: ${FINAL_SIZE} (目标: ${COVER_W}x${COVER_H})"
echo "   颜色深度: ${COLOR_DEPTH}"
echo "   比例: 3:4"
echo "   字体大小: 固定 ${FONT_SIZE}px"
echo "   颜色组合: ${COMBO_NAME}"
echo "   背景色: ${BG_COLOR}"
echo "   文字色: ${TEXT_COLOR}"
echo ""
echo "📐 设计说明:"
echo "   ┌─────────────────────────────┐"
echo "   │                             │"
echo "   │     颜色主题: ${COMBO_NAME}        │"
echo "   │                             │"
echo "   │     背景颜色: ${BG_COLOR}        │"
echo "   │                             │"
echo "   │     文字颜色: ${TEXT_COLOR}        │"
echo "   │                             │"
echo "   │     「${TITLE:0:20}...」    │"
echo "   │     （自动换行显示）        │"
echo "   │                             │"
echo "   └─────────────────────────────┘"
echo "   总计: ${COVER_W}x${COVER_H} (3:4)"
echo ""
echo "💡 提示:"
echo "   • 此版本使用ImageMagick的caption功能"
echo "   • 固定字体大小80px，文字自动换行"
echo "   • 颜色组合基于标题内容自动选择"
echo "   • 共20种精心设计的颜色组合"
echo ""
echo "🎨 可用颜色组合:"
for combo in "${COLOR_COMBINATIONS[@]}"; do
  name=$(echo "$combo" | cut -d',' -f3)
  bg=$(echo "$combo" | cut -d',' -f1)
  text=$(echo "$combo" | cut -d',' -f2)
  echo "   • ${name}: ${bg} + ${text}"
done


path: scripts/generate.sh
content: #!/bin/bash
# 小红书文案生成脚本（备用方案）
# 说明: Agent 优先使用当前对话模型直接生成文案，此脚本仅作为备用
#       当用户明确配置了环境变量并要求使用指定 API 时调用
#
# 用法:
#   bash generate.sh title "内容摘要"
#   bash generate.sh content "完整内容" "选定标题"
#
# 环境变量（均需用户设置，无默认值）:
#   XHS_AI_API_KEY  - API Key
#   XHS_AI_API_URL  - API URL（如 https://api.openai.com/v1/chat/completions）
#   XHS_AI_MODEL    - 模型名称（如 gpt-4o、deepseek-v3.2）

set -e

MODE="${1:-title}"
CONTENT="${2:-}"
TITLE="${3:-}"

# AI API 配置（需要用户设置环境变量，无默认值）
API_URL="${XHS_AI_API_URL:-}"
[REDACTED_SECRET]"
MODEL="${XHS_AI_MODEL:-}"

# 检查必要的环境变量
MISSING=""
[ -z "$API_KEY" ] && MISSING="${MISSING}  - XHS_AI_API_KEY\n"
[ -z "$API_URL" ] && MISSING="${MISSING}  - XHS_AI_API_URL\n"
[ -z "$MODEL" ] && MISSING="${MISSING}  - XHS_AI_MODEL\n"

if [ -n "$MISSING" ]; then
  echo "❌ 错误: 缺少以下环境变量:"
  echo -e "$MISSING"
  echo "示例:"
  echo "  export XHS_AI_API_KEY=\"sk-xxx\""
  echo "  export XHS_AI_API_URL=\"https://api.openai.com/v1/chat/completions\""
  echo "  export XHS_AI_MODEL=\"gpt-4o\""
  echo ""
  echo "提示: 建议直接让 Agent 使用当前对话模型生成文案，无需配置额外 API"
  exit 1
fi

if [ -z "$CONTENT" ]; then
  echo "❌ 错误: 请提供内容参数"
  echo "用法:"
  echo "  bash $0 title \"内容摘要\""
  echo "  bash $0 content \"完整内容\" \"选定标题\""
  exit 1
fi

# 转义JSON特殊字符
escape_json() {
  echo "$1" | python3 -c "import sys,json; print(json.dumps(sys.stdin.read().strip()))"
}

CONTENT_ESCAPED=$(escape_json "$CONTENT")

if [ "$MODE" = "title" ]; then
  # ========== 生成标题 ==========
  SYSTEM_PROMPT='## 小红书爆款标题生成专家\n\n### 角色设定\n你是一名资深的小红书标题大师。\n你精通各种爆款标题创作技巧。\n你擅长用标题瞬间抓住用户注意力。\n\n### 标题创作技能\n\n你掌握以下5种标题创作方法：\n1. **数字法则**：用具体数字增加可信度（如"7天"、"3个方法"）\n2. **二极管标题**：制造强烈反差和对比效果\n3. **疑问句式**：激发好奇心（如"为什么..."、"怎么..."）\n4. **情绪共鸣**：使用高唤起情绪词，瞬间唤醒用户共鸣\n5. **利益驱动**：直击痛点或利益点\n\n【7大爆款标题风格】\n- 数字悬念型：【3个懒人收纳法，房间一周不乱！】\n- 情感共鸣型：【谁懂啊！这碗面直接治愈了我的周一！】\n- 结果导向型：【跟着博主做，7天搞定Python基础！】\n- 反差对比型：【从烂脸到水光肌，我只做了这两件事】\n- 稀缺信息型：【这10个上海小众秘境，90%的人没去过】\n- 对话互动型：【你的枕头选对了吗？快来对照这份指南！】\n- 价值宣言型：【2025年投资自己，这3项技能最值钱】\n\n### 平台禁忌词（严禁使用）\n【诱导类】速来、必看、必收、千万不要、马上、抓紧、最后一波\n【夸大类】全网第一、最全、最强、史上、终极、完美、天花板、封神\n【营销类】免费送、0元购、薅羊毛、福利、红包、点击领取、价格感人\n【负面类】丑哭、踩雷、血亏、别买、避坑、垃圾、后悔、翻车\n\n### 标题创作要求\n1. 每个标题使用不同的爆款标题风格\n2. 严禁使用平台禁忌词\n3. emoji优先用✨🔥✅💡❗️😭🤔💪，每个标题最多2个\n4. 避免"XX分享""XX笔记"等无效词\n5. 使用"亲测""试过""我发现"等真实感表述\n6. 每个标题字数控制在20字以内\n7. 标题要有吸引力，让人忍不住点进来看'

  # 截取内容前500字
  CONTENT_SHORT=$(echo "$CONTENT" | head -c 1500)
  CONTENT_SHORT_ESCAPED=$(escape_json "$CONTENT_SHORT")

  USER_PROMPT="请根据以下内容，生成5个不同风格的小红书爆款标题。\n\n内容概要：\n${CONTENT_SHORT}...\n\n要求：\n1. 生成5个标题，每个使用不同的爆款标题风格\n2. 直接输出5个标题，每行一个，不要添加序号和说明\n3. 严格遵守平台禁忌词规则\n4. 每个标题字数控制在20字以内\n5. 必须包含emoji，每个标题最多2个\n\n请开始生成："

  PAYLOAD=$(cat <<EOFPAYLOAD
{
  "model": "${MODEL}",
  "messages": [
    {"role": "system", "content": $(escape_json "$SYSTEM_PROMPT")},
    {"role": "user", "content": $(escape_json "$USER_PROMPT")}
  ],
  "temperature": 0.8,
  "max_tokens": 500
}
EOFPAYLOAD
)

  echo "🔄 正在生成小红书爆款标题..."
  RESULT=$(curl -s -X POST "$API_URL" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $API_KEY" \
    -d "$PAYLOAD")

  # 提取内容
  echo "$RESULT" | python3 -c "
import sys, json
data = json.load(sys.stdin)
if 'choices' in data and len(data['choices']) > 0:
    print(data['choices'][0]['message']['content'])
else:
    print('❌ 生成失败:', json.dumps(data, ensure_ascii=False))
"

elif [ "$MODE" = "content" ]; then
  # ========== 生成正文 ==========
  if [ -z "$TITLE" ]; then
    echo "❌ 错误: 生成正文需要提供标题参数"
    echo "用法: bash $0 content \"完整内容\" \"选定标题\""
    exit 1
  fi

  TITLE_ESCAPED=$(escape_json "$TITLE")

  SYSTEM_PROMPT='## 小红书爆款正文生成专家\n\n### 角色设定\n你是一名资深的小红书爆款文案写手。\n你精通小红书平台的内容创作规则。\n你擅长创作高互动、高转化的种草文案。\n\n### 正文创作技能\n\n#### 1. 写作风格\n- **语言风格**：像朋友聊天，真诚、直接、有温度\n- **句式结构**：简单明了，主谓宾清晰，一句话一个意思\n- **词汇选择**：大白话优先，专业术语必须解释\n- **段落节奏**：每段2-3句，保持呼吸感\n\n#### 2. 写作开篇方法\n- **金句开场**：用一句话抓住注意力\n- **痛点切入**：直接说出用户困扰\n- **反转开场**：先说常见误区，再给出正确方法\n- **故事引入**：用个人经历引发共鸣\n\n#### 3. 文本结构\n- **开头**：emoji+金句/痛点（1-2句话）\n- **主体**：分点叙述，每点前加emoji，3-5个要点\n- **每个要点包含**：具体方法+个人体验+效果说明\n- **结尾**：总结+互动引导\n\n#### 4. 互动引导方法\n- **提问式**："你们有遇到这种情况吗？"\n- **征集式**："评论区说说你的方法～"\n- **行动式**："赶紧收藏起来！"\n- **共鸣式**："姐妹们懂我的扣1！"\n\n#### 5. 小技巧\n- 使用"姐妹们"、"宝子们"等亲昵称呼\n- 适当使用网络流行语和梗\n- 多用"你、我、他"，少用"其、该、此、彼"\n- 多用"真的"、"绝了"、"爱了"等语气词\n- 用"第一、第二、第三"而不是"首先、其次、最后"\n\n#### 6. 爆炸词库\n**情绪类**：绝了、爱了、yyds、无敌、炸裂、疯狂、上头、氛围感\n**效果类**：秒杀、碾压、吊打、神仙、手残党必备\n**程度类**：超级、巨、狂、暴、极致\n**共鸣类**：懂的都懂、破防了、DNA动了、真实、太真实了\n\n### 写作约束（严格执行）\n\n**禁止使用以下内容**：\n1. 不使用破折号（——）\n2. 禁用"A而且B"的对仗结构\n3. 不使用冒号（：），除非是对话或列表\n4. 开头不用设问句\n5. 一句话只表达一个完整意思\n6. 每段不超过3句话\n7. 避免嵌套从句和复合句\n8. 多用"你、我、他"，少用"其、该、此、彼"\n\n**改写策略**：\n1. **长句拆短**：把复合句拆成多个简单句\n2. **术语翻译**：把专业词汇翻译成大白话\n3. **增加温度**：适当加入个人感受和真实体验\n4. **逻辑清晰**：用"第一、第二、第三"标注顺序\n\n### 创作要求\n1. 内容真诚可信，把"真诚"摆在第一位\n2. 避免假大空，花里胡哨的内容\n3. 保持小红书社区调性，注重用户体验\n4. 正文控制在600-800字之间\n5. 在文末添加5-10个相关标签（用#号开头）'

  USER_PROMPT="请根据以下标题和内容，创作一篇爆款小红书正文。\n\n标题：\n${TITLE}\n\n内容：\n${CONTENT}\n\n---\n\n【极其重要：关于列表的绝对禁令】\n绝对禁止使用任何形式的项目符号、编号列表或bullet points，包括但不限于：\n- 星号（*）开头的列表\n- 横杠（-）开头的列表\n- 数字编号（1.、2.、3.）的列表\n- 任何形式的条目化表述\n\n所有内容必须使用连贯的段落形式，用"第一"、"第二"、"第三"等词语自然串联。\n\n创作要求：\n开篇方法：选择金句开场/痛点切入/反转开场/故事引入之一\n文本结构：开头（emoji+金句1-2句）→ 主体（3-5个要点用段落展开，每段前加emoji）→ 结尾（总结+互动引导）\n写作风格：像朋友聊天，真诚、直接、有温度\n句式要求：简单明了，一句话一个意思，每段2-3句话\n称呼使用："姐妹们"、"宝子们"等亲昵称呼\n语气词：多用"真的"、"绝了"、"爱了"等\n人称使用：多用"你、我、他"，少用"其、该、此、彼"\n互动引导：2-3处自然的互动问句\n正文控制在600-800字之间\n文末添加5-10个相关标签（用#号开头，每个标签另起一行）\n\n写作约束（严格禁止）：\n- 绝对不使用任何形式的项目符号或编号列表\n- 不使用破折号（——）\n- 禁用"A而且B"的对仗结构\n- 尽量避免使用冒号（：），用句号代替\n- 开头不用设问句\n- 避免嵌套从句和复合句\n- 所有内容都用自然段落呈现\n\n请直接输出正文内容，不要包含标题。"

  PAYLOAD=$(cat <<EOFPAYLOAD
{
  "model": "${MODEL}",
  "messages": [
    {"role": "system", "content": $(escape_json "$SYSTEM_PROMPT")},
    {"role": "user", "content": $(escape_json "$USER_PROMPT")}
  ],
  "temperature": 0.7,
  "max_tokens": 2000
}
EOFPAYLOAD
)

  echo "🔄 正在生成小红书正文..."
  RESULT=$(curl -s -X POST "$API_URL" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $API_KEY" \
    -d "$PAYLOAD")

  echo "$RESULT" | python3 -c "
import sys, json
data = json.load(sys.stdin)
if 'choices' in data and len(data['choices']) > 0:
    print(data['choices'][0]['message']['content'])
else:
    print('❌ 生成失败:', json.dumps(data, ensure_ascii=False))
"

else
  echo "❌ 未知模式: $MODE"
  echo "用法:"
  echo "  bash $0 title \"内容摘要\"       # 生成5个标题"
  echo "  bash $0 content \"内容\" \"标题\"  # 生成正文"
  exit 1
fi


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