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

wjs-tweeting-from-articles

Use when the user wants to post a daily X/Twitter tweet inspired by one of their recently-published 微信公众号 articles. Picks the newest article that hasn't been tweeted yet, drafts 3 tweet candidates from it (different angles — quote / metaphor / one-liner), posts the chosen one via xurl, records to history. Triggers — "每天发一个 tweet", "从文章里发推", "今天的 tweet", "/wjs-tweeting-from-articles".

インストール方法を見る

含まれるファイル(10)

  • SKILL.md7.7 KB
  • com.jianshuo.wjs-tweeting-from-articles.plist.template1.0 KB
  • daily.sh6.0 KB
  • scripts/mirror-articles.py2.1 KB
  • scripts/pick-next-article.sh2.7 KB
  • scripts/pick-next-article.sh.bak.17796896741.7 KB
  • setup.sh2.4 KB
  • state/.gitignore8 B
  • state/queue-2026-05-24.tsv4.4 KB
  • uninstall.sh510 B

SKILL.md(原文)

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

wjs-tweeting-from-articles

每天一条 X tweet,灵感直接从最近发的公众号文章里抠。文章是源头,tweet 是更短的萃取。

Core Principle

文章已经过了一轮王建硕式的精炼,tweet 只是再短一格的版本。 不要重新构思——从 article.md 里直接抠最 quotable 的一句 / 一段,按 X 的节奏切。

一天最多一条,一篇文章只推一次。 状态文件 state/history.jsonl 记录哪些 article 已经推过;不重复。(例外:批量排期模式——一次把多篇排进队列、按每 N 小时一条自动发,见下文。)

真发,不暂存。 用户确认后立刻 xurl POST。失败原文 dump 给用户重试。

When This Skill Fires

  • 用户说「今天的 tweet」/「发一条 X」/「从文章里发推」
  • 用户跑 /wjs-tweeting-from-articles
  • 用户设了 /schedule daily /wjs-tweeting-from-articles 之后每天自动调

When NOT to use

  • 用户要发的内容和最近的公众号文章无关——直接 xurl POST /2/tweets 即可
  • 用户要发的是产品 / skill 推广——用 /publish-skill 或 /wjs-promoting-skills

Workflow

Step 1: 挑今天要推的文章

scripts/pick-next-article.sh

输出最新一篇还没推过的文章的 folder 路径(最近一周内,按日期倒序找第一个未推的)。已经全推完 → 退出 0、空输出,告诉用户「最近 7 天的文章都推过了,今天 rest day」。

如果用户想推特定那一篇:跳过此脚本,直接用 <folder>。

Step 2: 读文章 + 草拟 3 条 tweet 候选

读 <folder>/article.md,按下面三个角度各起草一条:

角度选材例子
A · 金句从文中挑一句最 quotable 的,可以加一句铺垫"笔头钝了,写不出锋——蘸点墨,在砚台上转两圈,重新有了尖。"
B · 比喻文章的核心比喻 + 一句把比喻落到读者头上"写 prompt 跟画画一样,是手感活儿。每天都得写点。"
C · 反差「不是 X,是 Y」式的认知翻转"不是变聪明,是手感来了。"

长度硬约束:tweet ≤ 280 字符(X 限制;中文每字算 2)——所以中文 tweet 实际 ≤ 140 字。留 buffer 到 120 字以内比较稳。

风格:保留王建硕语气——平实、家常比喻、不写营销腔。不要加 hashtags、不要加 @、不要加 emoji(除非原文有)。不要加 mp.weixin 链接(默认);如果用户问要不要带链接,提示可以 reply 里附。

Step 3: 让用户挑一条

用 AskUserQuestion 给出 A/B/C 三条候选 + 「四选其他」。用户选一条之后进入 Step 4。

Step 4: 真发 X

TWEET_TEXT='<picked text>'
JSON=$(jq -nc --arg text "$TWEET_TEXT" '{text:$text}')
resp=$(xurl -X POST -d "$JSON" /2/tweets)
# Don't use `jq -r '.data.id'` here — X API returns raw newlines in the echoed
# `text` field, which strict jq rejects with "control characters must be escaped".
# Grep the id directly instead.
TWEET_ID=$(printf '%s' "$resp" | grep -oE '"id":"[0-9]+"' | head -1 | sed -E 's/.*"([0-9]+)".*/\1/')
[[ -n "$TWEET_ID" ]] || { echo "POST failed: $resp"; exit 1; }
echo "https://x.com/jianshuo/status/$TWEET_ID"

