Sync Yuque Doc → Dumi Spec
One-shot sync from Yuque to docs/spec/{slug}.zh-CN.md (+ English docs/spec/{slug}.md), with no manual edits when config and tooling are in place.
Prerequisites
| Tool | Purpose |
|---|---|
MCP user-语雀mcp-server v2 |
skylark_resolve_url, skylark_doc_detail |
huamei CLI (@alipay/huamei-cli) |
Upload images to CDN |
translate-docs skill |
English docs/spec/*.md for simple docs |
Default Huamei space for design spec images: S_nZdyOe
CDN pattern: https://mdn.alipayobjects.com/huamei_qpzozj/afts/img/.../original
Quick start (one command after fetch)
# 1. Agent: fetch Yuque body via MCP → save to /tmp/yuque-body.md
# 2. Generate ephemeral config → /tmp/sync-yuque-doc-{slug}.json (from _template + existing spec frontmatter)
# 3. Run sync (download images → Huamei → write zh-CN)
node .cursor/skills/sync-yuque-doc/scripts/sync-yuque-doc.mjs \
--config /tmp/sync-yuque-doc-product-graphic.json \
--body /tmp/yuque-body.md
# 4. Generate English with translate-docs skill (docs/spec/product-graphic.zh-CN.md → product-graphic.md)
Workflow
Copy this checklist and complete every step:
Sync progress:
- [ ] 1. Resolve Yuque URL → doc_id
- [ ] 2. Fetch body (format=md) + save to temp file
- [ ] 3. Generate ephemeral sync config in `/tmp/sync-yuque-doc-{slug}.json` (do not keep under `configs/`)
- [ ] 4. Run sync-yuque-doc.mjs (images + transform + write zh-CN)
- [ ] 5. Generate English (`translate-docs` skill)
- [ ] 6. Validate (grep + dev preview)
- [ ] 7. Remove temp assets; do NOT commit url-map / downloaded images / sync config JSON
Step 1–2: Fetch from Yuque
skylark_resolve_url({ url: "<yuque-url>" }) → doc_id
skylark_doc_detail({ doc_id, format: "md" }) → save body to /tmp/yuque-body.md
Use format: "md" (not ymd) unless you need section-level editing via skylark_doc_section_*.
Step 3: Config (ephemeral)
Do not save {slug}.json under configs/. Each sync run:
- Copy configs/_template.json →
/tmp/sync-yuque-doc-{slug}.json - Set fields below (read existing
docs/spec/{slug}.zh-CN.mdforfrontmatter/siteIntrowhen re-syncing) - Delete the temp config when done (or leave in
/tmp)
outputs.zh-CN— e.g.docs/spec/product-graphic.zh-CN.mdoutputs.en— e.g.docs/spec/product-graphic.mdfrontmatter— preserve existinggroup,subGroup,title,ordersiteIntro— Dumi-only paragraph(s) after frontmatter (component links, etc.)huameiSpaceId— defaultS_nZdyOefor spec docsskipImages— filenames that 404 on Yuque CDN (screenshots only; keep illustration)stripBlocks— regex list (e.g. Figma:::tipsblocks)
Step 4: Run sync script
node .cursor/skills/sync-yuque-doc/scripts/sync-yuque-doc.mjs \
--config /tmp/sync-yuque-doc-{slug}.json \
--body /tmp/yuque-body.md \
[--url-map /tmp/huamei-url-map.json] # skip download/upload if map exists
Script does:
- Extract
intranetproxy.alipay.comimage URLs from body - Download to temp dir (skip
skipImages) huamei asset upload <dir> --space-id <spaceId> --json- Retry failures: PNG → JPEG via
sips, re-upload - Write
/tmp/huamei-url-map.json(filename → asset.assetUrl) - Transform body → prepend frontmatter + siteIntro → write
outputs.zh-CN
Step 5: English
Use translate-docs skill: docs/spec/{slug}.zh-CN.md → docs/spec/{slug}.md.
Rule: EN and zh-CN must share the same structure and CDN URLs; only text differs.
Step 6: Validate
# No intranet / local asset leaks
rg 'intranetproxy|/assets/spec/' docs/spec/{slug}*.md
# All images in zh-CN resolve (optional spot-check)
rg -o 'https://mdn.alipayobjects.com[^)]+' docs/spec/{slug}.zh-CN.md | head
# Preview
pnpm dev # open /zh-CN/docs/spec/{slug} and /docs/spec/{slug}
Pass criteria:
- Heading levels: page title in frontmatter; body starts at
## - Tables match Yuque (cells use
<br/>, tertiary rows<br/><br/>) -
+lists,<u>, numbered lists preserved - No
intranetproxy, nopublic/assets/spec/paths -
skipImagescells show illustration only (no broken img) -
stripBlocksremoved (no Figma / internal-only links unless requested) - siteIntro present; wording unchanged from last sync unless intentional
Content transform rules
Full reference: references/TRANSFORM-RULES.md
Must preserve (Yuque → Dumi)
| Yuque | Dumi |
|---|---|
# 章节 |
## 章节 (demote one level; H1 = frontmatter title) |
+ unordered lists |
keep + (do not convert to - if Yuque used +) |
<u>…</u> |
keep |
:::tips / :::info |
keep type Yuque used (:::tips not :::info) |
| Table multi-image cells | join with <br/>; tertiary section <br/><br/> |
200*100 size notation |
keep * not × if Yuque used * |
| Original Chinese copy | do not paraphrase |
Must transform
| Source | Target |
|---|---|
https://intranetproxy.alipay.com/skylark/.../{filename} |
Huamei asset.assetUrl (/original) |
<!-- ... --> |
remove |
![]() after skipped image |
remove |
Flex <div style="display:flex"> if Yuque used tables |
use Markdown tables, not flex |
Internal-only blocks in stripBlocks |
remove |
Must NOT do
- Commit downloaded images under
public/assets/spec/ - Commit
/tmp/huamei-url-map.json(regenerate on sync) - Keep per-doc sync config under
configs/(only_template.jsonbelongs there) - Replace tables with flex layouts for “prettier” rendering
- Add Figma / Yuque links unless user asks
- Use
subAssets[0]WebP for spec docs — useasset.assetUrl(/original) for consistency with existing spec pages
Images & attachments
Image pipeline
Yuque MD (intranetproxy URLs)
→ download to /tmp/sync-yuque-doc-{slug}/
→ huamei asset upload --space-id S_nZdyOe --json
→ map[filename] = result.asset.assetUrl
→ replace URLs in markdown
→ delete temp dir
Upload failures
| Error | Fix |
|---|---|
| PNG compress fail | sips -s format jpeg <file> --out /tmp/<name>.jpeg then re-upload |
| Single file fail | Upload individually; merge into url-map |
| Source 404 on Yuque | Add filename to skipImages; remove resulting ![]() |
Non-image attachments
- Yuque file cards / attachments: use
skylark_resource_detailif URL is a resource id - For public site: upload via
huamei asset upload <file> --type file --space-id S_nZdyOe - Replace link in MD with
asset.assetUrl
Config vs manual layout
| Scenario | Tool |
|---|---|
| First sync / Yuque structure changed | Regenerate /tmp/sync-yuque-doc-{slug}.json (stripBlocks / skipImages), re-run sync |
| CDN URLs changed | Re-run sync with existing --url-map |
Dumi-only layout (flex rows, .product-graphic-spec) |
Edit docs/spec/*.zh-CN.md directly; then translate-docs for EN |
Agent notes
- Always read existing target file before sync — preserve
frontmatterandsiteIntrounless user wants replace. - MCP auth: if
skylark_*fails, ask user to authenticate 语雀 MCP first. - huamei not found:
source ~/.zshrc; tnpm i -g @alipay/huamei-cli - After sync, summarize: files written, image count, skipped images, stripped blocks.
- Changelog: spec doc sync is user-facing → mention in PR changelog table; do not edit
docs/design/design-CHANGELOG*.mdunless doing a release pass.
Related
- references/TRANSFORM-RULES.md — transform details & edge cases
- translate-docs — English prose docs