本文へ移動
cccskills
無料GitHub で公開

wjs-publishing-books-to-x

Use when 王建硕 wants to publish his VoiceDrop books (voicedrop.cn/books) to X/Twitter as threads — 列出他写的书、挑没发过的、整本拆成推文串发出。

Triggers — "把书发到 X", "发书的 thread", "publish my book to X", "书架的书发推", "/wjs-publishing-books-to-x".

インストール方法を見る

含まれるファイル(6)

  • SKILL.md6.3 KB
  • com.jianshuo.wjs-publishing-books-to-x.plist.template1.0 KB
  • daily.sh6.8 KB
  • scripts/fetch-book.py2.1 KB
  • scripts/pick-next-book.sh1.3 KB
  • state/.gitignore22 B

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

wjs-publishing-books-to-x

把 VoiceDrop 书架上我写的书,一本一个 thread 发到 X。首条钩子 + 封面图,中间按书的脉络走,最后一条讲这本书是怎么用 VoiceDrop 写出来的。

Core Principle

一本书 = 一个 thread。 书已经是成品,thread 是它的预告片——从章节梗概和正文里抠最硬的内容,不重新构思、不写营销腔。

只发我的书。 书架是社区书架,上面有别的用户写的书,发出去就是替别人代言,绝对不行。

Workflow

Step 1: 列我的书,排除已发过的

mcp__voicedrop__list_books   # 公开书架,免登录
  • hidden 的书(book.json 里 hidden: true)服务端已滤掉,不用再处理。
  • 我的书判定:author == "王建硕" 或为空(早期的书没署名,都是我的)→ 是我的。其他署名(蜜蜡 / Dennis / sissi / …)→ 别人的书,不发。
  • 对照 state/history.jsonl 排除已发过的,列出剩余清单让用户挑。用户点名某本 → 直接用那本。

Step 2: 读书

mcp__voicedrop__read_book <slug>            # 目录 + 每章梗概 + 一句话简介
mcp__voicedrop__read_book_chapter <slug> intro   # 序章;再挑 1-2 个最有料的章读正文

梗概给骨架,正文给 quotable 的细节(数字、比喻、反直觉的断言)。

Step 3: 拆 thread(结构合同)

条内容
1钩子:书的核心断言或问题 + 书名,配封面图 https://voicedrop.cn/books/<slug>/cover.jpg
2 … N-2按书的脉络每条讲透一个点,从梗概/正文里抠。总共 6–10 条
N-1全书免费读:https://voicedrop.cn/books/<slug>/
N(必须)这本书怎么写的:真实过程——在 VoiceDrop 丢了一句什么中心思想(seed),书自己长出来、逐章补齐、不满意的地方一句话修书。落 voicedrop.cn

硬约束:每条加权 ≤280(中文每字算 2),buffer 到 ~120 汉字。王建硕语气:平实、家常比喻。无 hashtag、无 emoji、无 @。链接只出现在 N-1 和 N 两条。盘古之白。

Step 4: 过目

整串列给用户确认(每条标序号 + 字数)。用户说过 --yes 或明确「直接发」才跳过。

Step 5: 发(xurl 链式)

SLUG=<slug>
curl -s -o /tmp/cover.jpg "https://voicedrop.cn/books/$SLUG/cover.jpg"
MEDIA_ID=$(xurl media upload --category tweet_image --media-type image/jpeg /tmp/cover.jpg \
  | grep -oE '"media_id_string":"[0-9]+"' | grep -oE '[0-9]+')
# 注意:不带 --category tweet_image 会按视频处理,media id 无效

# 首条(带图)
resp=$(xurl -X POST -d "$(jq -nc --arg t "$T1" --arg m "$MEDIA_ID" \
  '{text:$t, media:{media_ids:[$m]}}')" /2/tweets)