成功 → 拿到 tweet_id + URL,告诉用户。

Step 5: 记录到 history

HIST="$HOME/.claude/skills/wjs-tweeting-from-articles/state/history.jsonl"
SLUG=$(basename "$FOLDER")
jq -nc --arg date "$(date +%F)" --arg slug "$SLUG" --arg angle "$ANGLE" \
       --arg tweet_id "$TWEET_ID" --arg text "$TWEET_TEXT" \
       '{date:$date,slug:$slug,angle:$angle,tweet_id:$tweet_id,text:$text,status:"posted"}' \
  >> "$HIST"

angle ∈ A / B / C / other。

Step 6: 收尾

告诉用户:

  • tweet URL
  • 哪篇文章(slug)
  • 哪个 angle
  • 今天的 history 行已经写入

Inputs

/wjs-tweeting-from-articles                       # 自动挑最近一篇没推过的
/wjs-tweeting-from-articles <article-folder>      # 显式指定
/wjs-tweeting-from-articles --dry-run             # 草稿不发

File Layout

~/.claude/skills/wjs-tweeting-from-articles/
├── SKILL.md
├── scripts/
│   ├── pick-next-article.sh        # 找最近一篇未推的 article folder
│   └── post-next-from-queue.sh     # 批量排期模式:每次发队列里下一条,自节流
└── state/
    ├── .gitignore              # 屏蔽 history.jsonl 不被推到 public repo
    ├── history.jsonl           # 每条 tweet 一行 JSON record
    ├── queue-<DATE>.tsv        # 批量模式:待发队列 idx/slug/text
    ├── queue-cursor            # 批量模式:下一条序号
    └── last-post-epoch         # 批量模式:上次发出的时间戳(节流用)

批量排期模式(多篇一次排,每 N 小时一条)

一次要发很多篇(典型来源:wjs-mining-articles 从一场长对谈挖出十几篇文章),用这个模式——一次连发会被 X 判刷屏,所以排成队列、按固定间隔自动发。

为什么不用 AskUserQuestion 逐篇选 angle:十几篇 × A/B/C 太多。每篇直接抠一条最 quotable 的(≤120 字、王建硕语气、无 hashtag/emoji/链接、带盘古之白),列全文给用户一次过目 + 定节奏,确认后排期。

机制(scripts/post-next-from-queue.sh + 每小时 cron,脚本自己节流):

# 1. 队列文件:state/queue-<DATE>.tsv,每行  idx<TAB>slug<TAB>text
# 2. cursor: state/queue-cursor(下一条序号);last-post-epoch(上次发的时间)
# 3. 立刻发第一条(FORCE 绕过节流,顺便验证 xurl 能发):
FORCE=1 bash scripts/post-next-from-queue.sh
# 4. 装 cron:每小时跑,脚本只在距上次 ≥ MIN_GAP(默认 4h)才真发:
( crontab -l 2>/dev/null | grep -v post-next-from-queue.sh; \
  echo "5 * * * * /bin/bash $HOME/.claude/skills/wjs-tweeting-from-articles/scripts/post-next-from-queue.sh >/dev/null 2>&1" ) | crontab -

脚本要点:单机锁(防并发)、发失败不推进 cursor(下小时重试)、发成功才写 history.jsonl 并推进、队列发完自动删掉自己的 cron 行。改间隔用 MIN_GAP(秒)。

Daily 自动化(可选)

要每天自动跑:

/schedule daily 09:00 /wjs-tweeting-from-articles

或写 cron。但默认不自动跑——每天人工确认 angle 选哪条更稳。

Anti-Patterns

不要原因
加 hashtags(#AI #prompt)王建硕的 X 风格不用 hashtag,加了变营销腔
同一篇文章推两条一篇一推;如果文章特别长 / 多核心,下次跑时把它从 history 删一行重推
tweet 里塞 mp.weixin 链接默认不带;想带就放 reply 里
把 3 条候选都发出去用户挑 1 条;不挑 = 跳过今天
凭空生造一条不在文章里的 tweet灵感必须从 article.md 抠;这条 skill 的价值就是「文章是源」
LLM 自己改原文风格做"提炼"王建硕原文已经够紧;直接抠 > 重写

Dependencies

  • xurl:xurl whoami 能返回用户名(auth OK)
  • jq:解析 xurl 返回的 JSON
  • 存在 ~/code/wechat-publish/articles/YYYY-MM-DD-*/article.md:源文章

レビュー

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

同じリポジトリのスキル

概要と使いどころ

王建硕的思维框架与表达方式。基于 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 のスキルをすべて見る

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