计划执行与检查节点
executing-plans
按既定实施计划完成工作,保持过程检查和反馈。
book-audio-digest【效率与协作】深度听书 — 融合微信读书素材(书籍信息、目录、热门划线)与个人知识库,生成飞书深度读书笔记 + 可通勤收听的高质量音频(MP3)。
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
给一本书名,产出两件交付物:飞书深度读书笔记(深度整合 + 个人感悟)和高质量音频(通勤/排队收听,默认 8–15 分钟)。素材来自微信读书(书籍信息、目录、热门划线),关联用户知识库里最相关的内容(少而精)。详细方法见 references/audio-script-guide.md 与 references/feishu-note-guide.md,动笔前先用 skill_read 读完。
PROJECT="$HOME/.ethan/output/book-audio-digest/$(date +%Y%m%d-%H%M%S)-<书名拼音>"
mkdir -p "$PROJECT/weread"
/store/search(scope=10)→ bookId;/book/info → 详情;/book/chapterinfo → 章节/book/bestbookmarks(chapterUid=0),若返回 {"synckey":0} 空响应,说明这本书拿不到划线数据(多见于付费书/冷门版本,如吴军《态度》的推广版 bookId=3001121336),换版本或换书,不要硬写/book/bestbookmarks 只回 top 20):逐 chapterUid 调用、按 markText 去重、按 totalCount 降序。限流纪律:请求间 sleep 1–2s;errcode:-2010 是限流不是 key 失效,指数退避重试;连续失败先拉 chapterUid=0 兜底;偶发 HTTP 499 直接跳过该章、下轮补拉$PROJECT/weread/,别只留在内存knowledge_search 做 2–3 个查询(书名/作者/核心主题),limit 2–3;只对最有价值的 1–2 条 knowledge_read 精读,让解读带个人上下文。搜不到就跳过,不硬凑。
a. 飞书深度读书笔记:按 references/feishu-note-guide.md 的结构,用 lark-cli docs +create --as user 创建(遵循 feishu-writer 铁律:黄金开局、去 AI 味、Callout 节制、正文 ≥ 2500 字)。注意:user token 过期时报 need_user_authorization,需要用户在场跑 lark-cli auth login(交互式);无人值守时段可先完成音频交付,把笔记 XML 存 $PROJECT/feishu-note.xml 待授权后补建。--content 用 @./file.xml 相对路径(绝对路径与 ~ 都会被 CLI 拒绝)。
b. 音频脚本:按 references/audio-script-guide.md 把笔记口语化改写(不是照念文档),写入 $PROJECT/manifest.json:
{"title": "《态度》深度听书", "voice": {"name": "zh-CN-YunxiNeural", "rate": "+0%", "volume": "+0%", "pitch": "+0Hz"}, "gapMs": 700, "targetDurationSec": 600,
"sections": [{"id": "opening", "narration": "..."}, {"id": "insight-1", "narration": "..."}]}
# 先校验(无网络)
python3 ~/.ethan/skills/book-audio-digest/scripts/audio_pipeline.py validate --manifest "$PROJECT/manifest.json"
# 后台合成(uv 临时注入 edge-tts;env -u 是本机代理未运行时的直连兜底)
nohup env -u HTTP_PROXY -u HTTPS_PROXY -u http_proxy -u https_proxy \
uv run --isolated --no-project --with 'edge-tts>=7,<8' python \
~/.ethan/skills/book-audio-digest/scripts/audio_pipeline.py run \
--manifest "$PROJECT/manifest.json" --output-dir "$PROJECT" \
> "$PROJECT/render.log" 2>&1 &
合成 1–3 分钟,轮询 render.log 看进度:脚本按节打 [audio-pipeline] 合成中/完成/缓存命中,
同时 run-status.json 在开工时就落 {"status": "running", "stage": ...}(不再是「文件不存在」),
所以「没反应」和「在跑」分得开。status 变 ok/error 即结束;出错时 stage 指出炸在哪一步。
脚本按 narration+voice 内容哈希缓存,重跑只重做变化章节。
run-status.json 的 status 是 ok,final.mp3 与 subtitles.srt 存在status: error)时脚本会删掉 final.mp3/subtitles.srt:产物和状态永远一致,
所以「文件在 = 本次成功」。别拿上一轮残留的音频兜底交付;按 stage/error 修问题后重跑deliver_file(path="<PROJECT>/final.mp3", title="《书名》深度听书笔记"),正文附飞书文档链接activate_tools: shell, file_write, knowledge_search, knowledge_read, deliver_file