Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,11 @@ _无。SKILL.md / scripts 业务接口 / DB schema / MCP 工具集 零变化。_
- **问题**:原脚本只查 `python3` / `sqlite3`;但 `install.sh` 自己在 upgrade-all 和初装都用 rsync 同步源码、大量脚本用 jq 解析 JSON,缺失会在执行到具体命令时直接崩
- **修复**:预检加 jq + rsync,缺失直接 fail_fast + 给 brew/apt 命令提示;关键依赖缺失不再允许"继续安装",改为硬停

**2. Gemini Key 写入目标修正:根 `.env` → `config/runtime.env`**
- **问题**:install.sh 把 `GEMINI_API_KEY=xxx` 追加到源目录根 `.env`;但运行时 `scripts/image.py` / `scripts/preflight.py` 读的是每个 target 的 `config/runtime.env` 的 `IMAGE_GEN_API_KEY` —— 两处完全断开,用户跑完 install 以为配好了,实际发帖时报"API key NOT configured"
**2. 图片 Key 写入目标修正:根 `.env` → `config/runtime.env`**
- **问题**:install.sh 把图片 Key 追加到源目录根 `.env`;但运行时 `scripts/image.py` / `scripts/preflight.py` 读的是每个 target 的 `config/runtime.env` —— 两处完全断开,用户跑完 install 以为配好了,实际发帖时报"API key NOT configured"
- **修复**:
- §6 改为只收集 `gemini_key` 变量(接受 `IMAGE_GEN_API_KEY` 或 `GEMINI_API_KEY` env var,向后兼容
- §7.5 新增 `_runtime_env_set()` 幂等函数,循环把 `IMAGE_GEN_API_KEY=<key>` 写入每个 target 的 `config/runtime.env`(已有值则保留,不覆盖)
- §6 改为收集 Gemini 原生 Key 与 OpenAI 兼容 Key(接受 `GEMINI_API_KEY`、`IMAGE_GEN_API_KEY` 或 `OPENAI_API_KEY` env var)
- §7.5 新增 `_runtime_env_set()` 幂等函数,循环把 `GEMINI_API_KEY` / `IMAGE_GEN_API_KEY` 写入每个 target 的 `config/runtime.env`
- 同步源目录 `config/runtime.env`,方便在源目录跑脚本验证
- **MCP URL** 同样修正:从 `XHS_MCP_URL` 写入 `config/runtime.env` 的 `MCP_URL`

Expand All @@ -140,15 +140,15 @@ git pull
bash install.sh upgrade-all --json # v2.4.0 的 upgrade-all 本身正常,不受本版 bugfix 影响
```

**如果你是刚装完 v2.4.0 但没跑通发帖**,大概率是 Gemini Key 只写到了根 `.env`。修复方式:
**如果你是刚装完 v2.4.0 但没跑通发帖**,大概率是图片 Key 只写到了根 `.env`。修复方式:

```bash
# 方式 A(推荐):升级到 v2.4.1 + 重跑 install
git pull && bash install.sh
# 会自动把 gemini_key 同步到各 target 的 config/runtime.env
# 会自动把图片 Key 同步到各 target 的 config/runtime.env

# 方式 B(不升级,手动同步):
python3 scripts/image.py --set-key <your-gemini-key>
python3 scripts/image.py --set-key <your-image-api-key>
```

### 🧠 Brain
Expand Down
26 changes: 14 additions & 12 deletions SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,11 +247,12 @@ python3 scripts/preflight.py
- **用户主动提议方案优先**:用户说"我给你 cookie"/"我直接粘贴"/"帮我用 cookie 登录"等任何变体 → **立即接受**,让用户从浏览器复制完整 `Cookie` 头字符串,调用 `bash scripts/xhs.sh import-cookie '<cookie字符串>'`。**不要绕回扫码、不要继续解释扫码流程**
- 默认扫码:执行 `bash scripts/xhs.sh login` 获取二维码链接,返回给上层让用户扫码

2. **图片生成 API**(**必需** —— 强制 Gemini,无降级路径)
- 薯灵已移除 HTML 截图降级。没有 Gemini API Key 就无法生图,也就无法发帖
- 问用户:"薯灵需要 Gemini 图片 API(免费额度 / 有 Nano Banana Pro 模型)。请提供你的 API Key。"
- 获取地址:https://aistudio.google.com/app/apikey
- 拿到 Key 写入:`python3 scripts/image.py --set-key <KEY>`
2. **图片生成 API**(**必需** —— 首次固定选择一种供应商,无自动切换)
- 薯灵已移除 HTML 截图降级。没有图片 API Key 就无法生图,也就无法发帖
- 首次使用必须先问用户:"你能提供哪一种图片 API?1) Gemini 原生 API;2) OpenAI 兼容图片 API。确认后我会固定使用这一种,后续真实生图不自动切换。"
- 用户选 Gemini:写 `IMAGE_GEN_PROTOCOL=gemini-native`,配置 `GEMINI_API_KEY`、`GEMINI_IMAGE_MODEL=gemini-2.5-flash-image`
- 用户选 OpenAI 兼容:写 `IMAGE_GEN_PROTOCOL=openai-images`,配置 `IMAGE_GEN_API_KEY`、`IMAGE_GEN_OPENAI_MODEL`、`IMAGE_GEN_BASE_URL`
- 拿到协议选择后再写 Key:`python3 scripts/image.py --set-key <KEY>`
- **用户拒绝提供 Key 时**:明确告知这是强依赖,安装流程停在这一步,不进入 §1 建画像

> **不要在 0 节问 Telegram / IM 通讯凭证**——通讯渠道由 hermes-agent 自己配置,不属于 skill 业务范围。
Expand Down Expand Up @@ -285,7 +286,7 @@ python3 scripts/preflight.py

```bash
MCP_URL=http://localhost:18060/mcp
# IMAGE_GEN_PROVIDER=gemini
# IMAGE_GEN_PROVIDER=openai-compatible
# IMAGE_GEN_API_KEY=...
```

Expand Down Expand Up @@ -671,7 +672,7 @@ scripts/db.sh log-choice '{"choice_type":"draft","offered_count":2,"chosen_index
python3 scripts/image.py --check
```
- 返回 0 → 走 AI 生图(下面的第 4 步)
- 返回 2 → **硬停**。告诉用户:"Gemini API Key 未配置,薯灵强制使用 Gemini 生图,请先配置 Key 才能继续",不要尝试降级任何 HTML 截图路径
- 返回 2 → **硬停**。告诉用户:"图片 API 类型或 Key 未配置,请先确认固定使用 Gemini 原生还是 OpenAI 兼容,并提供对应 Key",不要尝试自动切换或降级任何 HTML 截图路径

4. **AI 生图路径**(中文模板驱动,两阶段生成)

Expand Down Expand Up @@ -714,9 +715,10 @@ scripts/db.sh log-choice '{"choice_type":"draft","offered_count":2,"chosen_index

**提示词理念**(跟 RedInk 对齐,**不要违反**):
- **禁止自己写英文 prompt**——模板已经是中文的 77 行完整约束
- **禁止说"不要包含文字"**——Gemini 3 Pro 的中文字形渲染已过关,强制"文字必须完整呈现"反而更像小红书
- **禁止说"不要包含文字"**——当前 Gemini / OpenAI 图片模型的中文排版能力已够用,强制"文字必须完整呈现"更符合小红书图文
- **禁止用 `IMAGE_BRAND_STYLE` 拼前缀**——模板里"小红书爆款图文风格"这个锚词就是品牌风格的最高表达
- **推荐模型**:`gemini-3-pro-image-preview`(Nano Banana Pro,中文文字 + multimodal 参考图都最准)
- **协议规则**:`IMAGE_GEN_PROTOCOL` 必须固定为 `gemini-native` 或 `openai-images`,不要使用 `auto`
- **模型选择**:Gemini 原生 `gemini-2.5-flash-image`;OpenAI 兼容常用 `gpt-image-2`

**极短 prompt 兜底**(仅当 API 上下文受限):加 `--short` 切到 `prompts/image_prompt_short.txt`(6 行极简版)。

Expand Down Expand Up @@ -1101,11 +1103,11 @@ scripts/xhs.sh user <user_id> # 用户主页信息

```bash
python3 scripts/image.py --check # 检查 API Key,exit 0=可用,2=未配置
python3 scripts/image.py --set-key "API_KEY" # 配置 Gemini Key
python3 scripts/image.py --set-key "API_KEY" # 配置图片 API Key
python3 scripts/image.py "图片描述prompt" /output.png # 生成图片
```

环境变量:`IMAGE_GEN_API_KEY`、`IMAGE_GEN_MODEL`(默认 gemini-2.0-flash-preview-image-generation)
环境变量:先固定 `IMAGE_GEN_PROTOCOL=gemini-native` 或 `IMAGE_GEN_PROTOCOL=openai-images`;Gemini 使用 `GEMINI_API_KEY`、`GEMINI_IMAGE_MODEL`;OpenAI 兼容使用 `IMAGE_GEN_API_KEY`、`IMAGE_GEN_OPENAI_MODEL`、`IMAGE_GEN_BASE_URL`


### scripts/db.sh — 数据库操作
Expand Down Expand Up @@ -1195,7 +1197,7 @@ scripts/noterx-diagnose.sh --test
|------|---------|
| MCP 未运行 | `xhs.sh` 自动尝试启动,失败则提示用户 |
| 登录过期 | `xhs.sh login` 获取二维码 → 返回给上层让用户扫码;若用户主动给 cookie,用 `xhs.sh import-cookie` |
| Gemini 不可用 | 硬停并提示用户配置 Key(已不再提供 HTML 截图降级) |
| 图片 API 不可用 | 硬停并提示用户配置 Key(已不再提供 HTML 截图降级) |
| 用户长时间不回复 | 超时后自动选择评分最高的(超时时间由平台层配置) |
| 知识库文件损坏/不存在 | 用默认值继续,不阻塞创作 |
| 发布失败 | 返回失败原因,保留 meta.json 供重试 |
Expand Down
12 changes: 7 additions & 5 deletions UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,11 @@ cd <target> && python3 scripts/preflight.py --json
> ⚠️ 本条目为 v2.4.0 发版时**补录**(v2.3.0 发版时 UPGRADE.md 漏更新)。

**类型**:HANDS + CALIB
**Breaking**:**有** —— 之前靠 HTML 截图兜底的部署必须配 Gemini API Key
**Breaking**:**有** —— 之前靠 HTML 截图兜底的部署必须配置图片 API Key

**变化**:
- HTML 截图降级路径完全删除(`scripts/screenshot.cjs` / `templates/post.html` 移除)
- Gemini API Key 从可选变必需
- 图片 API Key 从可选变必需,且必须先固定选择 Gemini 原生或 OpenAI 兼容其中一种
- `scripts/image.py` 重写:`render_prompt()` 模板系统 + `--reference` 封面回流 + `--short` 极简 fallback
- 新增 `prompts/image_prompt.txt` / `prompts/image_prompt_short.txt` 中文模板
- `generated_images.prompt` 字段改为存 `page_content` 短语义(节省空间 + 便于 pattern 学习)
Expand All @@ -121,14 +121,14 @@ cd <target> && python3 scripts/preflight.py --json

```bash
cd /path/to/shuling && git pull
bash install.sh # 会强制问 Gemini API Key(老安装已配则不问)
bash install.sh # 会强制问图片 API Key(老安装已配则不问)

# 预检
python3 scripts/image.py --check # 返回 0 才能继续
```

**兼容性说明**:
- 老部署若未配 Gemini Key:发帖流程 §2.3 会硬停,按提示补配
- 老部署若未配图片 API Key:发帖流程 §2.3 会硬停,按提示补配
- 老数据(posts / generated_images)完全保留
- v2.4.0 起 upgrade-hooks/v2.3.0/ 提供自动化路径(`runtime-env-sync.sh` 跨 target 借用 Key)

Expand Down Expand Up @@ -249,7 +249,9 @@ ls schemas/ # 应看到 3 个 .schema.json
| 变量 | 默认 | 作用 |
|---|---|---|
| `SHULING_ASSUME_YES` | `0` | 设 `1` 等同 `--yes`,所有交互用默认值 |
| `GEMINI_API_KEY` | 空 | 非交互模式下预填 Gemini Key,避免被 prompt 卡住 |
| `IMAGE_GEN_PROTOCOL` | 空 | 非交互模式下固定图片 API 类型:`gemini-native` 或 `openai-images` |
| `GEMINI_API_KEY` | 空 | 非交互模式下预填 Gemini 原生图片 Key,避免被 prompt 卡住 |
| `IMAGE_GEN_API_KEY` / `OPENAI_API_KEY` | 空 | 非交互模式下预填 OpenAI 兼容图片 Key |
| `XHS_MCP_URL` | 空 | 非交互模式下预填 MCP URL |

> `preflight.py` 退出码从 v2.1.3 起分级:`0` 就绪 / `1` 可自动修复 / `2` 需用户配合。如果你的 CI 脚本之前假设 exit=0 就是"没问题",请复核——以前总是返回 0。
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ calib:
migration_idempotency: "v2.4.0" # v2.4.0 新增:__migrations 表 + _guard.sh
dependencies_locked: "v2.4.0" # v2.4.0 新增:requirements.txt
install_dep_check: "v2.4.1" # v2.4.1 新增:install.sh 补 jq + rsync 依赖检查
install_env_write_target: "config/runtime.env" # v2.4.1 修正:从根 .env 的 GEMINI_API_KEY → config/runtime.env IMAGE_GEN_API_KEY
install_env_write_target: "config/runtime.env" # v2.4.1 修正:从根 .env → config/runtime.env;v2.4.x 支持 GEMINI_API_KEY + IMAGE_GEN_API_KEY
preflight_mcp_strict: "v2.4.1" # v2.4.1 修正:check_mcp 否定信号优先,去掉 state.mcp_configured 掩盖失败的 fallback
runtime_env_force_override: "v2.4.2" # v2.4.2 修正:_runtime_env_set 强制覆盖模板默认值(MCP_URL 才能被真写入)
install_target_db_init: "v2.4.2" # v2.4.2 新增:每 target 循环跑 db.sh init,target 的 data/xhs.db 不再 not_initialized
Expand Down
23 changes: 17 additions & 6 deletions config/runtime.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,32 @@
# ─── 小红书 MCP 服务地址 ──────────────────────────────────────
MCP_URL=http://localhost:18060/mcp

# ─── 图片生成(必需 —— 强制 Gemini,无降级)──────────────────
# 薯灵已移除 HTML 截图降级路径。没有下面这个 Key 无法生图 → 无法发帖。
# ─── 图片生成(必需 —— 首次固定选择一种供应商)──────────
# 薯灵已移除 HTML 截图降级路径。没有可用图片 API Key 无法生图 → 无法发帖。
# 首次使用时必须选择一种协议;后续真实生图只使用选中的供应商,不自动切换。
IMAGE_GEN_PROTOCOL=

# Gemini 原生生图(二选一)
# 获取地址: https://aistudio.google.com/app/apikey
GEMINI_API_KEY=
GEMINI_IMAGE_MODEL=gemini-2.5-flash-image
# GEMINI_BASE_URL=https://generativelanguage.googleapis.com/v1beta
# GEMINI_ASPECT_RATIO=3:4
# GEMINI_IMAGE_SIZE=1K

# OpenAI 兼容图片接口(二选一)
IMAGE_GEN_API_KEY=
# IMAGE_GEN_MODEL=gemini-3-pro-image-preview # Nano Banana Pro,中文准 + 支持参考图
# IMAGE_GEN_PROTOCOL=gemini-native # 或 openai-chat(走兼容代理时)
# IMAGE_GEN_BASE_URL=https://generativelanguage.googleapis.com
IMAGE_GEN_OPENAI_MODEL=gpt-image-2
IMAGE_GEN_BASE_URL=https://api.gjs.ink
# IMAGE_GEN_SIZE=1024x1536

# ─── NoteRx 诊断(可选,默认用 muran 公网地址)────────────────
# NOTERX_API_URL=https://noterx.muran.tech
# NOTERX_TIMEOUT_PRE=15
# NOTERX_TIMEOUT_FULL=150

# ─── 图片品牌风格(已弃用)────────────────────────────
# 旧版用 IMAGE_BRAND_STYLE 把英文设计语境拼到 prompt 前面,实测会把 Gemini
# 旧版用 IMAGE_BRAND_STYLE 把英文设计语境拼到 prompt 前面,实测会把模型
# 拉到欧美 infographic 样本池,生出来像 Notion/Medium 而不像小红书。
# 新版生图已改用 prompts/image_prompt.txt 中文模板,直接锚小红书爆款图文风格,
# 请不要再设这个变量。
Expand Down
Loading