Claude To Im
op7418/Claude-to-IM-skill
Bridge THIS Claude Code or Codex session to Telegram, Discord, Feishu/Lark, QQ, or WeChat so the user can chat with Claude from their phone.
Agent skill
by dracohu2025-cloud in dracohu2025-cloud/draco-skills-collection
从飞书/Feishu 文档直接生成微信公众号草稿内容(支持预览、默认样式、dry-run 发布),基于现有 wechat-draft-publisher 流程的独立封装。
$ npx skills add dracohu2025-cloud/draco-skills-collection --skill feishu-doc-to-wechat-draft -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install dracohu2025-cloud/draco-skills-collection feishu-doc-to-wechat-draft --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/dracohu2025-cloud/draco-skills-collection.git skills-src && mkdir -p .claude/skills && cp -r skills-src/wechat-publishing-workflow/publisher .claude/skills/feishu-doc-to-wechat-draft && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "feishu-doc-to-wechat-draft" agent skill from https://github.com/dracohu2025-cloud/draco-skills-collection/tree/main/wechat-publishing-workflow/publisher into .claude/skills/feishu-doc-to-wechat-draft/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "feishu-doc-to-wechat-draft", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/dracohu2025-cloud/draco-skills-collection/tree/main/wechat-publishing-workflow/publisherType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add dracohu2025-cloud/draco-skills-collection --skill feishu-doc-to-wechat-draft -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install dracohu2025-cloud/draco-skills-collection feishu-doc-to-wechat-draft --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/dracohu2025-cloud/draco-skills-collection.git skills-src && mkdir -p .agents/skills && cp -r skills-src/wechat-publishing-workflow/publisher .agents/skills/feishu-doc-to-wechat-draft && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "feishu-doc-to-wechat-draft" agent skill from https://github.com/dracohu2025-cloud/draco-skills-collection/tree/main/wechat-publishing-workflow/publisher into .agents/skills/feishu-doc-to-wechat-draft/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "feishu-doc-to-wechat-draft", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add dracohu2025-cloud/draco-skills-collection --skill feishu-doc-to-wechat-draft -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install dracohu2025-cloud/draco-skills-collection feishu-doc-to-wechat-draft --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/dracohu2025-cloud/draco-skills-collection.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/wechat-publishing-workflow/publisher .cursor/skills/feishu-doc-to-wechat-draft && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "feishu-doc-to-wechat-draft" agent skill from https://github.com/dracohu2025-cloud/draco-skills-collection/tree/main/wechat-publishing-workflow/publisher into .cursor/skills/feishu-doc-to-wechat-draft/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "feishu-doc-to-wechat-draft", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/dracohu2025-cloud/draco-skills-collection.git --path wechat-publishing-workflow/publisher--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add dracohu2025-cloud/draco-skills-collection --skill feishu-doc-to-wechat-draft -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install dracohu2025-cloud/draco-skills-collection feishu-doc-to-wechat-draft --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/dracohu2025-cloud/draco-skills-collection.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/wechat-publishing-workflow/publisher .gemini/skills/feishu-doc-to-wechat-draft && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "feishu-doc-to-wechat-draft" agent skill from https://github.com/dracohu2025-cloud/draco-skills-collection/tree/main/wechat-publishing-workflow/publisher into .gemini/skills/feishu-doc-to-wechat-draft/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "feishu-doc-to-wechat-draft", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install dracohu2025-cloud/draco-skills-collection feishu-doc-to-wechat-draftInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add dracohu2025-cloud/draco-skills-collection --skill feishu-doc-to-wechat-draft -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/dracohu2025-cloud/draco-skills-collection.git skills-src && mkdir -p .github/skills && cp -r skills-src/wechat-publishing-workflow/publisher .github/skills/feishu-doc-to-wechat-draft && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "feishu-doc-to-wechat-draft" agent skill from https://github.com/dracohu2025-cloud/draco-skills-collection/tree/main/wechat-publishing-workflow/publisher into .github/skills/feishu-doc-to-wechat-draft/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "feishu-doc-to-wechat-draft", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add dracohu2025-cloud/draco-skills-collection --skill feishu-doc-to-wechat-draft -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install dracohu2025-cloud/draco-skills-collection feishu-doc-to-wechat-draft --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/dracohu2025-cloud/draco-skills-collection.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/wechat-publishing-workflow/publisher .opencode/skills/feishu-doc-to-wechat-draft && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "feishu-doc-to-wechat-draft" agent skill from https://github.com/dracohu2025-cloud/draco-skills-collection/tree/main/wechat-publishing-workflow/publisher into .opencode/skills/feishu-doc-to-wechat-draft/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "feishu-doc-to-wechat-draft", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
feishu-doc-to-wechat-draft从飞书/Feishu 文档直接生成微信公众号草稿内容(支持预览、默认样式、dry-run 发布),基于现有 wechat-draft-publisher 流程的独立封装。
Feishu Doc To Wechat Draft is an agent skill from dracohu2025-cloud/draco-skills-collection. 从飞书/Feishu 文档直接生成微信公众号草稿内容(支持预览、默认样式、dry-run 发布),基于现有 wechat-draft-publisher 流程的独立封装。
Its SKILL.md is about 5k tokens, which your agent loads only when the skill is triggered. The skill folder holds 35 other files, including scripts (for example `README.md`, `examples/default-publish-style.yaml` and `scripts/run.py`).
It sits in Productivity & Automation, covering Messaging and chat bots. It works with WeChat and Feishu (Lark). The licence is MIT.
2 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 26e8975. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Ships 12 files in scripts/ (Python, from the files we listed), which the agent can run.
Shell commands in SKILL.md call:
python3pipffmpegpytestFrom the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
g1mu6da08l.feishu.cnapi.weixin.qq.comFrom URLs in SKILL.md, links to its own repository left out.
Names these keys or tokens, usually read from environment variables:
ACCESS_TOKENWECHAT_APP_SECRETFrom names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Feishu Doc To Wechat Draft loads about 5k tokens when it runs. Until then it costs about 28 tokens; SKILL.md has 1,296 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.
The full file from dracohu2025-cloud/draco-skills-collection at commit 26e8975, republished under its MIT licence (© dracohu2025-cloud). 1,296 words, ~4,985 tokens.
.claude/skills/feishu-doc-to-wechat-draft/SKILL.md (or your agent's skills folder). This skill also uses 32 other files; get the full folder from GitHub.这是一个独立可运行的 skill 封装:把飞书文档内容抓取为 Markdown,按公众号样式渲染,并支持
render-preview-feishu-doc-default)publish-feishu-doc-default)说明:这是在保留旧
wechat-official-account-draft-publisher能力的前提下,新增的“从飞书文档入库”方向,不会覆盖旧版本。
feishu-doc-to-wechat-draft/
├── scripts/
│ ├── run.py # 本地 CLI 入口
│ └── wechat_draft_publisher/ # 独立迁移后的核心逻辑(load/render/pipeline/cli)
├── examples/
│ └── default-publish-style.yaml
├── tests/
│ └── test_integration_example_doc.py
├── requirements.txt
└── env.sample.txtcd ~/.hermes/skills/productivity/feishu-doc-to-wechat-draft
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt当前渲染链路除 PyYAML、markdown-it-py 外,还需要 Pygments。
原因:代码块现在采用服务端语法高亮,而不是只靠简单的纯文本换行包装。这样发布到微信公众号草稿箱后,代码块才能更接近 Doocs 的真实实现效果。
示例文档:
https://g1mu6da08l.feishu.cn/docx/H0TZdmw3GoW2JSxGBFacw2jdnV8?from=from_copylink
python3 scripts/run.py render-preview-feishu-doc-default \
--doc "https://g1mu6da08l.feishu.cn/docx/H0TZdmw3GoW2JSxGBFacw2jdnV8?from=from_copylink" \
--output /tmp/example-feishu-to-wechat-preview.htmlpython3 scripts/run.py publish-feishu-doc-default \
--doc "https://g1mu6da08l.feishu.cn/docx/H0TZdmw3GoW2JSxGBFacw2jdnV8?from=from_copylink" \
--thumb-media-id DRY_RUN_MEDIA_ID \
--dry-run返回 JSON 中会包含 payload,可直接用于确认是否满足微信要求(标题、摘要、封面 ID、正文 HTML)。
--thumb-media-id这次真实联调再次确认:
publish-feishu-doc-default --dry-run如果不传:
--thumb-media-id会直接报:
ValueError: thumb_media_id is required in dry-run mode所以 dry-run 的最小正确写法应固定为:
python3 scripts/run.py publish-feishu-doc-default \
--doc "<飞书文档URL>" \
--author "DracoVibeCoding" \
--thumb-media-id DRY_RUN_MEDIA_ID \
--dry-run也就是说:
thumb_media_id 占位即可用户明确要求公众号草稿内容默认全左对齐。当前 doocs/grace 发布链路应满足:
justify=falsetext-align: justifytext-align: center注意:此前当前文档并不是两端对齐;doocs 默认 justify=false。真正容易造成“看起来没左齐”的残留是标题默认样式里的 display: table; margin: ... auto 和图注/星号分割线的居中样式。
1.飞书/Lark 文档导出的 Markdown 可能把每个有序列表项都写成 1.;如果列表项中间夹了截图、引用块,Markdown 渲染会把它们拆成多个单项列表,推到微信公众号后台后序号看起来全是 1.。
当前链路已做两层修复:
normalize_lark_markdown() 会把跨图片/引用块的连续步骤重编号,例如 1,2,3...15。<ol start="N"> 的起始序号,并把它转成微信更稳的显式 <span class="md-ordered-index">N.</span>,避免依赖微信后台的 <ol> 默认样式。验收时固定检查:
md-ordered-index 不应全是 1.。lark-image:// 残留应为 0。这次真实联调踩到一个很隐蔽的坑:
~/.cache/wechat-draft-publisher/access_token.json)表面现象会非常迷惑:
draft/add 看起来返回成功media_iddraft/get 这个 media_id,会得到 invalid media_id稳妥做法:
appid 分开,例如:~/.cache/wechat-draft-publisher/access_token_<APPID>.jsondraft/batchget 是否真能列出草稿draft/get 是否能读取刚返回的 media_id这次继续联调时又踩到一个新的真实坑:
appid/appsecret 没错GET /cgi-bin/token 也能返回 access_tokenmaterial/add_material、draft/add 等接口时,微信仍可能返回:40001 invalid credential, access_token is invalid or not latest
could get access_token by getStableAccessToken这类报错在当前公众号环境里,不能只理解成“密钥错了”,更常见的根因是:
POST /cgi-bin/stable_tokenforce_refresh=False 仍会拿到一个不是 latest 的 token稳妥策略:
POST https://api.weixin.qq.com/cgi-bin/stable_token
Content-Type: application/json
{
"grant_type": "client_credential",
"appid": "...",
"secret": "...",
"force_refresh": true
}如果报错里明确出现:
invalid credentialnot latestcould get access_token by getStableAccessToken那就不要继续重试旧 token;直接切到:
stable_tokenforce_refresh=true对于“上传封面 → 发草稿”的一次性发布链路,宁可每次正式发布时都重新取一次最新 stable token,也不要过度相信本地缓存。
修完后立即做最小验证:
get_access_token() 是否成功upload_cover_image(...) 是否成功如果现有代码仍是:
GET /cgi-bin/token则建议改成:
POST /cgi-bin/stable_tokenforce_refresh=true这样能显著减少“本地看着拿到 token 了,但微信后续接口仍判你不是 latest”的问题。
publish-default 时,frontmatter 不是可选项这次继续联调又踩到一个很容易忽略的坑:
publish-default --input /path/to/article.md 直接发布本地 Markdown 时# 从飞书文档一键发布到微信公众号ValueError: title is required根因是当前 load_article(...) 的取值规则是:
title / author / digest / cover_image / source_url# 一级标题 自动回填 title也就是说,下面这种文件不能直接用于 publish-default:
# 文章标题
正文……稳妥做法是至少补上:
---
title: 文章标题
author: DracoVibeCoding
---然后再接正文 Markdown。
如果只是临时重发一篇本地稿,可以先在 /tmp 里生成一个带 frontmatter 的发布副本,再执行:
python3 scripts/run.py publish-default \
--input /tmp/article_publishable.md \
--thumb-media-id "已有封面素材ID"media_id这次排查也再次证明:
draft_media_id更稳的收尾动作应是:
draft_media_idaccess_token 调 draft/batchgetmedia_idtitleupdate_time也就是把“微信接口说成功”升级成“当前公众号后台可列出这条草稿”。
尤其当用户明确反馈“后台没看到新推送”时,优先排查:
thumb_media_idmedia_id,但当前号的 draft/batchget 根本列不出来需要正式发布到微信草稿箱时,请在环境变量中提供:
thumb_media_id 时,先本地做一个临时封面再发这次把新的飞书文档直推公众号草稿箱时,真实踩到的第一道坎仍然是:
ValueError: cover_image or thumb_media_id is required for publish也就是说:
publish-feishu-doc-default 真发草稿时--thumb-media-id--cover-image如果手头没有现成封面素材,最省事的办法是:
python3 scripts/run.py render-preview-feishu-doc-default \
--doc "<飞书文档URL>" \
--author "DracoVibeCoding" \
--output /tmp/feishu_wechat_preview.htmlffmpeg 直接生成一张临时封面 PNG这台机器上没有 PIL,但有 ffmpeg,下面这类命令可直接出图:
ffmpeg -y \
-f lavfi -i color=c='#FA5151':s=900x383:d=1 \
-vf "drawbox=x=28:y=28:w=844:h=327:color=white@0.10:t=fill,\
drawtext=fontfile=/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc:text='文章标题':fontcolor=white:fontsize=46:x=(w-text_w)/2:y=130,\
drawtext=fontfile=/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc:text='DracoVibeCoding':fontcolor=white@0.92:fontsize=24:x=(w-text_w)/2:y=220" \
-frames:v 1 /tmp/wechat_cover.pngpython3 scripts/run.py publish-feishu-doc-default \
--doc "<飞书文档URL>" \
--author "DracoVibeCoding" \
--cover-image /tmp/wechat_cover.png适用场景:
ffmpegdraft/get 回查这次成功发布后,又额外做了一步验证:
stable_token 重新取最新 tokencgi-bin/draft/gettitleauthorthumb_media_idmedia_id这样才能确认:
这次真实联调又踩到一个非常容易误判的问题:
draft_media_id更稳的做法是:每次说“已经发到草稿箱”之前,都立即用微信 draft/batchget 回查一次,确认当前公众号后台真的能列出目标标题。
推荐最小验证链路:
draft_media_idstable_tokenPOST https://api.weixin.qq.com/cgi-bin/draft/batchget?access_token=ACCESS_TOKEN
Content-Type: application/json
{
"offset": 0,
"count": 10,
"no_content": 1
}item[].content.news_item[] 里同时核对:titleauthorthumb_media_idmedia_id如果用户反馈“草稿箱里没看到新稿”,优先不要争论;直接重新做这一步回查。
publish-default 发布本地 Markdown 时,缺 frontmatter 会直接报 title is required这次还有一个非常具体、很容易再次遇到的坑:
publish-default --input article.md那么 load_article() 读不到:
titleauthordigestcover_image此时发布链路会在校验阶段直接报:
ValueError: title is required稳妥做法:
---
title: 从飞书文档一键发布到微信公众号
author: DracoVibeCoding
---python3 scripts/run.py publish-default \
--input /tmp/article_publishable.md \
--thumb-media-id YOUR_THUMB_MEDIA_IDthumb_media_iddraft/batchget 回查需要正式发布到微信草稿箱时,请在环境变量中提供:
如果用户反馈“公众号草稿箱里的 code block 看起来不对”,优先检查下面两件事,而不是先盲目改 CSS:
有没有对 <code> 内容做二次 HTML 转义
& / < / > 再整体替换一遍,就会把 " 变成 &quot;。有没有真正做服务端语法高亮
<span style="display:block">...,外壳看起来像代码块,但底层并不接近 Doocs。<code> 里取出已 escape 的内容Pygments)生成带 inline style 的 token HTML实践上,这类问题的根因通常是渲染链路错误,不是单纯“主题颜色不一致”。
<pre>这次真实发布后又踩到一个非常关键的兼容性坑:
<pre> 挪到内部 <code>,表面上仍然可能看起来“能滚”不要把外层改成:
<pre style="overflow: hidden; ...">
...
<code style="overflow-x: auto; white-space: pre; min-width: max-content; ...">这个结构在普通浏览器里可能还能工作,但在微信文章环境里不够稳。
应优先保持:
<pre style="overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; ...">
...
<code style="white-space: pre; min-width: max-content; ...">也就是:
<pre> 负责横向滚动<code> 只负责承载内容与内边距,不要再承担主要滚动职责如果你还要保留 Doocs-like 的 Mac 顶部样式(红黄绿 dots / 顶部 header 感):
pre 内部的独立块放在前面pre 改成 overflow: hiddencodeoverflow-x: auto; overflow-y: hidden;-webkit-overflow-scrolling: touch;code 保留:white-space: premin-width: max-contentword-break: normaloverflow-wrap: normal至少补一条针对公众号横滑的测试:
<pre> 上仍有 overflow-x: auto-webkit-overflow-scrolling: touchoverflow: hidden 这种会吞掉横滑的结构一句话记忆:在微信公众号里,code block 的横向滚动容器应优先是 <pre>,不是内部 <code>。视觉细节可以继续优化,但不要为 Mac 顶部样式牺牲 pre 的横滑能力。
需要正式发布到微信草稿箱时,请在环境变量中提供:
export WECHAT_APP_ID="<AppID>"
export WECHAT_APP_SECRET="<AppSecret>"再执行:
python3 scripts/run.py publish-feishu-doc-default \
--doc "https://g1mu6da08l.feishu.cn/docx/H0TZdmw3GoW2JSxGBFacw2jdnV8?from=from_copylink"source .venv/bin/activate
pytest -q tests/test_integration_example_doc.py成功后可复用示例输出,确认新 skill 封装链路可用。
这次真实联调又踩到一个很蠢、但非常容易再次出现的坑:
~/.hermes/skills/productivity/feishu-doc-to-wechat-draft/scripts/run.py/home/ubuntu/projects/draco-skills-collection/feishu-doc-to-wechat-draft/如果两边代码漂移,就会出现非常迷惑的现象:
运行时副本里仍是旧逻辑,例如:
display: -webkit-boxwhite-space: nowrapwhite-space: pre + min-width: max-content + pre 负责横向滚动<br/> 保留换行的修复而 standalone 项目里已经是修复后的版本。
不要只靠“记得同步文件”。更稳的是:
例如 scripts/run.py 应优先类似这样做:
ROOT = Path(__file__).resolve().parent
CANONICAL_ROOT = Path("/home/ubuntu/projects/draco-skills-collection/feishu-doc-to-wechat-draft/scripts")
IMPORT_ROOT = CANONICAL_ROOT if CANONICAL_ROOT.exists() else ROOT
sys.path.insert(0, str(IMPORT_ROOT))当用户反馈“这个 bug 明明修过,为什么又回来了”时,优先不要先怀疑微信;先查:
run.pyrenderer.py 路径是哪一个white-space: nowrapdisplay: -webkit-boxwhite-space: premin-width: max-contentoverflow-x: auto; overflow-y: hidden-webkit-overflow-scrolling: touch一句话记忆:如果 skill 既有运行时副本,又有 standalone canonical 项目,就不要让运行入口默认吃本地副本;否则回归只是时间问题。
这次真实回归排查踩到了一个很隐蔽但很致命的坑:
feishu-doc-to-wechat-draft:~/.hermes/skills/productivity/feishu-doc-to-wechat-draft//home/ubuntu/projects/draco-skills-collection/feishu-doc-to-wechat-draft/~/.hermes/skills/.../scripts/run.pyrenderer.py 仍然是旧版,于是把 white-space: nowrap / display: -webkit-box 这些老逻辑又带回去了,导致:不是微信随机抽风,也不是测试全白费。
是因为:
这类问题一旦出现,单看 HTML/CSS 症状会很像“神秘回归”,但真正根因是 执行入口与源码来源不一致。
如果这台机器上同时存在:
那么在重新发布公众号草稿箱前,必须先确认以下三件事:
例如本技能实际发布命令是:
python3 ~/.hermes/skills/productivity/feishu-doc-to-wechat-draft/scripts/run.py ...那就说明真正生效的是:
~/.hermes/skills/productivity/feishu-doc-to-wechat-draft/scripts/wechat_draft_publisher/*.py而不是 /home/ubuntu/projects/... 那份。
对于这次 code block 回归,至少应对拍:
diff -u \
~/.hermes/skills/productivity/feishu-doc-to-wechat-draft/scripts/wechat_draft_publisher/renderer.py \
/home/ubuntu/projects/draco-skills-collection/feishu-doc-to-wechat-draft/scripts/wechat_draft_publisher/renderer.py重点看是否还残留这些旧逻辑:
display: -webkit-boxwhite-space: nowrapmin-width: max-contentoverflow-x: auto; overflow-y: hidden-webkit-overflow-scrolling: touch不要只测 standalone 项目。
应直接用运行时 skill 重新生成 preview / payload,并检查是否满足:
white-space: nowrapdisplay: -webkit-boxwhite-space: premin-width: max-contentoverflow-x: auto; overflow-y: hidden-webkit-overflow-scrolling: touch如果用户反馈:
优先不要先怪微信。
先检查:
renderer.py 是否还是旧副本white-space: nowrap以后凡是这类“standalone + 运行时副本共存”的技能,公众号真实发布前建议固定做:
~/.hermes/skills/...draft/get 回查最终草稿里的 HTML 关键片段一句话记忆:在这台机器上,发布是否成功,不只取决于你“修过哪份代码”,更取决于“命令实际执行的是哪份代码”。
飞书文档里经常出现一种视觉上很像有序列表、但抓回来的 Markdown 实际还只是普通段落的结构,例如:
简单说,它解决三个核心问题:
**1. 图片自动处理**
说明正文……
**2. 格式完整保留**
说明正文……
**3. 排版风格统一**
说明正文……如果直接交给 Markdown 渲染器,或者只做“标题+正文硬拼成同一行”的粗暴重写,都会出问题。常见症状包括:
1 / 2 / 3 不再保留原本的段落层次更稳的做法,是在 normalize_lark_markdown(...) 阶段先做结构正规化:
**1. 标题**也就是优先转成:
1. **图片自动处理**
说明正文……
2. **格式完整保留**
说明正文……
3. **排版风格统一**
说明正文……而不是:
1. **图片自动处理** 说明正文……
2. **格式完整保留** 说明正文……
3. **排版风格统一** 说明正文……这样 MarkdownIt 会自然产出“一个 <li> 内含多个 <p>”的结构,后续 HTML 渲染才能既保留有序列表语义,又保留段落边界。
即使 normalize 已经产出了正确的多段 list item,渲染层仍然可能把它破坏掉。
这次真实踩到的坑是:
_rewrite_ordered_lists() 如果把整个 <li>...</li> 内容塞回一个 inline <span class="md-ordered-text">...</span><p> 会被再次 inline 化稳妥做法:
<section class="md-ordered-text">...</section>)item.strip() 后塞进一个 <span> 就是安全的至少补两类测试:
normalize_lark_markdown(...) 回归测试
**1. 标题** + 下一行正文 + **2. 标题** + 下一行正文1. **标题**\n\n 正文renderer 回归测试
这次实际补上的测试方向包括:
tests/test_lark_markdown_normalization.pytests/test_ordered_list_start_and_code_theme.py这次继续联调又发现一个很容易遗漏的结构坑:
飞书原始 Markdown 里像下面这种内容:
**2. 微信公众号凭证**
登录微信公众平台,在「开发」-「基本配置」里获取:
- AppID
- AppSecret(只显示一次,记得保存)
同时把你的服务器 IP 添加到「IP 白名单」,否则调用接口会报错。如果 normalize 只把 **2. 微信公众号凭证** 变成 ordered item 标题,却没有把:
一起缩进并吸附进同一个 list item,就会在公众号里出现:
更稳的正规化目标应是:
2. **微信公众号凭证**
登录微信公众平台,在「开发」-「基本配置」里获取:
- AppID
- AppSecret(只显示一次,记得保存)
同时把你的服务器 IP 添加到「IP 白名单」,否则调用接口会报错。strong-numbered block 的更稳处理规则在 _convert_strong_numbered_blocks(...) 里,建议采用下面的策略:
**2. 标题** 这类独占一行的强编号标题2. **标题****3. 标题** 这类强编号标题**方法一:...**)# / ## / <hr>)- ... 保留为 item 内部 bullet list这意味着:
2. 微信公众号凭证,后面的说明 + bullets + IP 白名单说明,都应继续属于同一个 ordered item3. 封面图的 media_id,遇到 **方法一:...** 时必须停止吸收,让方法标题和后续步骤重新成为 item 外的独立块除了“标题 + 下一行正文”的测试,还应覆盖:
编号项内部 bullets 不掉出 item
**2. 微信公众号凭证** + 段落 + bullet 列表 + 补充说明2. item 内编号项遇到独立 strong 小标题时及时断开
**3. 封面图的 media_id** 后面跟 **方法一:...**方法一 不会被吞进 3. item 的正文段里最终 HTML 中 2/3 两个编号项连续且不重复错号
2. 微信公众号凭证 与 3. 封面图的 media_id 都在同一 ordered list 体系内2. 项内部包含 bullets 与补充说明3. 项之后的方法标题和方法步骤是编号项外的独立块飞书抓回来的文本“看起来有结构”,不代表 Markdown 语义已经完整;而且就算 normalize 修对了,renderer 也可能把结构再次压扁。发布到公众号前,必须同时检查:语义结构有没有补对,渲染后处理有没有把它破坏掉。对于编号项,既要避免把后续内容吞过头,也要避免只收标题不收其内部 bullets / 补充说明。
<ul><li>这次真实发布又踩到一个 renderer 层面的坑:
- Hermes:- 模型:...- 宿主:...<ul> / <li>根因不是 normalize,而是 renderer 旧逻辑对无序列表做了这种事:
<ul ...>(...)</ul><li ...>(...)</li><ul> 时会在第一个 </li> / </ul> 处把层级拆坏稳妥做法:
ul.md-ul 做递归重写<p> 包整个 item这次实际修复采用的是:
xml.etree.ElementTree 解析当前 HTML 片段ul.md-ulmd-bullet-item 改成 block 级 <section>md-bullet-text 允许继续包住下一层 md-list md-list-unordered建议补的回归测试至少包括:
md-list md-list-unordered<ul class="md-ul"><li class="md-li">一句话记忆:无序列表一旦有嵌套,就必须按树处理;用正则拆 <ul>/<li> 迟早会炸。
© dracohu2025-cloud, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 32 other files (scripts) in wechat-publishing-workflow/publisher of dracohu2025-cloud/draco-skills-collection.
Open the folder on GitHubat commit 26e8975
Feishu Doc To Wechat Draft next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Feishu Doc To Wechat Draft this skilldracohu2025-cloud/draco-skills-collection | 227 | — | ~5k | Automated safety check: Pass | MIT | |
| Claude To Imop7418/Claude-to-IM-skill | 2.9k | — | ~3.4k | Automated safety check: Notes | MIT | |
| Content CollectorvigorX777/content-collector-skill | 240 | — | ~2k | Automated safety check: Pass | None | |
| Yichen Wechat Mp Batch Exportermcncarl/yichen-skills | 4.4k | — | ~1.5k | Automated safety check: Pass | Custom licence | |
| Web To Markdownrookie-ricardo/erduo-skills | 935 | — | ~894 | Automated safety check: Pass | MIT | |
| Use Avibeavibe-bot/avibe | 624 | — | ~2.5k | Automated safety check: Pass | MIT |
op7418/Claude-to-IM-skill
Bridge THIS Claude Code or Codex session to Telegram, Discord, Feishu/Lark, QQ, or WeChat so the user can chat with Claude from their phone.
vigorX777/content-collector-skill
Collect social media content (X/Twitter, WeChat, Jike, Reddit, etc.) into Feishu bitable.
mcncarl/yichen-skills
批量下载微信公众号文章正文、历史文章列表、原创文章筛选、历史计数口径、阅读量、点赞/转发等指标、评论和评论回复。Use when the user asks to batch fetch mp.weixin.qq.com articles, export WeChat public-account history, distinguish publish groups vs expanded…
rookie-ricardo/erduo-skills
Convert a web URL into cleaned Markdown with deterministic routing.
avibe-bot/avibe
Safely inspect and modify local Avibe configuration, routing, runtime settings, watches, scheduled tasks, Avibe Cloud remote access, and operational state.
iBigQiang/feedgrab
Batch content grabber — bulk fetch bookmarks, user tweets, search results, author notes, wiki pages, subreddit posts, and more from X/Twitter, Xiaohongshu, Reddit, WeChat, YouTube, Feishu, Zhihu.
dracohu2025-cloud/draco-skills-collection
A skill your agent uses when parsing a DingTalk daily news document and syncing title, date, Top 3, summary, conclusion, document link, and status into a DingTalk multidimensional table.
dracohu2025-cloud/draco-skills-collection
A skill your agent uses when running a Feishu/Lark Base-centered Seedance video production pipeline: inspect/backfill the Base row, create/reference assets, build Row-24-style Chinese Seedance…
dracohu2025-cloud/draco-skills-collection
Production pipeline for Motion Canvas — TypeScript-based programmatic vector animation with real-time preview.
dracohu2025-cloud/draco-skills-collection
A skill your agent uses when collecting public news candidates from Hacker News, GitHub Trending, Hugging Face papers, and other web sources for briefings and daily reports.
dracohu2025-cloud/draco-skills-collection
A skill your agent uses when mining Open Design visual systems and converting them into Open Slide React template kits or standalone 20-page template albums, with build, deployment, screenshot QA…
dracohu2025-cloud/draco-skills-collection
A skill your agent uses when generating a daily 24h AI / Agent / AIGC top-news briefing, publishing it as a DingTalk document, validating it, and optionally archiving it to a DingTalk…
Works with
Categories
从飞书/Feishu 文档直接生成微信公众号草稿内容(支持预览、默认样式、dry-run 发布),基于现有 wechat-draft-publisher 流程的独立封装。. Feishu Doc To Wechat Draft is an agent skill from dracohu2025-cloud/draco-skills-collection.
Feishu Doc To Wechat Draft fits situations like: tasks that involve Messaging and chat bots.
Run `npx skills add dracohu2025-cloud/draco-skills-collection --skill feishu-doc-to-wechat-draft -a claude-code`. Or copy the skill folder (wechat-publishing-workflow/publisher in dracohu2025-cloud/draco-skills-collection) into .claude/skills/feishu-doc-to-wechat-draft in your project. Claude Code loads it when a task matches its description.
Run `npx skills add dracohu2025-cloud/draco-skills-collection --skill feishu-doc-to-wechat-draft -a codex`. Or copy the skill folder (wechat-publishing-workflow/publisher in dracohu2025-cloud/draco-skills-collection) into .agents/skills/feishu-doc-to-wechat-draft in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add dracohu2025-cloud/draco-skills-collection --skill feishu-doc-to-wechat-draft -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/feishu-doc-to-wechat-draft, .gemini/skills/feishu-doc-to-wechat-draft, .github/skills/feishu-doc-to-wechat-draft and .opencode/skills/feishu-doc-to-wechat-draft in your project.
Going by SKILL.md and its folder, Feishu Doc To Wechat Draft needs Python for the scripts in its folder, the command-line tools its instructions call (python3, pip, ffmpeg and pytest) and credentials named ACCESS_TOKEN and WECHAT_APP_SECRET. Our summary lists: Python 3.
SKILL.md names 2 domains. In commands or code: g1mu6da08l.feishu.cn and api.weixin.qq.com; the agent is likely to contact these when it follows the instructions. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.
Feishu Doc To Wechat Draft is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.
About 5k tokens (SKILL.md is roughly 20k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Feishu Doc To Wechat Draft: Claude To Im (op7418/Claude-to-IM-skill, 2.9k stars), Content Collector (vigorX777/content-collector-skill, 240 stars), Yichen Wechat Mp Batch Exporter (mcncarl/yichen-skills, 4.4k stars) and Web To Markdown (rookie-ricardo/erduo-skills, 935 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
dracohu2025-cloud (a GitHub user) maintains it in dracohu2025-cloud/draco-skills-collection, which has 227 GitHub stars. The repository holds 27 skills in this directory. The repository was last updated on September 17, 2026.
Source: dracohu2025-cloud/draco-skills-collection on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.