Prerequisites
- feishu-cli: if not installed, go to riba2534/feishu-cli install
- Authentication: environment variable
FEISHU_APP_ID+FEISHU_APP_SECRETor~/.feishu-cli/config.yaml - Permissions:
board:whiteboard(whiteboard read/write) +docx:document(add whiteboard to document) - whiteboard-cli(used by paths B/C):
npm i -g @larksuite/whiteboard-cli
Selection Decision Tree
画什么?
│
├─ 标准图表(思维导图/时序图/类图/饼图/流程图/甘特图)
│ ├─ 图整图展示即可,不需要单独编辑节点 → 路径 A(Mermaid 服务端)
│ └─ 需要单独编辑每个节点 / Mermaid 含 par / 10+ participant / 30+ 长标签
│ → 路径 B(Mermaid 本地引擎)
│
├─ AI 自由作图(飞轮/鱼骨/价值金字塔/转化漏斗/桑基/路线图/Dashboard/海报/
│ Mobile UI/户型图/地铁图/插画/周期表/机芯/赛博朋克城市等)
│ ⭐ → 路径 C(SVG → 原生节点,每个元素可单独点击编辑)
│
├─ 简单 SVG 装饰(图标/印章/小元素,< 2KB SVG)
│ └─ 路径 D(svg-import 单节点)
│
└─ 精排架构图 / 对比矩阵 / 组织树(需要绝对坐标 + 特定配色 + 连接线 ID 引用)
└─ 路径 E(手写节点 JSON + create-notes)
Path Selection Quick Reference:
| User Description | Recommended Path |
|---|---|
| "Draw a mind map / sequence diagram / class diagram" | A |
| "Draw a flowchart" | A |
| "Put this mermaid onto the whiteboard" | A |
| "mermaid server-side error / par not supported / overly complex" | B |
| "Draw a growth flywheel / fishbone analysis / value pyramid" | C ⭐ |
| "Draw a Dashboard / Mobile UI / poster" | C ⭐ |
| "Draw an illustration / floor plan / subway map" | C ⭐ |
| "AI freely designed graphics (use Claude to directly output SVG)" | C ⭐ |
| "Need every element in the image to be individually clickable / recolorable / draggable" | C ⭐ |
| "Upload a small icon / stamp to the whiteboard" | D |
| "Draw a 6-microservice architecture diagram, requiring precise coordinates and connections" | E |
Path A: Mermaid/PlantUML Server-Side
Suitable for: standard charts, the whole image displayed as one node.
Quick Start
DOC_ID=$(feishu-cli doc create --title "示例" -o json | jq -r .document_id)
BOARD_ID=$(feishu-cli doc add-board $DOC_ID -o json | jq -r .whiteboard_id)
# 从文件导入
feishu-cli board import $BOARD_ID flowchart.mmd --syntax mermaid
# 从字符串导入
feishu-cli board import $BOARD_ID "graph TD; A-->B-->C" --source-type content --syntax mermaid --diagram-type flowchart
# PlantUML
feishu-cli board import $BOARD_ID diagram.puml --syntax plantuml
Limitations (see references/mermaid-engines.md for details)
- The entire image is a single node and cannot be split apart for editing
- Does not support
parsyntax - ≥10 participant / ≥3 levels of alt / ≥30 long labels may fail
- The CLI automatically diagnoses complexity and warns to stderr
Path B: Mermaid Local Engine
Suitable for: complex Mermaid (which would fail server-side), or when each node needs to be edited separately.
Quick Start
# 一次性装好本地引擎(仅首次)
npm i -g @larksuite/whiteboard-cli
# 走本地引擎
feishu-cli board import $BOARD_ID complex.mmd --syntax mermaid --engine local
How It Works
feishu-cli board import --engine local
│
├─ whiteboard-cli 把 Mermaid 翻译为节点 JSON(在本地,不调飞书)
└─ feishu-cli 把节点 JSON 用 create-notes 分批上传
For detailed comparison and pitfalls, see references/mermaid-engines.md。
Path C: SVG → Native Nodes ⭐
Suitable for: all AI freely designed graphics, where every element is an independent, editable Feishu node.
Quick Start (one-click script)
# Step 0: 定色板(生成 SVG 之前)—— 色值取自统一色板,不自创
# 结构分组用浅底/深边对、数据系列用 categorical 原色,见 references/style.md。
# 原样按序取用统一色板时无需校验(已预校验,结论见 feishu-cli-dataviz palette.md);
# 仅当改色值/换底色时先跑校验(定位方式见 references/style.md"数据图表的系列色"一节)。
# Step 1: 准备 SVG(手写 / Python 生成 / AI 吐)
# 示例:用 Claude 生成一个增长飞轮 SVG,保存为 flywheel.svg
# Step 2: 创建文档 + 画板
DOC_ID=$(feishu-cli doc create --title "增长飞轮" -o json | jq -r .document_id)
BOARD_ID=$(feishu-cli doc add-board $DOC_ID -o json | jq -r .whiteboard_id)
# Step 3: 一键 SVG → 飞书画板(5 步管道自动执行)
python3 ./skills/feishu-cli-board/scripts/svg_to_board.py flywheel.svg $BOARD_ID
The script automatically performs 5 steps:
- whiteboard-cli translation: SVG → node JSON
- Fix z_index: explicitly assign values in array order (fixes pitfall 1)
- Trim viewBox overflow: delete nodes that exceed the bounds (fixes pitfall 2)
- Batch create-notes: 300 per batch, 0.3s interval (prevents rate limiting)
- Verify: pull the real node count / type distribution for comparison
Full Workflow Details
Read references/svg-workflow.md: includes the translation mapping table from SVG elements → Feishu nodes, node density references for 14 real-world diagrams, and the boundaries for when to split a diagram.
SVG Design Reference
Read references/examples-real.md: Index of design patterns for 14 practical diagrams, SVG element composition of each diagram, and key technical points (polar coordinates / trigonometric functions / cubic-bezier, etc.).
Path D: SVG single-node decoration
Suitable for: icons / seals / small elements (< 2KB SVG), no need to split for editing.
Quick start
feishu-cli board svg-import $BOARD_ID icon.svg \
--x 100 --y 100 --width 60 --height 60
# 自动从 viewBox 推断尺寸
feishu-cli board svg-import $BOARD_ID badge.svg --x 0 --y 0
# 直接传字符串
feishu-cli board svg-import $BOARD_ID '<svg viewBox="0 0 100 100">...</svg>' \
--source-type content --x 50 --y 50
# 预览不发请求
feishu-cli board svg-import $BOARD_ID drawing.svg --dry-run
Core differences from Path C
| Path | Node count | Editability | Suitable complexity |
|---|---|---|---|
| D(svg-import) | 1 (the whole diagram is 1 svg node) | ❌ The whole diagram as one vector texture | < 2 KB SVG |
| C(svg_to_board.py) | N (1 node per element) | ✅ Each rect/text/path can be selected individually | Unlimited |
Path E: Precisely arranged architecture diagram
Suitable for: architecture diagrams / comparison matrices / organization trees, requiring absolute coordinates + specific color schemes + connector line ID references.
Quick start
# 1. 创建文档 + 画板
DOC_ID=$(feishu-cli doc create --title "微服务架构" -o json | jq -r .document_id)
BOARD_ID=$(feishu-cli doc add-board $DOC_ID -o json | jq -r .whiteboard_id)
# 2. 写 shapes.json(先形状)
cat > /tmp/shapes.json << 'EOF'
[
{"type":"composite_shape","x":100,"y":100,"width":160,"height":40,"z_index":10,
"composite_shape":{"type":"round_rect"},
"text":{"text":"服务 A","font_size":14,"font_weight":"regular","horizontal_align":"center","vertical_align":"mid"},
"style":{"fill_color":"#FFFFFF","fill_opacity":100,"border_style":"solid","border_color":"#1446C2","border_width":"medium","border_opacity":100}},
{"type":"composite_shape","x":400,"y":100,"width":160,"height":40,"z_index":10,
"composite_shape":{"type":"round_rect"},
"text":{"text":"服务 B","font_size":14,"font_weight":"regular","horizontal_align":"center","vertical_align":"mid"},
"style":{"fill_color":"#FFFFFF","fill_opacity":100,"border_style":"solid","border_color":"#0C6800","border_width":"medium","border_opacity":100}}
]
EOF
feishu-cli board create-notes $BOARD_ID /tmp/shapes.json -o json
# → {"node_ids":["o1:1","o1:2"]}
# 3. 写 connectors.json(再连线,引用上面的 node_ids)
cat > /tmp/connectors.json << 'EOF'
[
{"type":"connector","width":1,"height":1,"z_index":50,
"connector":{"shape":"polyline",
"start":{"arrow_style":"none","attached_object":{"id":"o1:1","position":{"x":1,"y":0.5},"snap_to":"right"}},
"end":{"arrow_style":"triangle_arrow","attached_object":{"id":"o1:2","position":{"x":0,"y":0.5},"snap_to":"left"}}},
"style":{"border_color":"#BBBFC4","border_opacity":100,"border_style":"solid","border_width":"narrow"}}
]
EOF
feishu-cli board create-notes $BOARD_ID /tmp/connectors.json -o json
Reference materials
- Node JSON Schema:
references/schema.md - Layout strategies:
references/layout.md(layered bands / row-column alignment / island style / tree structure) - Color system:
references/style.md(unified palette usage method + 5 theme variants + structural rules) - Connector strategies:
references/connectors.md(snap_to / shape / spacing) - Typography rules:
references/typography.md(font size hierarchy) - Information planning:
references/content.md(information volume reference)
Full command quick reference
| Command | Function | Key parameters |
|---|---|---|
feishu-cli doc add-board <doc_id> |
Add a canvas block in the document | --parent-id(parent block ID, default root level)--index(insert position, -1=end)-o json |
feishu-cli board nodes <board_id> |
Pull all nodes | None |
feishu-cli board image <board_id> out.png |
Download canvas thumbnail | None |
feishu-cli board create-notes <board_id> nodes.json |
Batch create nodes | --source-type --client-token |
feishu-cli board import <board_id> diagram.mmd --syntax mermaid |
Path A: Server-side rendering | --engine [server|local] --diagram-type --style --dry-run |
feishu-cli board svg-import <board_id> drawing.svg |
Path D: Single svg node | --x --y --width --height --source-type --dry-run |
python3 svg_to_board.py drawing.svg <board_id> |
Path C: 5-step pipeline | --viewbox WxH(override the SVG's own viewBox, default auto-parse)--keep-overflow(do not clip overflowing nodes)--batch(default 300)--interval(default 0.3s)--dry-run |
feishu-cli board update <board_id> nodes.json |
Update canvas (overwrite mode) | --overwrite --snapshot --dry-run --stdin |
feishu-cli board delete <board_id> --all |
Delete all nodes | --node-ids |
feishu-cli board clone <src> <dst> |
Clone canvas | --batch-size --interval --filter-types --dry-run |
feishu-cli board upload-image <board_id> photo.png |
Convert image to image node | --x --y --width --height --dry-run |
feishu-cli board lint <board_id> |
Geometry quality check | None |
feishu-cli board export-code <board_id> |
Reverse export SVG | --output-path --merge |
For the detailed internal behavior of each command, see the corresponding code:cmd/board_*.go。
Three fatal pitfalls (quick reference)
In practice, the three easiestpitfalls to fall into are all described in references/pitfalls.md with detailed troubleshooting:
Pitfall 1: z_index disorder ⭐⭐⭐
- Symptom: large backgrounds obscure foreground elements, making the canvas visually chaotic
- Root cause: whiteboard-cli output nodes do not carry z_index, and Feishu's automatic assignment is out of order
- Fix: before uploading, explicitly assign by array index
z_index = i - One-click fix:
scripts/svg_to_board.pybuilt into Step 2
Pitfall 2: viewBox overflow ⭐⭐
- Symptom: a strange "half building" shape in the lower-right corner
- Root cause: node
x + width > viewBox_w - Fix: filter / truncate overflowing nodes before upload
- One-click fix:
scripts/svg_to_board.pyStep 3 built-in
Pitfall 3: Node duplication ⭐⭐
- Symptom: after clearing and re-uploading, node count ×2
- Root cause: script stdout parsing fails but API already succeeded → re-upload causes duplication
- Fix: treat rc=0 as success, and if already duplicated,
board delete --allthen re-upload - One-click fix:
scripts/svg_to_board.pyStep 4 fault-tolerant parsing built-in
Key constraints quick reference table
- Shapes first, then connections: connectors reference shape nodes by ID, so shapes must be created before connections can be created
- Minimal field set: extra fields trigger
2890002 invalid arg, only usereferences/schema.mdthe safe fields listed - Background color block fill_opacity ≤ 25: otherwise it completely blocks the layer above
- z_index layering: background 0-1, secondary 2-3, regular nodes 10, connections 50
- Coordinate system uses absolute coordinates: manually written nodes must have x/y/width/height calculated by hand (path E)
- Node text brief: title + brief description (< 12 characters), no long paragraphs
- Same-group nodes visually consistent: same group uses the same
fill_color / border_color - Node count upper limit: when a single board has > 2000 nodes, the editor starts to lag; consider splitting the diagram or simplifying
- Color values taken from the unified palette: group/series colors are used in order by
references/style.mdused in order, do not invent, do not cycle; only when changing color values/background colors do you need to run thefeishu-cli-datavizvalidator (the default palette is already pre-validated)
Symptom → Fix reference table
| Problem seen | What to change | See details |
|---|---|---|
| Text truncated / overflowing | Increase width or height, or shorten the text | references/typography.md |
| Nodes overlapping and sticking together | Increase node spacing (same layer ≥ 30px, with connections ≥ 60px) | references/layout.md |
| Background color block blocks nodes | Lower fill_opacity (≤ 25), confirm z_index layering | references/schema.md |
| Connections passing through nodes | Adjust snap_to direction or increase spacing | references/connectors.md |
| Large background instead covers the foreground | z_index out of order → assign explicitly | references/pitfalls.md ⭐ |
| "half-cut building" in the bottom-right corner | viewBox overflow → trim | references/pitfalls.md ⭐ |
| Node count doubled / colors darkened | re-upload causes duplication → board delete --all then re-upload |
references/pitfalls.md ⭐ |
| Text and background color too close | Adjust fill_color or text.text_color, ensure contrast | references/style.md |
| Grouping cannot be seen | Same group uses the same color, switch colors across groups | references/style.md |
| Data series colors hard to distinguish (color blindness/projection) | Change series colors to be taken in unified palette order and run the validator | feishu-cli-dataviz |
| Unsure whether to draw bar/line/pie | Choose the form based on the data task, not the user's spoken chart name | feishu-cli-dataviz |
2890002 invalid arg |
Contains extra fields (read-only fields such as id/locked/children) | references/schema.md |
| Mermaid server-side error | Switch --engine local or modify SVG |
references/mermaid-engines.md |
End-to-end verification checklist
After placing on the board, check item by item:
- Thumbnail main elements are all present:
feishu-cli board image <id> /tmp/check.png - Node count matches:
feishu-cli board nodes <id> | jq '.data.nodes | length' - The smallest z_index is the large background: see
references/pitfalls.mdGeneral diagnostics Step 2 - viewBox has no overflow:
max(x+w) ≤ viewBox_w - lint quality score ≥ 0.85:
feishu-cli board lint <id>
If any item fails, go back to references/pitfalls.md for troubleshooting.
Reference documentation index
| File | When to read |
|---|---|
references/svg-workflow.md |
Required reading when taking path C (5-step pipeline details + translation mapping table) |
references/mermaid-engines.md |
Required reading when taking path A/B (server-side vs local engine selection) |
references/pitfalls.md |
⭐ Required reading for hands-on work (troubleshooting the three major pitfalls: z_index / viewBox / doubling) |
references/examples-real.md |
Design reference (patterns from 14 hands-on diagrams + SVG elements + node density) |
references/schema.md |
Required reading when taking path E (authoritative reference for node JSON) |
references/layout.md |
Required reading when taking path E (5 layout strategies + spacing rules) |
references/style.md |
Color reference for paths C/E (how to use the unified palette + 5 theme variants) |
references/connectors.md |
Reference when using connectors (snap_to / shape selection) |
references/typography.md |
Typography reference (font size hierarchy) |
references/content.md |
Information density planning (avoid overload) |
references/node-api.md |
API endpoint details, error code troubleshooting, typical workflows |
One-sentence summary
| User description | Command |
|---|---|
| "Draw a growth flywheel / fishbone / Dashboard" | python3 svg_to_board.py drawing.svg $BOARD |
| "Put this mermaid onto the canvas" | feishu-cli board import $BOARD diagram.mmd --syntax mermaid |
| "mermaid server-side failure / too complex" | Add --engine local |
| "Upload a small icon / stamp" | feishu-cli board svg-import $BOARD icon.svg |
| "Fine-tune the architecture diagram, each node needs to be manually positioned" | Handwrite nodes.json + feishu-cli board create-notes |
| "Clone this canvas" | feishu-cli board clone <src> <dst> |
| "Put this image onto the canvas" | feishu-cli board upload-image $BOARD photo.png |
| "Check canvas quality" | feishu-cli board lint $BOARD |
| "Pull the SVG in the canvas back locally" | feishu-cli board export-code $BOARD --output-path design.svg --merge |