| 1 | # Browser CLI Unification Implementation Plan |
| 2 | |
| 3 | > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. |
| 4 | |
| 5 | **Goal:** 为抖音、快手、小红书三家浏览器平台统一 `sau` CLI 契约,补齐小红书 CLI/skill,并把视频正文统一为 `desc`、图文正文统一为 `note`。 |
| 6 | |
| 7 | **Architecture:** 保持现有 `sau_cli.py` 单文件主入口,不引入新的 CLI 框架。`sau_cli.py` 负责 parser、request dataclass、dispatch 和账号文件解析;各平台 uploader 只做最小字段接线;skill、README、CLI/install/update 文档、examples 同步切到统一契约,避免对外同时暴露多套命名。 |
| 8 | |
| 9 | **Tech Stack:** Python 3.10+, `argparse`, `asyncio`, `dataclasses`, `pathlib`, `unittest`, existing Patchright-based uploaders, repository markdown docs |
| 10 | |
| 11 | --- |
| 12 | |
| 13 | ## File Structure |
| 14 | |
| 15 | ### New files |
| 16 | |
| 17 | - `tests/test_sau_browser_cli.py` |
| 18 | - 覆盖三家浏览器平台统一 CLI parser / dispatch / request 映射 |
| 19 | - `skills/xiaohongshu-upload/SKILL.md` |
| 20 | - 小红书 CLI skill 主说明 |
| 21 | - `skills/xiaohongshu-upload/references/runtime-requirements.md` |
| 22 | - 小红书运行前提 |
| 23 | - `skills/xiaohongshu-upload/references/cli-contract.md` |
| 24 | - 小红书 CLI 契约 |
| 25 | - `skills/xiaohongshu-upload/references/troubleshooting.md` |
| 26 | - 小红书排障文档 |
| 27 | - `skills/xiaohongshu-upload/scripts/examples/xiaohongshu_commands.ps1` |
| 28 | - PowerShell 示例命令 |
| 29 | - `skills/xiaohongshu-upload/scripts/examples/xiaohongshu_commands.sh` |
| 30 | - shell 示例命令 |
| 31 | - `skills/xiaohongshu-upload/scripts/examples/xiaohongshu_cli_template.py` |
| 32 | - Python 命令模板 |
| 33 | |
| 34 | ### Modified files |
| 35 | |
| 36 | - `sau_cli.py` |
| 37 | - 新增 `xiaohongshu` parser / dispatch |
| 38 | - 改造抖音、快手 request dataclass 和参数模型 |
| 39 | - `uploader/douyin_uploader/main.py` |
| 40 | - 给视频接入 `desc` |
| 41 | - 给图文接入 `title + note` |
| 42 | - `uploader/ks_uploader/main.py` |
| 43 | - 给视频接入 `desc` |
| 44 | - 给图文接入 `title + note` |
| 45 | - `uploader/xiaohongshu_uploader/main.py` |
| 46 | - 只补 CLI 接线所需的最小字段适配 |
| 47 | - `README.md` |
| 48 | - 补小红书 CLI / skill,并统一三家参数说明 |
| 49 | - `docs/CLI.md` |
| 50 | - 统一三家浏览器平台命令契约 |
| 51 | - `docs/install.md` |
| 52 | - 补小红书 CLI 示例和统一参数说明 |
| 53 | - `docs/update.md` |
| 54 | - 补小红书检查项与 skill 路径 |
| 55 | - `skills/douyin-upload/SKILL.md` |
| 56 | - `skills/douyin-upload/references/cli-contract.md` |
| 57 | - `skills/douyin-upload/scripts/examples/douyin_commands.ps1` |
| 58 | - `skills/douyin-upload/scripts/examples/douyin_commands.sh` |
| 59 | - `skills/douyin-upload/scripts/examples/douyin_cli_template.py` |
| 60 | - `skills/kuaishou-upload/SKILL.md` |
| 61 | - `skills/kuaishou-upload/references/cli-contract.md` |
| 62 | - `skills/kuaishou-upload/scripts/examples/kuaishou_commands.ps1` |
| 63 | - `skills/kuaishou-upload/scripts/examples/kuaishou_commands.sh` |
| 64 | - `skills/kuaishou-upload/scripts/examples/kuaishou_cli_template.py` |
| 65 | - `examples/get_xiaohongshu_cookie.py` |
| 66 | - `examples/upload_video_to_xiaohongshu.py` |
| 67 | |
| 68 | ## Task 1: 用测试锁定统一 CLI 契约 |
| 69 | |
| 70 | **Files:** |
| 71 | - Create: `tests/test_sau_browser_cli.py` |
| 72 | - Reference: `sau_cli.py` |
| 73 | |
| 74 | - [ ] **Step 1: 写统一 CLI parser 测试** |
| 75 | |
| 76 | 在 `tests/test_sau_browser_cli.py` 里覆盖最小命令契约: |
| 77 | |
| 78 | ```python |
| 79 | import asyncio |
| 80 | import unittest |
| 81 | from argparse import Namespace |
| 82 | from pathlib import Path |
| 83 | from unittest.mock import AsyncMock, patch |
| 84 | |
| 85 | import sau_cli |
| 86 | |
| 87 | |
| 88 | class BrowserCliParserTests(unittest.TestCase): |
| 89 | def test_build_parser_accepts_xiaohongshu_login(self): |
| 90 | parser = sau_cli.build_parser() |
| 91 | args = parser.parse_args(["xiaohongshu", "login", "--account", "creator"]) |
| 92 | self.assertEqual(args.platform, "xiaohongshu") |
| 93 | self.assertEqual(args.action, "login") |
| 94 | |
| 95 | def test_douyin_upload_video_accepts_desc(self): |
| 96 | parser = sau_cli.build_parser() |
| 97 | args = parser.parse_args([ |
| 98 | "douyin", "upload-video", |
| 99 | "--account", "creator", |
| 100 | "--file", "demo.mp4", |
| 101 | "--title", "标题", |
| 102 | "--desc", "视频简介", |
| 103 | ]) |
| 104 | self.assertEqual(args.desc, "视频简介") |
| 105 | |
| 106 | def test_kuaishou_upload_note_accepts_title_and_note(self): |
| 107 | parser = sau_cli.build_parser() |
| 108 | args = parser.parse_args([ |
| 109 | "kuaishou", "upload-note", |
| 110 | "--account", "creator", |
| 111 | "--images", "1.png", |
| 112 | "--title", "图文标题", |
| 113 | "--note", "图文正文", |
| 114 | ]) |
| 115 | self.assertEqual(args.title, "图文标题") |
| 116 | self.assertEqual(args.note, "图文正文") |
| 117 | ``` |
| 118 | |
| 119 | - [ ] **Step 2: 写 dispatch 路由测试** |
| 120 | |
| 121 | 继续在 `tests/test_sau_browser_cli.py` 中补最小 dispatch 验证: |
| 122 | |
| 123 | ```python |
| 124 | class BrowserCliDispatchTests(unittest.TestCase): |
| 125 | def test_dispatch_xiaohongshu_check_prints_valid(self): |
| 126 | args = Namespace(platform="xiaohongshu", action="check", account="creator") |
| 127 | with patch("sau_cli.check_xiaohongshu_account", new=AsyncMock(return_value=True)): |
| 128 | code = asyncio.run(sau_cli.dispatch(args)) |
| 129 | self.assertEqual(code, 0) |
| 130 | |
| 131 | def test_dispatch_douyin_upload_note_uses_new_request_fields(self): |
| 132 | args = Namespace( |
| 133 | platform="douyin", |
| 134 | action="upload-note", |
| 135 | account="creator", |
| 136 | images=[Path("1.png")], |
| 137 | title="图文标题", |
| 138 | note="图文正文", |
| 139 | tags="测试,图文", |
| 140 | schedule=0, |
| 141 | debug=False, |
| 142 | headless=True, |
| 143 | ) |
| 144 | with patch("sau_cli.upload_note", new=AsyncMock()) as mock_upload: |
| 145 | asyncio.run(sau_cli.dispatch(args)) |
| 146 | request = mock_upload.await_args.args[0] |
| 147 | self.assertEqual(request.title, "图文标题") |
| 148 | self.assertEqual(request.note, "图文正文") |
| 149 | ``` |
| 150 | |
| 151 | - [ ] **Step 3: 先跑测试确认失败** |
| 152 | |
| 153 | Run: |
| 154 | |
| 155 | ```powershell |
| 156 | py -3 -m unittest tests.test_sau_browser_cli -v |
| 157 | ``` |
| 158 | |
| 159 | Expected: |
| 160 | |
| 161 | - 因为 `sau_cli.py` 还没有 `xiaohongshu` 分支和统一字段而失败 |
| 162 | |
| 163 | - [ ] **Step 4: 提交测试脚手架** |
| 164 | |
| 165 | ```powershell |
| 166 | git add tests/test_sau_browser_cli.py |
| 167 | git commit -m "test: define browser cli unification contract" |
| 168 | ``` |
| 169 | |
| 170 | ## Task 2: 改 `sau_cli.py`,补齐统一参数与小红书路由 |
| 171 | |
| 172 | **Files:** |
| 173 | - Modify: `sau_cli.py` |
| 174 | - Reference: `uploader/xiaohongshu_uploader/main.py` |
| 175 | - Reference: `uploader/douyin_uploader/main.py` |
| 176 | - Reference: `uploader/ks_uploader/main.py` |
| 177 | |
| 178 | - [ ] **Step 1: 增加小红书 request dataclass** |
| 179 | |
| 180 | 在 `sau_cli.py` 中新增: |
| 181 | |
| 182 | ```python |
| 183 | @dataclass(slots=True) |
| 184 | class XiaohongshuVideoUploadRequest: |
| 185 | account_name: str |
| 186 | video_file: Path |
| 187 | title: str |
| 188 | description: str |
| 189 | tags: list[str] |
| 190 | publish_date: datetime | int |
| 191 | thumbnail_file: Path | None = None |
| 192 | publish_strategy: str = XIAOHONGSHU_PUBLISH_STRATEGY_IMMEDIATE |
| 193 | debug: bool = True |
| 194 | headless: bool = True |
| 195 | |
| 196 | |
| 197 | @dataclass(slots=True) |
| 198 | class XiaohongshuNoteUploadRequest: |
| 199 | account_name: str |
| 200 | image_files: list[Path] |
| 201 | title: str |
| 202 | note: str |
| 203 | tags: list[str] |
| 204 | publish_date: datetime | int |
| 205 | publish_strategy: str = XIAOHONGSHU_PUBLISH_STRATEGY_IMMEDIATE |
| 206 | debug: bool = True |
| 207 | headless: bool = True |
| 208 | ``` |
| 209 | |
| 210 | - [ ] **Step 2: 改造抖音、快手 request dataclass** |
| 211 | |
| 212 | 把字段统一到以下模型: |
| 213 | |
| 214 | ```python |
| 215 | class DouyinVideoUploadRequest: |
| 216 | title: str |
| 217 | description: str |
| 218 | |
| 219 | class DouyinNoteUploadRequest: |
| 220 | title: str |
| 221 | note: str |
| 222 | |
| 223 | class KuaishouVideoUploadRequest: |
| 224 | title: str |
| 225 | description: str |
| 226 | |
| 227 | class KuaishouNoteUploadRequest: |
| 228 | title: str |
| 229 | note: str |
| 230 | ``` |
| 231 | |
| 232 | 要求: |
| 233 | |
| 234 | - 视频用 `description` |
| 235 | - 图文用 `note` |
| 236 | - 不再把图文 request 设计成只有历史 `note` 语义但没有 `title` |
| 237 | |
| 238 | - [ ] **Step 3: 改 parser** |
| 239 | |
| 240 | 在 `build_parser()` 里完成: |
| 241 | |
| 242 | - `douyin upload-video` 增加 `--desc` |
| 243 | - `kuaishou upload-video` 增加 `--desc` |
| 244 | - `douyin upload-note` 改成 `--title --note` |
| 245 | - `kuaishou upload-note` 改成 `--title --note` |
| 246 | - 新增整套 `xiaohongshu`: |
| 247 | - `login` |
| 248 | - `check` |
| 249 | - `upload-video --title --desc --tags --thumbnail` |
| 250 | - `upload-note --images --title --note --tags` |
| 251 | |
| 252 | - [ ] **Step 4: 补小红书账号操作函数** |
| 253 | |
| 254 | 在 `sau_cli.py` 中新增: |
| 255 | |
| 256 | ```python |
| 257 | async def login_xiaohongshu_account(account_name: str, headless: bool = True) -> dict: ... |
| 258 | async def check_xiaohongshu_account(account_name: str) -> bool: ... |
| 259 | async def upload_xiaohongshu_video(request: XiaohongshuVideoUploadRequest) -> Path: ... |
| 260 | async def upload_xiaohongshu_note(request: XiaohongshuNoteUploadRequest) -> Path: ... |
| 261 | ``` |
| 262 | |
| 263 | 要求: |
| 264 | |
| 265 | - 账号路径继续走 `resolve_account_file("xiaohongshu", account_name)` |
| 266 | - 登录 / 检查分别复用 `xiaohongshu_setup` 与 `cookie_auth` |
| 267 | - 上传前先做 `setup(handle=False)` 校验 |
| 268 | |
| 269 | - [ ] **Step 5: 改 dispatch** |
| 270 | |
| 271 | 要求: |
| 272 | |
| 273 | - 三家浏览器平台都统一输出: |
| 274 | - `login` 成功时打印账号文件路径 |
| 275 | - `check` 输出 `valid` / `invalid` |
| 276 | - `upload-video` 打印简洁摘要 |
| 277 | - `upload-note` 打印图片数量摘要 |
| 278 | - request 构造统一映射: |
| 279 | - 视频:`title + description` |
| 280 | - 图文:`title + note` |
| 281 | |
| 282 | - [ ] **Step 6: 跑 CLI 测试确认通过** |
| 283 | |
| 284 | Run: |
| 285 | |
| 286 | ```powershell |
| 287 | py -3 -m unittest tests.test_sau_browser_cli -v |
| 288 | ``` |
| 289 | |
| 290 | Expected: |
| 291 | |
| 292 | - `BrowserCliParserTests` |
| 293 | - `BrowserCliDispatchTests` |
| 294 | |
| 295 | 全部通过 |
| 296 | |
| 297 | - [ ] **Step 7: 跑最小 help 自检** |
| 298 | |
| 299 | Run: |
| 300 | |
| 301 | ```powershell |
| 302 | py -3 sau_cli.py douyin --help |
| 303 | py -3 sau_cli.py kuaishou --help |
| 304 | py -3 sau_cli.py xiaohongshu --help |
| 305 | py -3 sau_cli.py xiaohongshu upload-note --help |
| 306 | ``` |
| 307 | |
| 308 | Expected: |
| 309 | |
| 310 | - 小红书子命令存在 |
| 311 | - 图文命令展示 `--title`、`--note` |
| 312 | - 视频命令展示 `--desc` |
| 313 | |
| 314 | - [ ] **Step 8: 提交 CLI 主线** |
| 315 | |
| 316 | ```powershell |
| 317 | git add sau_cli.py tests/test_sau_browser_cli.py |
| 318 | git commit -m "feat: unify browser cli contracts" |
| 319 | ``` |
| 320 | |
| 321 | ## Task 3: 给 uploader 做最小字段接线 |
| 322 | |
| 323 | **Files:** |
| 324 | - Modify: `uploader/douyin_uploader/main.py` |
| 325 | - Modify: `uploader/ks_uploader/main.py` |
| 326 | - Modify: `uploader/xiaohongshu_uploader/main.py` |
| 327 | - Modify: `tests/test_xiaohongshu_uploader.py` |
| 328 | |
| 329 | - [ ] **Step 1: 给抖音视频接入 `desc`** |
| 330 | |
| 331 | 在 `DouYinVideo.__init__()` 中补 `desc` 参数和 `self.desc`,并把发布页填写逻辑改成: |
| 332 | |
| 333 | ```python |
| 334 | await self.fill_title_and_description(page, self.title, self.desc or self.title, self.tags) |
| 335 | ``` |
| 336 | |
| 337 | - [ ] **Step 2: 给抖音图文接入 `title + note`** |
| 338 | |
| 339 | 在 `DouYinNote.__init__()` 中补 `title` 参数,保留 `note` 作为图文正文,发布页填写改成: |
| 340 | |
| 341 | ```python |
| 342 | await self.fill_title_and_description(page, self.title, self.note, self.tags) |
| 343 | ``` |
| 344 | |
| 345 | 要求: |
| 346 | |
| 347 | - `title` 必填 |
| 348 | - `note` 可选但建议非空;如果现有逻辑要求非空,就继续保留校验 |
| 349 | |
| 350 | - [ ] **Step 3: 给快手视频接入 `desc`** |
| 351 | |
| 352 | 在 `KSVideo.__init__()` 中补 `desc` 参数和 `self.desc`,填写“描述”区域时改成: |
| 353 | |
| 354 | ```python |
| 355 | await page.keyboard.type(self.desc or self.title) |
| 356 | ``` |
| 357 | |
| 358 | - [ ] **Step 4: 给快手图文接入 `title + note`** |
| 359 | |
| 360 | 在 `KSNote.__init__()` 中补 `title` 参数与 `self.title`,保留 `self.note` 作为正文。 |
| 361 | |
| 362 | 要求: |
| 363 | |
| 364 | - 图文上传校验里增加 `title` 必填 |
| 365 | - 如果页面当前只有正文输入区,没有独立标题区,仍然要在 CLI / request / 构造函数层保持 `title` 字段,以便后续平台对齐 |
| 366 | |
| 367 | - [ ] **Step 5: 检查小红书 CLI 接线是否需要补充适配** |
| 368 | |
| 369 | 确认 `XiaoHongShuVideo` / `XiaoHongShuNote` 只需要以下映射即可: |
| 370 | |
| 371 | ```python |
| 372 | title=request.title |
| 373 | desc=request.description # 视频 |
| 374 | desc=request.note # 图文 |
| 375 | ``` |
| 376 | |
| 377 | 如果 `XiaoHongShuNote` 里还保留历史 `note` 兼容,不要删,只保持 CLI 层优先走 `title + note + tags`。 |
| 378 | |
| 379 | - [ ] **Step 6: 补一条小红书映射测试** |
| 380 | |
| 381 | 在 `tests/test_xiaohongshu_uploader.py` 中增加最小断言: |
| 382 | |
| 383 | ```python |
| 384 | def test_note_title_defaults_do_not_override_explicit_title(self): |
| 385 | app = xhs_main.XiaoHongShuNote( |
| 386 | image_paths=["a.png"], |
| 387 | note="正文", |
| 388 | tags=[], |
| 389 | publish_date=0, |
| 390 | account_file="account.json", |
| 391 | title="显式标题", |
| 392 | desc="图文正文", |
| 393 | ) |
| 394 | self.assertEqual(app.title, "显式标题") |
| 395 | self.assertEqual(app.desc, "图文正文") |
| 396 | ``` |
| 397 | |
| 398 | - [ ] **Step 7: 跑 uploader 相关测试** |
| 399 | |
| 400 | Run: |
| 401 | |
| 402 | ```powershell |
| 403 | py -3 -m unittest tests.test_xiaohongshu_uploader -v |
| 404 | ``` |
| 405 | |
| 406 | Expected: |
| 407 | |
| 408 | - 小红书 uploader 相关单测通过 |
| 409 | |
| 410 | - [ ] **Step 8: 提交 uploader 接线** |
| 411 | |
| 412 | ```powershell |
| 413 | git add uploader/douyin_uploader/main.py uploader/ks_uploader/main.py uploader/xiaohongshu_uploader/main.py tests/test_xiaohongshu_uploader.py |
| 414 | git commit -m "feat: align browser uploader metadata fields" |
| 415 | ``` |
| 416 | |
| 417 | ## Task 4: 新增小红书 skill,并同步更新抖音、快手 skill |
| 418 | |
| 419 | **Files:** |
| 420 | - Create: `skills/xiaohongshu-upload/SKILL.md` |
| 421 | - Create: `skills/xiaohongshu-upload/references/runtime-requirements.md` |
| 422 | - Create: `skills/xiaohongshu-upload/references/cli-contract.md` |
| 423 | - Create: `skills/xiaohongshu-upload/references/troubleshooting.md` |
| 424 | - Create: `skills/xiaohongshu-upload/scripts/examples/xiaohongshu_commands.ps1` |
| 425 | - Create: `skills/xiaohongshu-upload/scripts/examples/xiaohongshu_commands.sh` |
| 426 | - Create: `skills/xiaohongshu-upload/scripts/examples/xiaohongshu_cli_template.py` |
| 427 | - Modify: `skills/douyin-upload/SKILL.md` |
| 428 | - Modify: `skills/douyin-upload/references/cli-contract.md` |
| 429 | - Modify: `skills/douyin-upload/scripts/examples/douyin_commands.ps1` |
| 430 | - Modify: `skills/douyin-upload/scripts/examples/douyin_commands.sh` |
| 431 | - Modify: `skills/douyin-upload/scripts/examples/douyin_cli_template.py` |
| 432 | - Modify: `skills/kuaishou-upload/SKILL.md` |
| 433 | - Modify: `skills/kuaishou-upload/references/cli-contract.md` |
| 434 | - Modify: `skills/kuaishou-upload/scripts/examples/kuaishou_commands.ps1` |
| 435 | - Modify: `skills/kuaishou-upload/scripts/examples/kuaishou_commands.sh` |
| 436 | - Modify: `skills/kuaishou-upload/scripts/examples/kuaishou_cli_template.py` |
| 437 | |
| 438 | - [ ] **Step 1: 复制现有 skill 目录结构作为小红书骨架** |
| 439 | |
| 440 | 要求: |
| 441 | |
| 442 | - 风格对齐 `skills/douyin-upload/` |
| 443 | - 默认优先走 `sau xiaohongshu ...` |
| 444 | - 明确小红书支持: |
| 445 | - `login` |
| 446 | - `check` |
| 447 | - `upload-video` |
| 448 | - `upload-note` |
| 449 | |
| 450 | - [ ] **Step 2: 写小红书 CLI 契约** |
| 451 | |
| 452 | 至少写清: |
| 453 | |
| 454 | ```bash |
| 455 | sau xiaohongshu login --account <account> |
| 456 | sau xiaohongshu check --account <account> |
| 457 | sau xiaohongshu upload-video --account <account> --file <video> --title "<title>" [--desc "..."] [--tags ...] |
| 458 | sau xiaohongshu upload-note --account <account> --images <img...> --title "<title>" [--note "..."] [--tags ...] |
| 459 | ``` |
| 460 | |
| 461 | - [ ] **Step 3: 更新抖音、快手 skill 契约** |
| 462 | |
| 463 | 要求: |
| 464 | |
| 465 | - 视频示例命令补 `--desc` |
| 466 | - 图文示例命令改成 `--title --note` |
| 467 | - 所有模板文件同步更新,不要只改文档不改脚本 |
| 468 | |
| 469 | - [ ] **Step 4: 做 skill 文件级自检** |
| 470 | |
| 471 | Run: |
| 472 | |
| 473 | ```powershell |
| 474 | Get-ChildItem skills\xiaohongshu-upload -Recurse |
| 475 | Get-Content skills\douyin-upload\references\cli-contract.md |
| 476 | Get-Content skills\kuaishou-upload\references\cli-contract.md |
| 477 | ``` |
| 478 | |
| 479 | Expected: |
| 480 | |
| 481 | - 小红书 skill 目录完整 |
| 482 | - 抖音、快手 skill 契约都已经切到新参数模型 |
| 483 | |
| 484 | - [ ] **Step 5: 提交 skill 变更** |
| 485 | |
| 486 | ```powershell |
| 487 | git add skills/xiaohongshu-upload skills/douyin-upload skills/kuaishou-upload |
| 488 | git commit -m "feat: add xiaohongshu skill and align browser skill contracts" |
| 489 | ``` |
| 490 | |
| 491 | ## Task 5: 更新 examples 和 README / docs |
| 492 | |
| 493 | **Files:** |
| 494 | - Modify: `examples/get_xiaohongshu_cookie.py` |
| 495 | - Modify: `examples/upload_video_to_xiaohongshu.py` |
| 496 | - Modify: `README.md` |
| 497 | - Modify: `docs/CLI.md` |
| 498 | - Modify: `docs/install.md` |
| 499 | - Modify: `docs/update.md` |
| 500 | |
| 501 | - [ ] **Step 1: 改小红书 examples** |
| 502 | |
| 503 | 要求: |
| 504 | |
| 505 | - `examples/get_xiaohongshu_cookie.py` 明确指向 `sau xiaohongshu login --account <account_name>` 这一主线 |
| 506 | - `examples/upload_video_to_xiaohongshu.py` 说明当前主线优先走 CLI |
| 507 | - 如果继续保留 uploader 直连示例,注释里标明“调试入口 / 历史直连路径” |
| 508 | |
| 509 | - [ ] **Step 2: 更新 README 平台表和快速开始** |
| 510 | |
| 511 | README 至少要改这些位置: |
| 512 | |
| 513 | - 平台能力表里把小红书改成: |
| 514 | - `CLI ✅` |
| 515 | - `Skill ✅` |
| 516 | - 快速开始里的浏览器平台命令改成统一契约 |
| 517 | - 抖音、快手图文示例改成: |
| 518 | |
| 519 | ```bash |
| 520 | sau douyin upload-note --account <account_name> --images videos/1.png videos/2.png --title "图文标题" --note "图文正文" |
| 521 | sau kuaishou upload-note --account <account_name> --images videos/1.png videos/2.png --title "图文标题" --note "图文正文" |
| 522 | sau xiaohongshu upload-note --account <account_name> --images videos/1.png videos/2.png --title "图文标题" --note "图文正文" |
| 523 | ``` |
| 524 | |
| 525 | - [ ] **Step 3: 更新 `docs/CLI.md`** |
| 526 | |
| 527 | 要求: |
| 528 | |
| 529 | - 补 `xiaohongshu` 小节 |
| 530 | - 把三家浏览器平台整理成一致说明: |
| 531 | - 视频:`title + desc + tags` |
| 532 | - 图文:`title + note + tags` |
| 533 | - 登录二维码说明补小红书 |
| 534 | |
| 535 | - [ ] **Step 4: 更新 `docs/install.md` 和 `docs/update.md`** |
| 536 | |
| 537 | 要求: |
| 538 | |
| 539 | - 安装文档里补 `sau xiaohongshu --help` |
| 540 | - 更新文档里补小红书自检命令和 skill 路径 |
| 541 | - 文档统一写 `account_name` |
| 542 | |
| 543 | - [ ] **Step 5: 做文档与示例核对** |
| 544 | |
| 545 | Run: |
| 546 | |
| 547 | ```powershell |
| 548 | Get-Content README.md | Select-String -Pattern "xiaohongshu|upload-note|--note|--desc" -Context 1,2 |
| 549 | Get-Content docs\CLI.md | Select-String -Pattern "xiaohongshu|--note|--desc" -Context 1,2 |
| 550 | Get-Content docs\install.md | Select-String -Pattern "xiaohongshu" -Context 1,2 |
| 551 | Get-Content docs\update.md | Select-String -Pattern "xiaohongshu" -Context 1,2 |
| 552 | ``` |
| 553 | |
| 554 | Expected: |
| 555 | |
| 556 | - README、CLI、install、update 都出现小红书 CLI |
| 557 | - 图文正文写成 `--note` |
| 558 | - 视频描述写成 `--desc` |
| 559 | |
| 560 | - [ ] **Step 6: 跑最终最小验证** |
| 561 | |
| 562 | Run: |
| 563 | |
| 564 | ```powershell |
| 565 | py -3 -m unittest tests.test_sau_browser_cli tests.test_xiaohongshu_uploader -v |
| 566 | py -3 sau_cli.py xiaohongshu --help |
| 567 | py -3 sau_cli.py xiaohongshu upload-video --help |
| 568 | py -3 sau_cli.py xiaohongshu upload-note --help |
| 569 | ``` |
| 570 | |
| 571 | Expected: |
| 572 | |
| 573 | - 单测通过 |
| 574 | - 小红书 CLI 帮助存在 |
| 575 | - 视频命令显示 `--desc` |
| 576 | - 图文命令显示 `--note` |
| 577 | |
| 578 | - [ ] **Step 7: 提交收尾** |
| 579 | |
| 580 | ```powershell |
| 581 | git add examples/get_xiaohongshu_cookie.py examples/upload_video_to_xiaohongshu.py README.md docs/CLI.md docs/install.md docs/update.md |
| 582 | git commit -m "docs: align browser cli docs and examples" |
| 583 | ``` |
| 584 |