Wechat autopublish
Skill TyrantLucifer/awesome-skills/skills/wechat-autopublish
Use when the user wants to publish a WeChat personal-subscription article from a topic, Feishu doc, notes, or existing draft. Turn research or source material into a ready-to-publish WeChat article and, when credentials allow, push it to the WeChat Official Account draft box with title/digest/cover/author prepared.From its SKILL.md
npx -y skills add TyrantLucifer/awesome-skills --skill wechat-autopublishAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- 14 days oldThe repository was created 14 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its file declares
Copied from the file, not written here
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
57.9 KB, ~12.8k tokens by cl100k_base, as published. Nobody here has run it
WeChat Autopublish
Overview
This skill turns source material into a polished WeChat Official Account article for a personal subscription account.
The core value is not generic writing advice. The skill is designed as a professional publishing pipeline for the owner's personal brand, with a strong bias toward:
- Feishu doc → WeChat article conversion
- topic → ready-to-publish WeChat article
- practical / technical content rather than empty thought-leadership copy
It should:
-
Accept one of these inputs:
- a topic
- a Feishu/Lark document
- local Markdown/notes
- reference links
- an existing draft
-
Produce one of these final outputs:
- WeChat draft box article (preferred)
- ready-to-paste publishing package (fallback)
- draft review package (when explicitly requested)
-
Default to a professional technical blog workflow instead of generic content generation.
-
Support explicit copy-transfer mode when the source article is already strong enough to be published as a mostly intact WeChat copy, especially when the user asks to preserve both the detailed content and the original images.
The skill should keep the workflow stable, reusable, and focused on publishing, not brainstorming.
When to Use
Use this skill when:
- the user wants to publish or convert a Feishu doc into a WeChat article
- the user gives a topic and wants a publish-ready WeChat article
- the user asks to push content into the WeChat draft box
- the user says things like "公众号", "推文", "公号稿", "草稿箱", "发布文章"
- the user wants a repeatable publishing workflow rather than one-off writing help
- the user provides an internal document, design note, or technical summary and wants it transformed into external-facing WeChat content
- the user wants the agent to handle the full publishing job rather than just write a draft
The three most important trigger patterns are:
- Feishu doc publishing mode: publish this Feishu doc as a WeChat article
- Topic content-building mode: take this topic and build a publish-ready WeChat article for me
- Copy-transfer mode: the source article is already detailed and should be published as a near-complete copy with images retained, not condensed into a fresh rewrite
Do not use this skill for:
- general article writing without WeChat publishing intent
- enterprise service-account publishing workflows
- short social posts unrelated to the WeChat Official Account
- lightweight brainstorming that clearly does not need a publishing pipeline
Default Profile
This is a personal-brand publishing skill, not a generic content generator.
Personal voice baseline
The default writing style should follow the owner's blog voice at https://tyrantlucifer.com/ .
Based on representative posts such as 笔记工作流的最佳实践 and Fluss - 面向分析的实时流存储初探, the blog's recurring style has these traits:
- writes in first person, but keeps the focus on the topic rather than self-dramatization
- opens by stating the real background, problem, or motivation in a few sentences
- prefers a clean problem-oriented or evaluation-oriented structure instead of fluffy narrative
- often uses a flow like: motivation/context → concept/objective → architecture or selection criteria → concrete examples or setup notes → verification/takeaways
- uses comparison, step reasoning, and decision explanation when introducing a new tool or workflow
- keeps paragraphs short and readable, usually 2-4 sentences
- frequently uses section titles that directly describe the current stage or question
- uses concrete nouns, real components, and real scenarios instead of abstract inspirational language
- preserves important English names exactly when discussing open-source projects, systems, or technical terms
- uses first-person observation to add practical judgment, not to perform emotion
- prefers clear lists, structured evaluation points, architecture breakdowns, and workflow summaries
- values clarity, practicality, reproducibility, and reader utility over rhetorical flourish
- tends to explain choices and trade-offs rather than just stack buzzwords
Style fingerprint: Write like the blog owner: a senior big-data / infrastructure engineer who explains things in a calm, practical, structured, example-aware, and opinionated way. The article should feel like a real practitioner's technical blog post, not AI promotional copy.
Source posts sampled for this profile:
笔记工作流的最佳实践Fluss - 面向分析的实时流存储初探SeaTunnel连接器V1到V2的架构演进与探究
User-operating preferences for this skill (hard-won corrections from live use):
- One canonical copy of publishing scripts lives inside this skill, under
scripts/wechat_publisher/. Do not propose wrapper shells that merely call an external checkout. - When the user asks for “搬运” / copy / migration mode, preserve the source document's structure and detail first. Do not aggressively rewrite into a short editorial unless the user explicitly asks for that mode.
- When migrating Feishu docs to WeChat, treat callout blocks and whiteboard figures as first-class content, not decorative noise. They must be converted or migrated explicitly.
- When figures exist, migrate unique images intentionally. Avoid naive duplication that inflates figure count and produces messy layout.
- Publishing output should be actionable and concrete: title, digest, author, cover, migrated images, HTML quality, fallback path, and next action. Avoid long theoretical explanations when the user wants execution.
- Quality gate comes after migration completeness, not before. First make the copy faithful; then polish for publishing readability.
- The user expects active review of the HTML conversion path whenever rich Feishu content is involved, especially callouts, figures, tables, and appendix image placement.
Publishing defaults
Unless the user overrides:
- account:
main - preferred publishing mode: draft box
- article scale: roughly 2500-5000 words for long-form
- output language: Chinese
- structure: problem-oriented or workflow-oriented
- style: professional technical blog, not marketing copy
- translation rule: if source material is in English, publish in Chinese with original terms preserved where useful
Execution backend
This skill manages its own publishing scripts internally:
scripts/wechat_publisher/
This is the correct integration shape for this user. Do not vendor the entire upstream project tree, do not create a wrapper shell that merely calls an external checkout, and do not leave publishing scripts split across two unrelated locations.
The required integration pattern is:
- extract only the necessary publishing scripts into
scripts/wechat_publisher/ - keep required publishing assets together with those scripts when the scripts depend on them
- keep
wechat-publisher.yamlwith the extracted scripts, not at unrelated outer paths - expose thin shell entrypoints under
scripts/wp-*.shthat call the internal scripts directly
If the underlying publishing code expects its config at parent.parent / wechat-publisher.yaml, adjust the internal copy so the config lookup matches the skill's actual layout instead of assuming the old upstream directory shape.
Known converter pitfalls
lark-cli table output missing pipe delimiters
When fetching Feishu docs via lark-cli docs +fetch, exported Markdown tables may be missing leading/trailing |. Normalize them before gzh-design rendering so table structure is unambiguous and source fidelity can be checked.
Fix: After fetching, normalize table rows by adding | at start and end:
lines = content.split('\n')
new_lines = []
for line in lines:
if '|' in line and not line.strip().startswith('```'):
if line.count('|') >= 2:
if not line.strip().startswith('|'):
line = '|' + line
if not line.strip().endswith('|'):
line = line + '|'
new_lines.append(line)
### Known converter pitfalls
#### Use `gzh-design` as the canonical Markdown → HTML renderer
`gzh-design` is the **default and mandatory renderer** for new publishing runs. The internal `html_converter.py` is retained only as a legacy emergency fallback; do not choose it merely because it is deterministic or already wired into `publish.py`.
Canonical path:
1. normalize Feishu/Word/PDF/notes into clean WeChat-ready Markdown;
2. load `gzh-design` and read its `theme-index.md`, the selected theme library, and `common-components.md`;
3. render a pure `<section>…</section>` body fragment with inline styles and `<span leaf="">` text wrappers;
4. run `gzh-design/scripts/validate_gzh_html.py` until **ERROR=0 and WARNING=0**;
5. run `scripts/wp-html.sh <rendered.html>` for the copy-ready preview;
6. publish the rendered HTML with `scripts/wp-publish.sh <rendered.html> --title ...`, which uploads local/external HTML images to WeChat CDN before draft creation.
Theme behavior:
- if the user specifies a gzh-design theme, use it directly;
- otherwise recommend from the article type; in full-auto publishing, choose automatically and report the reason;
- do not mix components from different gzh-design themes;
- preserve the normalized Markdown as the content source of truth and the gzh-design HTML as the publishing artifact.
Legacy fallback is allowed only when `gzh-design` is unavailable or its component assets are damaged. The fallback must be explicit in the final report and uses `wp-html-legacy-md.sh` / `wp-publish-legacy-md.sh`.
**Mandatory HTML quality gate before publishing:**
1. gzh-design validator reports 0 ERROR and 0 WARNING;
2. no literal `**` remains in HTML;
3. no `src=""` appears;
4. no raw `<grid>`, `<callout>`, `<whiteboard>`, Mermaid code, or `flowchart`/`mindmap` remains;
5. expected links retain `href="https://..."`;
6. every expected figure has a non-empty local/CDN image source;
7. after draft creation, `draft/get` confirms content and figures survived WeChat sanitization.
### Table rows MUST start and end with `|`
`html_converter.py` detects table rows by checking `stripped.startswith("|")`. Markdown tables like:
| 维度 | 传统数据湖 | 多模态数据湖 |
|---|---|---|
| 数据类型 | 结构化/半结构化 | 任意模态 |
will NOT be recognized as tables. They must be:
| 维度 | 传统数据湖 | 多模态数据湖 |
|---|---|---|
| 数据类型 | 结构化/半结构化 | 任意模态 |
Always normalize table rows to start/end with `|` before passing to the HTML converter.
### Table cells: `flush_table()` must call `process_inline()` on cell contents
The original `flush_table()` in `html_converter.py` inserted raw cell text into `<th>`/`<td>` tags without processing inline Markdown (`**bold**`, links, etc.). Fix: call `process_inline(c)` on each cell value.
### Table headers: strip `**bold**` markers to avoid yellow highlight
`process_inline()` converts `**text**` to `<strong>` with yellow highlight background (`#fff18a`). In table headers (`<th>` with dark blue background), this creates unreadable text. Fix: strip `**` markers from header cells before calling `process_inline()`:
```python
def clean_th_text(t):
t = re.sub(r'\*\*([^*]+)\*\*', r'\1', t)
return process_inline(t)
Table rows must start AND end with | (critical)
html_converter.py detects table rows via stripped.startswith("|"). Rows without leading | are treated as plain paragraphs and break the entire table.
See "Markdown tables MUST start and end with |" section above for the fix script, or references/table-format-fix.md for a standalone fixer script.
Table cell inline markdown needs explicit process_inline() call
Fixed in 2026-07-01: flush_table() now calls process_inline() on both <th> and <td> cell contents. Previously, **bold** in table cells rendered as literal asterisks.
Table header **bold** causes yellow highlight on dark background
Fixed in 2026-07-01: Table headers now strip **bold** markers before processing, since the strong style's yellow #fff18a background clashes with the dark blue #0b1530 header background.
Feishu <grid> / <column> blocks need manual preprocessing
The strong style in html_converter.py includes background: #fff18a (yellow highlight). When table header cells contain **bold** markers, the yellow highlight appears on the dark blue #0b1530 th background, making text unreadable.
Fix: In flush_table(), strip **bold** markers from table header (th) cells before passing to process_inline(), since <th> already has font-weight: 600:
def clean_th_text(t):
t = re.sub(r'\*\*([^*]+)\*\*', r'\1', t)
return process_inline(t)
Apply to the i == 0 (header row) branch only. Body <td> cells should still use process_inline() to preserve inline markdown formatting.
Table cell markdown not rendered
The original flush_table() passed cell content directly into <td> without calling process_inline(), so **bold** markers appeared as raw text. The fix is to call process_inline(c) on all non-header cell content.
Cover image: picsum.photos seeds produce irrelevant images
Using picsum.photos/seed/<word>/900/383 does NOT guarantee the seed word relates to the image content. Seeds like datalake, technology, database all produce random photos (vegetables, landscapes, etc.).
Better approach:
- Use a known-good tech image URL (e.g., from Pixabay/Unsplash with direct link)
- If needed, resize with
ffmpeg -i input.jpg -vf "scale=900:383" output.jpg - Or generate with
image_generatetool when available
Feishu <grid>/<column>` blocks need manual preprocessing
normalize_for_wechat.py handles <callout>, <whiteboard>, <title>, <p> blocks — but not <grid> / <column> layout blocks that Feishu exports for multi-column content (e.g. pros/cons comparison).
Preprocessing pattern:
import re
grid_re = re.compile(r'<grid>(.*?)</grid>', re.S | re.I)
col_re = re.compile(r'<column[^>]*>(.*?)</column>', re.S | re.I)
def replace_grid(m):
cols = col_re.findall(m.group(1))
return "\n\n---\n\n".join(c.strip() for c in cols) + "\n" if cols else m.group(1)
text = grid_re.sub(replace_grid, text)
Run this before normalize_for_wechat.py.
Markdown tables MUST start and end with |
html_converter.py detects table rows via stripped.startswith("|"). When converting Feishu docs or writing markdown manually, every table row (including the header and separator) must start and end with |:
|列A|列B|列C|
|---|---|---|
|值1|值2|值3|
Without leading |, rows render as plain paragraphs. Use a fixer script:
# fix_table_pipes.py — add missing leading/trailing | to table rows
import re
lines = content.split('\n')
for i, line in enumerate(lines):
if '|' in line and not line.strip().startswith('```'):
if line.count('|') >= 2:
if not line.strip().startswith('|'):
lines[i] = '|' + line
if not line.strip().endswith('|'):
lines[i] = lines[i] + '|'
flush_table() must call process_inline() on cell contents
The original html_converter.py passed raw cell text into <td>/<th> tags without inline markdown processing. **bold** in table cells rendered as literal asterisks.
Fix applied (2026-07-01): flush_table() now calls process_inline(c) for both <th> and <td> cells.
Table headers: strip **bold** to avoid yellow highlight conflict
When process_inline() processes **text**, it applies the strong style which includes background: #fff18a (yellow highlight). In table headers (<th> with background: #0b1530; color: #ffffff), this yellow highlight makes text unreadable.
Fix applied (2026-07-01): Table header cells use clean_th_text() that strips **bold** markers before process_inline(), since <th> is already bold by default.
def flush_table():
...
if i == 0: # header row
def clean_th_text(t):
t = re.sub(r'\*\*([^*]+)\*\*', r'\1', t)
return process_inline(t)
cells_html = "".join(f'<th ...>{clean_th_text(c)}</th>' for c in cells)
else: # body rows
cells_html = "".join(f'<td ...>{process_inline(c)}</td>' for c in cells)
Cover image generation: use the skill's built-in pipeline (FIRST CHOICE)
⚠️ CRITICAL ORDER: Always try generate_image.py FIRST.
Do NOT try image_generate tool (FAL), picsum, pixabay, or any external image source before checking the skill's own generate_image.py script. The script reads API credentials directly from wechat-publisher.yaml and works even when image_generate tool reports missing keys.
Correct cover image priority:
- User-supplied cover image
generate_image.pyscript (reads config fromwechat-publisher.yaml)- If that configured provider/model is unavailable, use the active
image_generatetool when available - Article inline images (reuse the most representative one)
- Branded placeholder template
- Last resort: stock photo (warn user it's temporary)
After generation, always inspect the image visually, then inspect the actual file dimensions before resizing or cropping. Do not trust a tool's reported nominal size: backends may return a different aspect ratio. For WeChat covers, verify the final 900×383 artifact again after conversion.
Do NOT jump to picsum/pixabay/random images just because image_generate tool reports FAL_KEY missing — the skill has its own image generation backend configured in wechat-publisher.yaml.
Sensitive info masking — do NOT assume values are truncated
Hermes tools (read_file, terminal output, session_search) automatically mask sensitive values like API keys. A displayed value like sk-701...2b99 is NOT truncated — it is the full key being masked at the display layer for security.
Do NOT:
- Assume the key in the config file is broken or incomplete
- Ask the user to "provide the full key" when it's already there
- Waste rounds trying to "fix" a value that is already correct
Do:
- Just call the script that reads the config directly (
generate_image.py,wp-token.sh, etc.) — they read the actual file, not the masked display - If the script fails with 401, then investigate the key — but trust the file, not the display
Do not infer that a credential file is incomplete from masked tool output. Let the local script read the file directly, then diagnose only from the real API response.
The skill has a complete image generation pipeline:
generate_image.py— unified entry point, readswechat-publisher.yamlopenai_image_gen.py— OpenAI-compatible API backend- Config keys in
wechat-publisher.yaml:image_generation.generator(set to"openai")image_generation.openai.api_keyimage_generation.openai.base_urlimage_generation.openai.image_model
Usage:
cd scripts/wechat_publisher
python3 generate_image.py --generator openai \
-p "描述封面图内容的详细prompt" \
--image /tmp/cover.jpg \
--size "1792x1024" \
--quality "high"
Pitfall: If the API key in wechat-publisher.yaml is truncated or invalid, the script will return 401. Always verify the key is complete before attempting generation. If generation fails, report the error clearly and ask the user to provide the correct key — do NOT silently fall back to unrelated stock images.
--html mode cover behavior
publish.py --html <gzh-fragment> always requires --title. --cover is optional only when the HTML contains a resolvable first image, which the publisher can reuse as cover; otherwise provide a real cover explicitly. Never download a random Picsum image silently.
⚠️ Lorem Picsum random images are often irrelevant — seeds like database, technology return random photos (vegetables, landscapes, architecture) that have nothing to do with the topic. Random Picsum is acceptable only as a "won't crash" fallback. When the user sees an irrelevant cover, they will complain.
Better fallback strategies (in priority order):
- Ask the user to supply a cover image
- If the article has inline images, reuse the most representative one
- Generate a cover via the configured image backend (OpenAI / Gemini)
- Use a solid-color SVG or a simple branded template image
- Last resort: Picsum random — but warn the user it's a placeholder
html_converter.py table cells must call process_inline() for markdown rendering
The flush_table() function in html_converter.py originally inserted table cell content raw — without calling process_inline(). This meant **bold**, [links](url), and other inline markdown inside table cells rendered as literal text.
Fix applied (2026-07): Changed flush_table() to call process_inline() on every cell:
# Before (broken):
cells_html = "".join(f'<th style="...">{c}</th>' for c in cells)
# After (fixed):
cells_html = "".join(f'<th style="...">{process_inline(c)}</th>' for c in cells)
Same for <td> cells. The patch is applied to the skill's copy of html_converter.py. If you replace or update the file, verify this fix is present.
Validation: after conversion, check the HTML output — if **text** appears as literal asterisks inside <td> or <th> tags, the fix was lost.
Mermaid / flowchart code blocks must be rendered to images before gzh-design
Before publishing any article containing Mermaid blocks:
- search the normalized Markdown for fenced
mermaidblocks orflowchart/mindmapsyntax; - render each diagram to a PNG;
- replace the fenced block with
; - render the resulting Markdown with gzh-design and verify no Mermaid source remains in the HTML;
- publish the clean HTML through
wp-publish.sh; it uploads the local image source to WeChat CDN.
If the server lacks Chinese fonts, download/use a local CJK font and reference it via @font-face when rendering diagrams with Playwright; otherwise Chinese labels become square glyphs in the generated image.
html_converter.py requires tables to start and end with |
The table detection in html_converter.py uses this check:
if "|" in stripped and stripped.startswith("|"):
Markdown tables that lack leading/trailing | (e.g. **维度** | **传统** | **多模态** instead of |**维度** | **传统** | **多模态**|) will not be detected as tables — they pass through as plain <p> text.
This commonly happens when:
- Feishu doc exports produce bare pipe-separated rows without
|boundaries - Content is hand-written with
|as separator but no leading|
Fix: normalize table rows before normalize_for_wechat.py:
import re
def fix_table_pipes(text: str) -> str:
"""Ensure markdown table rows start and end with |."""
lines = text.split('\n')
result = []
for line in lines:
if '|' in line and not line.strip().startswith('```'):
if line.count('|') >= 2:
if not line.strip().startswith('|'):
line = '|' + line
if not line.strip().endswith('|'):
line = line + '|'
result.append(line)
return '\n'.join(result)
This fix is available as scripts/fix_table_pipes.py.
Validation: after conversion, grep the HTML for <table — if absent and the source had tables, the pipe fix was missed.
Use the skill's wrapper scripts for operations:
scripts/wp-list-accounts.shscripts/wp-token.shscripts/wp-html.shscripts/wp-ai-score.shscripts/wp-publish.shscripts/wp-bootstrap.shscripts/wp-run.sh
Cover image generation
When image_generate tool is unavailable (no FAL_KEY), use the skill's built-in generate_image.py script:
cd ~/.hermes/skills/social-media/wechat-autopublish/scripts/wechat_publisher
python3 generate_image.py --generator openai \
-p "A modern data lake architecture diagram..." \
--image /tmp/cover.jpg \
--size "1792x1024" --quality "high"
The script reads API config from wechat-publisher.yaml (image_generation.openai.*).
If the API key is truncated or invalid, the script will fail with 401 — check the key before retrying.
When image generation is unavailable (no API key, API errors), fall back to a stock image from pixabay/picsum. Always inform the user about the fallback.
Image-generation integration notes are in references/wechat-image-generation.md.
Rendering, integration shape, and next-upgrade research are in references/wechat-rendering-and-integration-notes.md.
WeChat justified text stretches Chinese spacing
Do not use text-align: justify for normal WeChat article paragraphs. In WeChat preview/WebView, Chinese-English mixed lines can be expanded aggressively, creating large gaps between Chinese characters and English terms. Use:
text-align: left;
letter-spacing: 0.15px;
word-spacing: 0;
This applies to the default converter styles and the refined-blue theme. Verify the actual draft HTML returned by draft/get, not only the pre-upload HTML.
WeChat sanitizes multi-line blockquotes
Do not render Feishu callouts as one <blockquote> joined by <br>. WeChat's draft sanitizer can keep only the first line, silently deleting the callout body. Render each callout as a styled <section> containing one <p> per source line. After draft creation/update, call draft/get and verify that every callout still contains its body text.
List rendering strategy
WeChat Official Account HTML does not reliably support nested list indentation via ul/ol/li + CSS.
Therefore:
- use a standard Markdown renderer for correctness
- then convert nested lists into WeChat-safe list components using
p+span - preserve indentation through explicit left padding
- preserve numbering/bullets through explicit styled spans
This avoids duplicated numbering and unstable nested-list rendering.
Preconditions
Before attempting draft-box publishing, confirm:
- the WeChat account is a personal subscription account
AppIDis availableAppSecretis available- the server/public IP is added to the WeChat IP whitelist
- the publishing toolchain is configured inside
scripts/wechat_publisher/wechat-publisher.yaml - image generation configuration is understood:
image_generation.openai.*is used for OpenAI-compatible image backends,image_generation.gemini_proxy.*for Gemini-style backends, andimage_generation.generatorselects the active path - if a generated cover is required, the active image backend is configured before publishing
If any precondition fails, fall back to the publishing package workflow rather than stopping completely.
Operational lesson from actual use:
- when the user asks how to configure YAML, answer in execution-project terms first
- clarify that secrets / provider keys / account credentials belong in the execution project config
- clarify whether image generation is currently wired into this skill's publishing flow before giving configuration advice
If any precondition fails, fall back to the publishing package workflow rather than stopping completely.
Core Principle
This skill should always separate content production from account-specific publishing mechanics.
A stronger publishing principle should also be enforced:
- all inputs must first be normalized into WeChat-ready Markdown
- Markdown → HTML is the single main rendering path
- source-specific preprocessing (Feishu docs, rich exports, mixed tags) belongs in the Markdown normalization layer, not inside the HTML renderer
- preserve source value where appropriate; do not blindly compress detailed source documents when the user wants publication-grade content
This keeps the publishing pipeline stable and makes the rendering core reusable across different input types.
Two primary operating modes should be supported explicitly:
-
Feishu doc publishing mode
- Use when the user gives a Feishu doc URL/token and wants it published as a WeChat article.
- The Feishu doc is treated as the main source of truth.
- The skill should extract, restructure, de-internalize, and convert the doc into publishable WeChat content.
- This mode should be used when the user wants a publishing-grade rewrite or restructure.
-
Copy-transfer mode
- Use when the user wants the source article transferred to WeChat as faithfully as possible.
- Prefer preserving original structure, detail density, figures, and appendices over aggressive rewriting.
- This mode is especially appropriate when the source article is already mature and the user says things like “搬运一下”“图也得搬一下”“不能太精简”.
- The goal is publishable fidelity, not fresh content reconstruction.
-
Topic content-building mode
- Use when the user gives only a topic, outline, or rough idea.
- The skill should build the article end-to-end: define the job, research, outline, draft, humanize, format, and package for publishing.
Support files for execution:
references/gzh-design-integration.md— canonical renderer contract and artifact boundaryreferences/wechat-publisher-execution.mdreferences/feishu-wechat-conversion.mdreferences/html-publishing-quality-gate.md— renderer failure signatures and the pre/post-publish verification gatetemplates/wechat-publisher.yaml.exampletemplates/feishu-doc-intake.mdtemplates/topic-intake.mdtemplates/final-package.md
Recommended abstraction:
- Source intake
- Research / evidence gathering
- Structuring
- Drafting
- Humanization / anti-AI flattening
- WeChat formatting
- Publishing execution via wechat-publisher
- Output packaging / fallback packaging
This skill should treat wechat-publisher as the execution backend, not duplicate its publishing logic.
Copy-transfer mode: Feishu doc → WeChat copy
Use this mode when the source article should remain close to the original, especially when the user wants the original detail and diagrams preserved.
Default behavior:
- preserve section hierarchy and detail density
- preserve figures, appendices, tables, code blocks, callouts, and examples
- perform only necessary publishing cleanup instead of fresh rewriting
- rewrite only where internal phrasing, internal context, or platform formatting needs adjustment
- export embedded Feishu whiteboard/diagram/media content as images when possible and include them in the article
Important copy-transfer rules:
- do not compress a detailed document into a summary just because it is long
- do not strip diagrams unless they truly cannot be recovered or published
- do not replace an already-strong structure with a generic article skeleton
- treat user signals like “搬运一下” and “图也得搬一下” as explicit instructions to preserve content volume and figures
- if the user criticizes a version as “太精简”, the next version must restore detail and figures first
Completion criteria:
- the published WeChat draft is a faithful transfer of the source article
- figures are migrated wherever technically possible
- the article retains the original depth unless the user explicitly asks for condensation
When the source is a Feishu document:
- load the document first
- identify the original goal, audience, and structure
- convert internal phrasing into public-facing WeChat phrasing where needed
- preserve technical accuracy, original names, diagrams or examples worth keeping, and practical substance
- do not over-summarize; reshape the document into a publishable article instead of reducing it to a shallow overview
Feishu conversion rules
When loading a Feishu document, the feishu_doc_read tool will fail with "Feishu client not available" outside of Feishu comment contexts. Reliable fallback:
~/.local/bin/lark-cli docs +fetch --doc <token-or-url> --doc-format markdown --format json -q '.data.document.content'
Note: The feishu_doc_read tool is only available when Hermes is running inside a Feishu gateway context. In all other contexts (terminal, cron jobs, Desktop), use the lark-cli fallback above.
- preserve the technical spine of the document, not the internal presentation order
- keep real components, real flows, real constraints, and real examples whenever they are valuable to an external reader
- remove internal assumptions that an outside reader cannot understand or does not care about
- rewrite internal system names, internal project references, or internal shorthand unless they are essential to the story
- convert note-like or memo-like structure into a deliberate article structure
- if the document is too linear, too flat, or too internal, rebuild it into a stronger skeleton before drafting
- avoid flattening the document into a summary; the goal is publishing reconstruction, not compression
- make the final article feel like the author deliberately wrote it for WeChat readers, not like a sanitized internal export
- if the source Feishu doc contains
<callout>blocks, convert them explicitly to WeChat-safe structures before HTML conversion; do not leave raw Feishu-specific tags in the publishing payload - if the source Feishu doc contains embedded whiteboard/export figures, migrate them explicitly as images and deduplicate references before publishing
Feishu structural rebuilding heuristics
Rebuild the skeleton when the source doc shows any of these patterns:
- the document is essentially raw notes or bullet-heavy internal thinking
- the structure is too chronological without a clear publishing payoff
- the internal ordering buries the most publishable points
- the document mixes audience types or mixes unrelated concerns
- the original structure would make a WeChat reader drop off early
Preferred rebuilt shapes:
- problem → background → core approach → practical examples → pitfalls → conclusion
- objective → design/workflow → implementation notes → lessons → next steps
- question/context → architecture → execution details → verification → recommendation
Completion criteria:
- the Feishu doc has been processed as primary source material
- internal phrasing has been converted where needed without destroying technical value
- the final article reads like an intentional WeChat article rather than a raw internal doc repost
Topic → content building
When the source is only a topic:
- define the publishing job before generating content
- search for current and reliable material only as much as needed
- choose an article structure deliberately
- build a skeleton before long-form writing
- draft the article with real technical substance
- then humanize and package it
Cover image prompt strategy
When generating cover images, the prompt must extract specific structural information from the article content, not use generic abstract descriptions.
Bad prompt (generic):
"A minimalist technical architecture diagram cover image. Dark navy blue background with abstract glowing network nodes..."
Good prompt (content-specific):
Extract the article's core structure — layer names, component names, design pillars, key concepts — and describe them explicitly in the prompt. For example, for an architecture article, describe the actual layers (e.g., "Layer 1 Multi-Entry with CLI/Web/API, Layer 2 Core Runtime with Session/Scheduler/Executor"), the title text, subtitle, color scheme per layer, and layout.
The cover image generation pipeline:
- read the article content
- extract key structural elements (title, layers, components, design pillars)
- build a detailed prompt that describes these elements visually
- call
generate_image.py --generator openai - verify the generated image visually before publishing
Image generation strategy
This skill should treat image generation as a configurable publishing capability, not as a hard requirement.
Current integration status:
- the
wechat-publisherexecution project has image generation support and config keys - this skill has wired execution scripts for publishing / HTML conversion / AI-score checking
- image generation is not yet embedded as a required default step in this skill's publishing loop
Default recommendation:
- publishing should succeed even when image generation is disabled or unconfigured
- if image generation is unavailable, fall back to text-first layout or manual cover selection
- if image generation is enabled, separate the flows clearly:
- cover image
- in-article images
- fallback behavior when image generation partially fails
When advising on YAML configuration, clarify these distinct blocks:
- account credentials
- publishing behavior
- image generation provider keys / model settings
- integration tokens
This prevents confusion between "what is needed to publish" and "what is needed to auto-generate images".
Topic selection rules
Prefer these topic angles for the owner's personal brand:
- practical workflow / practice sharing
- architecture or system design breakdown
- toolchain setup, evaluation, or comparison
- engineering pitfalls and debugging notes
- open-source project analysis from a practitioner view
- data infrastructure, data integration, data synchronization, or adjacent engineering topics
Avoid these angles unless explicitly requested:
- shallow news reposting without analysis
- motivational or generic industry commentary
- purely promotional tool introduction without practitioner value
Topic-building quality checks
Before drafting, confirm the chosen structure answers these questions:
- what is the article actually giving the reader?
- why is this structure the right one for the topic?
- where are the concrete examples or practitioner judgments?
- what will the reader be able to do after reading the article?
Completion criteria:
- the topic has been shaped into a clear article job
- the output follows a deliberate structure rather than generic expansion
Workflow
Step 1: Clarify the source type
The skill should first identify the input type:
- topic only
- Feishu document
- Markdown / notes
- reference links
- existing draft
Completion criteria:
- source type is identified
- publishing account is confirmed
- intent is clear: publish now, produce draft, or produce review package
If the source is a Feishu doc, load it directly with Feishu doc tools when possible and treat it as the primary source of truth. If the source is only a topic, confirm the minimum missing context before research.
Step 2: Define the article job
Before writing, define:
- target reader
- article goal
- article type
- expected structure
Common article types:
- practical tutorial
- architecture / workflow explanation
- toolchain evaluation
- troubleshooting / case study
- industry or technical trend analysis
- document-to-article conversion
Completion criteria:
- the article job is written in one short paragraph
- the chosen structure is explicit
Step 3: Collect research material
Do research only after the job is defined.
Gather:
- official docs / release notes / blog posts
- real commands, configs, APIs, and behaviors
- high-quality recent references
- concrete examples or deployment notes
- only relevant discussion when it adds practitioner perspective
Do not pad research with generic background.
Completion criteria:
- key facts are collected
- sources are available
- reusable examples are identified
Step 4: Build the skeleton
Before full drafting, generate a skeleton:
- title candidates
- summary / digest
- section outline
- per-section angle
- expected diagrams / examples
- cover concept
Prefer skeletons with:
- a sharp opening
- 3-6 sections
- uneven section length if needed
- a clear ending that adds judgment or next-step advice
Completion criteria:
- skeleton exists and can be reviewed before long-form writing
Step 5: Draft the article
Write the draft in Markdown.
The draft should:
- start with the real problem or scenario
- avoid generic openers like "随着...的发展"
- avoid AI ceremonial phrasing
- keep paragraphs tight
- use concrete nouns and verbs
- mix explanations with examples
- show the actual steps when the topic is practical
- preserve important English terms where natural
Good patterns:
- problem statement
- prerequisites
- step-by-step implementation
- commands or configs
- validation steps
- pitfalls
- summary / recommendation
Completion criteria:
- Markdown draft is complete
- title, summary, and main body are ready
- cover direction is identified
Step 6: Humanize and de-AI the draft
This is a mandatory step for professional publishing.
Check and fix:
- generic filler
- repetitive parallel sentences
- over-polite or marketing-like tone
- empty conclusions
- sections that sound impressive but say nothing
- overuse of the same rhetorical structure in every section
Useful checks:
- does each section contain something only someone who did the work would know?
- are there concrete examples, numbers, configs, commands, or paths?
- does the article have personal judgment or author perspective?
- would a technically literate reader trust this article?
Completion criteria:
- the draft reads like a real technical blog post
- obvious AI patterns are reduced
- the voice matches the default profile unless overridden
Step 6.5: Normalize source into WeChat-ready Markdown
Before converting to HTML, normalize heterogeneous source Markdown into WeChat-ready Markdown.
This step should handle Feishu-specific constructs and other non-standard blocks, including:
<callout ...>...</callout>→ bold text with emoji prefix preserved (e.g.<callout emoji="💡">定位:...</callout>becomes**💡 定位:...**), NOT a Markdown blockquote<whiteboard ...>...</whiteboard>→ local exported image reference when a token is available<title ...>...</title>→ top-level Markdown heading when appropriate- emoji hints preserved as bold prefixes when appropriate
- residual wrapper tags stripped while preserving usable text
Completion criteria:
- the article has been normalized into clean Markdown
- the HTML renderer receives standardized Markdown instead of raw source-specific markup
Step 7: Render with gzh-design
Markdown → HTML must use the gzh-design skill. Read references/gzh-design-integration.md for the exact integration contract.
Required sequence:
- keep the Step 6.5 normalized Markdown as the canonical source;
- load
gzh-design; - choose a theme from its
references/theme-index.mdaccording to article type or the user's explicit choice; - read the selected theme component library and
references/common-components.md; - assemble the final pure
<section>…</section>body fragment—do not addhtml/head/body/style/scriptwrappers; - preserve every source paragraph, figure, table, callout conversion, code block, and link;
- run
scripts/wp-gzh-validate.sh <html>and fix until ERROR=0 and WARNING=0; do not trust the upstream validator's exit code alone because WARNING can still return success; - generate the copy-ready preview with
scripts/wp-html.sh.
Do not call html_converter.py in the normal path. It is legacy fallback only.
Completion criteria:
- normalized Markdown and gzh-design HTML both exist;
- selected gzh-design theme and selection reason are recorded;
- validator reports 0 ERROR and 0 WARNING;
- the HTML contains no raw source-specific blocks and no missing figures;
- title / digest / author / cover are explicit.
Step 7.5: Generate cover image if missing
When the publishing flow needs a cover but none exists, attempt automatic cover generation from the configured image backend before publishing.
Priority:
- use user-supplied cover
- use an existing article image if appropriate
- if still missing, generate one cover image and use it for the draft
Completion criteria:
- the publishing flow has a usable cover strategy
- publishing is not blocked unnecessarily when image generation is available
Step 8: Execute publishing via wechat-publisher
When draft-box publishing is requested and prerequisites are satisfied, delegate execution to the wechat-publisher toolchain instead of inventing a new publishing path.
Use these execution assets from this skill:
references/wechat-publisher-execution.mdtemplates/wechat-publisher.yaml.examplescripts/wechat_publisher/scripts/wp-list-accounts.shscripts/wp-token.shscripts/wp-html.shscripts/wp-ai-score.shscripts/wp-publish.shscripts/wp-bootstrap.shscripts/wp-run.sh
- prepare and preserve the normalized Markdown article;
- check AI score / humanization quality on Markdown;
- render with
gzh-design, then run its validator to 0 ERROR / 0 WARNING; - prepare cover / title / digest / author;
- call
scripts/wp-publish.sh <gzh-html> --title ...—the HTML publishing path uploads local/external<img src>references to WeChat CDN before draft creation; - capture the returned draft
media_id; - verify the created draft with
scripts/wp-verify-draft.py --media-id <id> --account <name>; confirm title, author, digest, non-empty content, selected theme structure, and expected inline images; - if publishing fails, keep the validated gzh-design HTML and preview as the ready-to-paste package.
Completion criteria:
- the publishing attempt has been executed through the real backend
- a successful draft has been read back from WeChat, not inferred only from the create response
- success or failure is explicit
- fallback output is ready when draft-box publishing is unavailable
Step 9: Package the final output
Mode A: draft-box publishing (preferred)
Use the configured WeChat publishing workflow to push the article into the draft box.
Typical required outputs:
- title
- digest
- author
- cover image
- HTML content
This mode should be used when:
- credentials are configured
- IP whitelist is configured
- API connection succeeds
- upload / draft creation succeeds
Mode B: ready-to-paste package (fallback)
Use when draft-box publishing is not possible.
Deliver:
- title
- digest
- author suggestion
- cover image suggestion
- final HTML or copy-ready formatted content
- publishing notes
This mode is not a failure mode. It is the stable fallback for a personal subscription account.
Mode C: review package (optional)
Use only when the user explicitly asks for review before publishing.
Deliver:
- Markdown draft
- HTML draft
- 3-5 rewrite suggestions
- checklist of what still needs improvement
- publishing recommendation
Completion criteria:
- one of the three output modes is delivered
- the user knows exactly what the next action is
Input Contract
Accept one or more of the following:
- a topic
- a Feishu doc token / URL
- local Markdown file path
- notes or outline
- a set of reference links
- publishing constraints
If the source is a Feishu document, prefer extracting and transforming that document instead of asking the user to restate the content manually.
When doing so, use templates/feishu-doc-intake.md to capture publishing intent and transformation constraints.
If the user gives only a topic, ask only the minimum missing context:
- target account (default to
main) - audience
- preferred structure or article type
- any must-include material
When doing so, use
templates/topic-intake.mdinstead of asking open-ended questions.
Do not over-ask. If reasonable defaults exist, use them.
Output Contract
Every run should clearly deliver:
- final title
- final digest
- author
- cover direction or cover file
- Markdown draft
- WeChat HTML when available
- publishing result or fallback package
- a short note on what the user should do next
Use templates/final-package.md when a structured publishing package is needed.
Recommended output shape for Feishu doc publishing mode
When the source is a Feishu document, the final package should include:
- title
- digest
- author
- cover direction / cover file
- what the publishing goal is
- what main structural changes were made
- what was preserved from the original doc
- what was rewritten, removed, or reorganized for external publishing
- publishing result or fallback package
Recommended output shape for topic content-building mode
When the source is a topic, the final package should include:
- title
- digest
- author
- chosen article type
- chosen structure / scaffold
- key references used
- publishing result or fallback package
Draft-box publishing package
When draft-box publishing is attempted, the final package should include:
- title
- digest
- author
- cover image / cover direction
- HTML content
- publishing result or failure summary
- fallback package if draft-box publishing fails
Ready-to-paste fallback package
When fallback publishing is used, deliver:
- final title
- final digest
- author
- cover image suggestion or cover file
- Markdown or HTML ready to paste
- short publishing notes
- recommended next step
Publishing Strategy
Default strategy:
- try draft-box publishing first
- if credentials or API issues occur, produce the ready-to-paste package
- if the user wants review first, switch to review package
- never stop at "writing only" unless the user explicitly asks for writing-only output
Draft-box attempt order
When draft-box publishing is attempted, follow this order:
- load account config
- check AppID / AppSecret / whitelist assumptions
- prepare title / digest / author / cover
- prepare WeChat-compatible HTML
- call the
wechat-publisherexecution backend - if successful, report the draft-box result clearly
- if failed, switch immediately to ready-to-paste package and explain the failure briefly
This makes the publishing flow stable and predictable instead of halting at the first failure.
Fallback Strategy
Use these fallbacks instead of stopping:
- if
AppID / AppSecret / whitelistis not ready → output publishing package - if token retrieval fails → output publishing package
- if draft API fails → output publishing package
- if image generation fails → publish without generated images when acceptable, or switch to text-first layout
- if article quality looks weak → force another humanization pass before publishing
- if the Feishu doc is too internal or too raw → restructure it into an explicit publishing skeleton before final drafting
- if the topic is too broad → force job definition and scaffold selection before content generation
Ready-to-paste package checklist
When fallback is triggered, deliver a complete publishing package:
- final title
- final digest
- author
- cover image suggestion or cover file
- copy-ready Markdown or HTML
- notes on what to paste into the WeChat editor
- short recommendation for the next step
WeChat Publishing Checklist
Before draft-box publishing, check:
- account selected
- title is sharp and not generic
- digest is clean and share-card friendly
- cover exists or fallback cover strategy is defined
- author is set
- HTML is WeChat-compatible
- IP whitelist is configured
- AppID / AppSecret are valid
- publishing mode is explicit: draft / paste-package / review
Recommended Article Skeleton
Use this as the default skeleton unless a better structure is required:
- opening with the real problem or scenario
- background / context only if needed
- core implementation / workflow / architecture
- concrete examples / commands / configs / Feishu doc conversion notes
- pitfalls and lessons learned
- conclusion with actionable next steps
Topic Scaffolding Templates
When the source is only a topic, use one of the following scaffolds unless the case clearly demands a different shape.
Problem-oriented technical article
- why this problem matters
- what we are going to solve or build
- minimal prerequisites
- core workflow / architecture / implementation path
- concrete examples or validation
- pitfalls and practical notes
- conclusion and next steps
Tool / framework evaluation article
- what problem the tool is trying to solve
- what the tool is and where it fits
- core concepts or architecture
- hands-on experience / setup notes / example flow
- strengths, limitations, and suitable scenarios
- conclusion
Workflow / practice article
- the original problem or goal
- what was tried before and why it was not ideal
- the improved workflow
- how it works in practice
- lessons learned
- recommended next step
Content review and quality gate
Publishing should not stop at "article generated successfully".
When the generated article looks publishable but weak, run a review pass before draft-box publishing:
- check whether the article reads like the owner's own professional output, not like a sanitized document export
- check whether the source document was transformed into a publishing-grade structure instead of being lightly reformatted
- check whether the article contains concrete examples, configs, commands, paths, or practitioner judgment
- check whether the opening is anchored in a real problem or scenario rather than generic setup
- check whether the article has enough publishable value beyond the original doc
If the review finds the article is still in "document dump" form, rewrite or restructure before publishing.
Useful review questions:
- does this article look like something the owner would publish on their own public account?
- did the skill preserve technical value while increasing publishability?
- would a reader get a clear payoff from the article?
- is the structure chosen for the reader, not just for the source document?
Completion criteria:
- the article has passed a qualitative review, not only an AI-score check
- if the article is still too raw, it is reworked before final packaging
Common Pitfalls
- Rendering new articles with
html_converter.pyorhtml_converter_mature.pyinstead of loadinggzh-design. - Passing Markdown directly to
wp-publish.sh; the canonical wrapper accepts validated gzh-design HTML. - Publishing the
_预览.htmlpage instead of the clean<section>fragment. - Skipping the gzh-design validator or accepting warnings; publishing requires 0 ERROR / 0 WARNING.
- Sending raw Feishu
<grid>,<callout>,<whiteboard>, Mermaid, or mindmap syntax into gzh-design. - Dropping or duplicating diagrams while migrating Feishu content.
- Compressing a mature source document when copy-transfer mode requires fidelity.
- Mixing components from multiple gzh-design themes or hand-writing an unrelated parallel theme.
- Using browser-only CSS, native nested-list assumptions, full-page wrappers, or missing
<span leaf="">wrappers. - Assuming pre-rendered HTML cannot carry local images; the HTML publisher now uploads and replaces local/external
img srcvalues. - Using
--allow-missing-imagesby default; unresolved figures should block publishing unless the user explicitly accepts missing images. - Omitting
--coverwhen the article has no resolvable first image. - Falling back to random Picsum/Pixabay covers instead of the configured
generate_image.pypipeline or a relevant article image. - Treating masked credentials shown by Hermes as truncated values; call the configured script and diagnose only real API failures.
- Declaring success from
draft/addalone; read the draft back and compare title, digest, content, links, and figure count.
Verification Checklist
-
publishing goal is explicit
-
input source is identified
-
article structure is chosen for the right reason
-
draft reads like a professional technical blog
-
WeChat publishing package is complete
-
final deliverable includes title / digest / HTML or Markdown / cover / next action
-
fallback behavior is clear if draft-box publishing is unavailable
-
execution assets are available:
references/gzh-design-integration.md,references/wechat-publisher-execution.md,templates/wechat-publisher.yaml.example,scripts/wechat_publisher/,scripts/wp-list-accounts.sh,scripts/wp-token.sh,scripts/wp-gzh-validate.sh,scripts/wp-html.sh,scripts/wp-ai-score.sh,scripts/wp-publish.sh,scripts/wp-verify-draft.py,scripts/wp-ready-md.sh -
gzh-designwas used for Markdown → HTML and its validator reports 0 ERROR / 0 WARNING -
the clean
<section>artifact—not the_预览.htmlpage—is the file passed to publishing -
intake templates are used when input is a Feishu doc or topic:
templates/feishu-doc-intake.md,templates/topic-intake.md -
final publishing package follows
templates/final-package.mdwhen a structured output is needed -
YAML configuration advice distinguishes between publishing credentials and image-generation settings
-
WeChat HTML avoids duplicate numbering and visually weak nested lists when hierarchy matters
-
Feishu-native blocks (callouts, embedded whiteboard figures, appendix images) have been explicitly converted or migrated before HTML conversion
Skill Scope
This skill is the implementation/runtime skill for WeChat personal-subscription publishing.
Class-level workflow design, evaluation criteria, and broad publishing heuristics belong in the companion skill wechat-official-article-automation.
Use wechat-autopublish when the task is to actually operate the publishing pipeline: read source content, normalize Markdown, render HTML, prepare publishing assets, and attempt draft-box publishing or produce the fallback package.
Future Extensions
This skill can later be extended to support:
- direct Feishu-doc-to-WeChat-article conversion mode
- topic queue and batch publishing
- personal style profile auto-refresh from the owner's blog
- brand glossary and preferred terminology list
- review pipeline with approval step
- multi-account profiles if needed
- expand the gzh-design theme library while keeping one canonical Markdown → HTML path
What ships with it: 72 files
348.3 KB alongside SKILL.md, 26 of them executable
references/
scripts/
- fix_table_pipes.pyruns1.6 KB
- wechat_publisher/ai_score.pyruns15.2 KB
- wechat_publisher/api.pyruns12.6 KB
- wechat_publisher/assets/image-styles/blue.json3.0 KB
- wechat_publisher/assets/image-styles/data-chart.json2.4 KB
- wechat_publisher/assets/image-styles/flat-editorial.json4.9 KB
- wechat_publisher/assets/image-styles/hand-drawn-blue.json2.3 KB
- wechat_publisher/assets/image-styles/illustrated-warm.json3.3 KB
- wechat_publisher/assets/image-styles/infographic-blue.json5.2 KB
- wechat_publisher/assets/image-styles/infographic-dark.json5.4 KB
- wechat_publisher/assets/image-styles/infographic-mint.json5.2 KB
- wechat_publisher/assets/image-styles/infographic-warm.json5.4 KB
- wechat_publisher/assets/image-styles/knowledge-card.json2.3 KB
- wechat_publisher/assets/image-styles/magazine-editorial.json2.3 KB
- wechat_publisher/assets/image-styles/meme-illustration.json2.3 KB
- wechat_publisher/assets/image-styles/mint.json3.1 KB
- wechat_publisher/assets/image-styles/morandi.json3.4 KB
- wechat_publisher/assets/image-styles/quote-card-minimal.json1.9 KB
- wechat_publisher/assets/image-styles/README.md19.9 KB
- wechat_publisher/assets/image-styles/tech-card-blue.json2.3 KB
- wechat_publisher/assets/image-styles/warm-handdrawn.json4.4 KB
- wechat_publisher/assets/image-styles/xiaohongshu-colorful.json2.3 KB
- wechat_publisher/assets/themes/academic-paper.json5.2 KB
- wechat_publisher/assets/themes/business-navy.json5.2 KB
- wechat_publisher/assets/themes/elegant-ink.json5.1 KB
- wechat_publisher/assets/themes/girly-pink.json5.3 KB
- wechat_publisher/assets/themes/ink-wash.json5.1 KB
- wechat_publisher/assets/themes/magazine-grid.json5.1 KB
- wechat_publisher/assets/themes/minimal-bw.json5.2 KB
- wechat_publisher/assets/themes/minimal-mono.json5.0 KB
- wechat_publisher/assets/themes/mint-fresh.json5.3 KB
- wechat_publisher/assets/themes/news-bold.json5.1 KB
32 more files not listed here. See all 72 in the repository.