# X 返回的 text 里有裸换行,jq 会拒;grep 抠 id
PREV=$(printf '%s' "$resp" | grep -oE '"id":"[0-9]+"' | head -1 | grep -oE '[0-9]+')
[[ -n "$PREV" ]] || { echo "POST failed: $resp"; exit 1; }

# 2…N 条依次 reply 上一条,条间 sleep 5
resp=$(xurl -X POST -d "$(jq -nc --arg t "$TN" --arg r "$PREV" \
  '{text:$t, reply:{in_reply_to_tweet_id:$r}}')" /2/tweets)

任何一条失败:停在原地,把已发到第几条 + 失败原文给用户,别跳条继续(断链)。首条 URL:https://x.com/jianshuo/status/<首条id>。

Step 6: 记录

jq -nc --arg date "$(date +%F)" --arg slug "$SLUG" --arg id "$FIRST_ID" --argjson n $N \
  '{date:$date,slug:$slug,thread_first_id:$id,tweets:$n,status:"posted"}' \
  >> ~/.claude/skills/wjs-publishing-books-to-x/state/history.jsonl

收尾告诉用户:thread URL、哪本书、几条、还剩几本没发。

多本连发

一次 session 默认发一本。用户要「把书都发了」→ 每本间隔 ≥4 小时排期(一口气连发多个 thread 会被 X 判刷屏),机制照抄 wjs-tweeting-from-articles 的批量排期模式(队列 + cron 自节流)。

Daily 自动化(已装)

launchd 每天 10:10 跑 daily.sh:自动挑最新一本没发过的(chapters=0 的老书跳过)→ claude -p 按上面结构合同起草 → 校验加权长度 → 链式发出 → 记 history。书发完了自动歇着。

DRY_RUN=1 bash ~/.claude/skills/wjs-publishing-books-to-x/daily.sh   # 起草不发
FORCE_SLUG=<slug> bash .../daily.sh                                  # 指定书
launchctl bootout gui/$(id -u)/com.jianshuo.wjs-publishing-books-to-x  # 停掉

日志:~/Library/Logs/wjs-publishing-books-to-x/。改时间:编辑 ~/Library/LaunchAgents/com.jianshuo.wjs-publishing-books-to-x.plist 后 bootout + bootstrap。

Anti-Patterns

不要原因
发署名是别人的书社区用户的书,不是我的
thread 写成目录(第一章讲X,第二章讲Y…)要抠内容,不是报菜名
每条都塞链接链接只在 N-1、N 两条
最后一条写成 VoiceDrop 广告词讲这本书的真实写作过程,产品是顺带的
jq -r '.data.id' 解析发推返回返回的 text 带裸换行,jq 报 control characters;用 grep
media upload 不带 --category默认按视频处理,图挂不上

File Layout

~/.claude/skills/wjs-publishing-books-to-x/
├── SKILL.md
├── daily.sh                  # launchd 每日入口(挑书→起草→校验→发→记录)
├── com.jianshuo.wjs-publishing-books-to-x.plist.template
├── scripts/
│   ├── pick-next-book.sh     # 下一本没发过的我的书(新→旧)
│   └── fetch-book.py         # 抓书素材(目录梗概+序章+前两章)→ 纯文本
└── state/
    ├── .gitignore            # history.jsonl / today-* 不进公开 repo
    ├── history.jsonl         # 每发一本记一行
    └── today-*.{txt,json,jpg}  # 当天工作文件

Dependencies

  • xurl:xurl whoami 能返回用户名
  • voicedrop MCP:list_books / read_book / read_book_chapter(公开内容,免登录)
  • jq

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

王建硕的思维框架与表达方式。基于 7 份深度调研(约 100 万词英文博客 + 约 109 万字中文博客, 2002–2022,全部一手)提炼出 7 个核心心智模型、10 条决策启发式和完整的双语表达 DNA。 用途:以王建硕的身份和声音写作、回应、思考——他平实、诚恳、好奇,爱用家常比喻和自造词, 在具体和抽象之间反复架梯子,从不写自己没亲身验证过的东西。 当用户提到「用王建硕的视角」「王建硕会怎么看」「王建硕模式」「像王建硕一样写」 「Jian Shuo Wang perspective」「切换到王建硕」时使用。 即使用户只是说「帮我用王建硕的角度想想」「如果是王建硕会怎么写这篇」也应触发。 一旦激活,本次对话后续所有回应都保持王建硕身份,直到用户明确说「退出」—— 不需要每轮重新点名。 不适用:用户要的是关于王建硕本人的客观介绍 / 事实查询(「王建硕是谁」「他哪年创业的」), 那种问题正常回答即可,不要进入角色扮演。

日本語の概要は準備中です。原文の説明を表示しています。

jianshuo/claude-skills1312026年8月21日 更新

Use when the user asks to audit what's wrong with a project, "make it right", "看看项目出了什么问题", "为什么用户的需求还没上线", "为什么没提交App Store", "为什么没新build", or wants a holistic state-of-the-project check covering unmerged branches, stalled PRs, failed GitHub Actions, stale builds, plan drift (TODOS.md / ROADMAP), unreleased commits, and log errors. Runs read-only investigation, presents a grouped checklist, fixes only after explicit user confirmation. Aware of the Cathier iOS app workflow (Xcode + fastlane + auto-merge @claude PRs from in-app feedback).

日本語の概要は準備中です。原文の説明を表示しています。

jianshuo/claude-skills1312026年8月21日 更新

Use when the user has a video + an SRT and wants the subtitles either burned into the pixels (libass, always-visible) or soft-muxed as a togglable track. Also handles the final composite step for the localization pipeline — burn subs, mix a dub track, and keep the original audio as a low-volume bed, all in ONE ffmpeg encode (no cascade). Verifies libass availability and auto-downloads a static evermeet ffmpeg build when Homebrew's stripped binary lacks it. Triggers — "烧字幕", "硬字幕", "burn subtitles", "burn-in subs", "embed subtitle", "soft mux SRT", "把字幕烧进视频", "做最终合成".

日本語の概要は準備中です。原文の説明を表示しています。

jianshuo/claude-skills1312026年8月21日 更新

Use when the user complains about spam on his X/Twitter posts — 同城面付 / 寻固炮 / 线下上门 / 免费破处 这类引流号在他推文下刷的 emoji 垃圾回复 — and wants them removed. Covers the last 7 days (X recent-search window). Triggers — "把这些spam删掉", "清理X垃圾回复", "推文下面好多引流号", "clean spam replies", "/wjs-cleaning-spam".

日本語の概要は準備中です。原文の説明を表示しています。

jianshuo/claude-skills1312026年8月21日 更新

Use when the user wants a 王建硕-style WeChat article (article.md) turned into a narrated short MP4 video — TTS voiceover via 火山引擎 Volcano TTS, HyperFrames CSS/GSAP animation per scene, subtle SFX, abstract watercolor background, full pipeline rendering to 1080×1920 portrait MP4 (30-90s). Triggers — "把这篇文章做成视频", "做一个解说视频", "讲解视频", "/wjs-converting-text-to-video".

日本語の概要は準備中です。原文の説明を表示しています。

jianshuo/claude-skills1312026年8月21日 更新

Use when migrating a WordPress site to a Hugo static site on GitHub Pages from a WXR export (.xml) plus the wp-content/uploads folder — preserving /archives/<id>/ URLs, localizing images, and deploying via GitHub Actions. Triggers — "把 WordPress 迁成 Hugo", "wordpress 转静态站", "migrate WordPress to Hugo", "WXR to Hugo", "publish WordPress to GitHub Pages", "/wjs-converting-wp-to-hugo".

日本語の概要は準備中です。原文の説明を表示しています。

jianshuo/claude-skills1312026年8月21日 更新

jianshuo のスキルをすべて見る

このスキルの問題を報告する