visual-planner by b-open-io/gemskills
npx skills add https://github.com/b-open-io/gemskills --skill visual-planner使用 tldraw 的 .tldr 格式创建可视化工作流图表。涵盖智能体编排、数据管道、系统架构以及任何多步骤流程。图表在基于 tldraw React 组件构建的游乐场应用中打开——无需 iframe,无需外部服务。
可视化规划器直接生成 .tldr 文件。tldraw 作为 npm 包(bun add tldraw)嵌入到我们的游乐场应用中——这是一个具有完整编程 API 访问权限的 React 组件。
visual-planner/
├── SKILL.md # 本文件
├── assets/
│ ├── supervisor.tldr # 模板图表
│ ├── hierarchical.tldr
│ └── pipeline.tldr
├── scripts/
│ ├── create_diagram.ts # 无头模式:根据描述生成 .tldr
│ ├── render_svg.ts # .tldr → 精美 SVG 导出
│ ├── validate.ts # 验证 .tldr 中的规划形状
│ ├── stats.ts # 来自 .tldr 的 KPI 摘要
│ └── playground_server.ts # 启动游乐场(tldraw + 规划 UI)
├── playground/ # 基于 tldraw 的画布应用
│ ├── package.json # tldraw + 最小依赖
│ └── src/
│ ├── shapes/PlannerNodeShape.ts # 带有阶段/智能体/工具的自定义形状
│ └── components/ # KPIBar, PlanningPanel, AgentBridge
└── references/
├── tldraw-format.md # 完整的 .tldr 模式参考
├── tldraw-mcp.md # MCP 内部原理,聚焦形状格式
├── workflow-patterns.md # 智能体编排模式
└── design-system.md # 规划视觉规范
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
开始前请阅读references/diagram-thinking.md。 糟糕图表的最大来源是跳过设计推理直接开始绘制形状。
在收集任何节点/边之前,定义此图表要回答的单一问题。如果问题包含“和”,则需要多个图表。
示例:
每个图表选择一个 C4 级别:
询问(一轮,然后生成):
planned、in_progress、implemented、needs_revision。在编写形状 JSON 之前:
references/design-system.md。note 形状记录上下文,如“30 分钟 TTL”、“使用 Claude Sonnet 4.6”、“需要重试逻辑”——不要把所有内容都塞进节点标签。对于智能体系统,检查节点是否映射到 bopen-tools 列表。当有明确匹配时,分配 agent 字段。
常见拓扑结构请参见 references/workflow-patterns.md,完整的设计推理指南请参见 references/diagram-thinking.md。
使用 create_diagram.ts 脚本将探索对话转换为 .tldr 文件。将文件放置在项目中:<project-dir>/docs/architecture/workflow.tldr。
该脚本处理所有困难部分:箭头绑定、richText 包装、来自 @tldraw/utils 的小数索引以及通过 dagre 的自动布局。你描述节点和边——工具生成正确的图表。
编写一个包含节点和边的聚焦形状 JSON 数组。使用 --layout auto 时可以省略 x/y:
[
{ "_type": "rectangle", "shapeId": "supervisor", "w": 200, "h": 80, "color": "violet", "fill": "solid", "text": "Supervisor" },
{ "_type": "rectangle", "shapeId": "worker_a", "w": 200, "h": 80, "color": "blue", "fill": "solid", "text": "Code Writer" },
{ "_type": "rectangle", "shapeId": "worker_b", "w": 200, "h": 80, "color": "blue", "fill": "solid", "text": "Reviewer" },
{ "_type": "arrow", "shapeId": "a1", "fromId": "supervisor", "toId": "worker_a", "color": "black", "text": "delegate" },
{ "_type": "arrow", "shapeId": "a2", "fromId": "supervisor", "toId": "worker_b", "color": "black", "text": "review" }
]
保存为 shapes.json。
bun run ${SKILL_DIR}/scripts/create_diagram.ts \
--input shapes.json \
--output <project-dir>/docs/architecture/workflow.tldr \
--layout auto \
--name "My Workflow"
--layout auto 标志运行 dagre(从上到下的 DAG 布局)并自动计算所有节点位置。每当图表有超过 2-3 个节点或你不想手动计算坐标时,请使用此选项。
当需要精确控制位置时,为每个形状提供 x/y 并使用 --layout manual(默认):
bun run ${SKILL_DIR}/scripts/create_diagram.ts \
--input shapes.json \
--output workflow.tldr
手动布局的间距常量:
| 元素 | 尺寸 |
|---|---|
| 节点宽度 | 200 像素 |
| 节点高度 | 80 像素 |
| 水平间距 | 150 像素 |
| 垂直间距 | 120 像素 |
| 框架内边距 | 40 像素 |
优先使用 kind: "arc" 箭头(默认)。仅当节点之间至少有 80 像素的间隙用于路由余量时,才使用 kind: "elbow"。
| 节点概念 | _type | color | fill | size |
|---|---|---|---|---|
| 监督者 / 主要节点 | rectangle | violet | solid | 220x80 |
| 工作者 | rectangle | blue | solid | 200x80 |
| 人工介入点 | diamond | yellow | solid | 160x100 |
| 工具/API/外部系统 | cloud | light-blue | solid | 200x80 |
| 决策点 | diamond | orange | solid | 160x100 |
| 起点 | ellipse | green | solid | 60x60 |
| 终点 | ellipse | red | solid | 60x60 |
| 注释 | note | yellow | — | 自动调整大小 |
| 独立标签 | text | black | — | 自动调整大小 |
| 外部系统(范围外) | rectangle | grey | semi | 160x60 |
使用虚线图案和颜色创建视觉层次结构:
| 关系 | dash | color | 使用时机 |
|---|---|---|---|
| 主要流程 | solid | black | 成功路径,主要请求流 |
| 条件分发 | dashed | black | 监督者路由到工作者 |
| 返回 / 响应 | dotted | grey | 工作者报告结果返回 |
| 错误 / 拒绝 | dashed | orange | 验证失败,循环返回 |
| 异步 / 事件驱动 | dashed | blue | 消息队列,webhooks |
| 监控 / 心跳 | dotted | light-blue | 健康检查,指标,定时任务 |
| 阶段 | color |
|---|---|
| 已规划 | grey |
| 进行中 | blue |
| 已实施 | green |
| 需要修订 | orange |
note / meta 中的规划元数据通过 note 字段(存储在 meta.note 中)传递规划特定数据,或使用原始 .tldr 直接嵌入 meta 键。note 字段是在聚焦格式中注释形状的最简单方式:
{ "_type": "rectangle", "shapeId": "supervisor", "w": 200, "h": 80, "color": "violet", "fill": "solid", "text": "Supervisor",
"note": "phase:in_progress | agent:orchestrator | model:claude-sonnet-4" }
将相关节点分组到框架中。在 children 数组中列出子形状 ID。使用 --layout auto 时,框架会自动调整大小以包含其子项:
[
{ "_type": "frame", "shapeId": "phase1", "name": "Phase 1: Setup", "children": ["setup_a", "setup_b"] },
{ "_type": "rectangle", "shapeId": "setup_a", "w": 200, "h": 80, "color": "blue", "fill": "solid", "text": "Task A" },
{ "_type": "rectangle", "shapeId": "setup_b", "w": 200, "h": 80, "color": "blue", "fill": "solid", "text": "Task B" }
]
有关箭头绑定内部原理、有效样式值和小数索引详细信息,请参见 references/tldraw-best-practices.md。
编写原始 .tldr 存储记录(非聚焦形状)时,避免以下错误:
框架形状需要在props中包含color。有效值:"black"、"grey"、"violet"、"blue"、"light-blue"、"yellow"、"orange"、"green"、"light-green"、"light-red"、"red"、"white"、"light-violet"。省略 color 会导致渲染时出现 ValidationError。
箭头start/end坐标不能为null。使用 { "x": 0, "y": 0 } 作为占位符——tldraw 根据绑定重新计算位置。设置为 null 会导致渲染器崩溃。
schema记录是必需的。每个 .tldr 文件必须包含一个顶层的 "schema" 对象,其中包含 schemaVersion: 2 和 sequences 映射。没有它,tldraw 会抛出 Cannot read properties of undefined (reading 'schemaVersion')。
富文本处理。带标签的形状需要 "richText": { "type": "doc", "content": [{ "type": "paragraph", "content": [{ "type": "text", "text": "Label" }] }] }。对于无标签箭头,完全省略 richText 键——不要使用空内容数组([])、空段落({ "type": "paragraph" })或仅包含空格的文本(" ")。所有这些都会导致“Empty text nodes are not allowed”错误。
框架中的子形状使用相对坐标。当 parentId 指向一个框架时,x 和 y 是相对于框架左上角的,而不是画布原点。
索引键必须是有效的小数索引字符串。tldraw 使用特定的小数索引格式。有效示例:"a1"、"a2"、"a1V"、"aD"、"aG"。无效:"b1"、"c2"、"d0"、"aK0"——索引不能以超过 "a" 的字母开头,并且不能以 "0" 结尾。使用顺序的 "a1" 到 ,然后是 到 ,然后是像 这样的双字符用于排序。不确定时,使用 、、 等。
始终使用"size": "s"(小字体)。中型和大型文本会很快溢出框,并且在架构图表中看起来杂乱。小字体是默认的可读性选择。
在节点之间留出充足的间距。连接的节点之间至少使用 120 像素的垂直间距,兄弟节点之间至少使用 60 像素的水平间距。为了可读性,框的尺寸至少为 240 宽 x 70 高。拥挤的图表比稍大一些的图表更难阅读——不确定时,增加更多空间。
每次编辑后验证 JSON。编写或编辑 .tldr 文件后,运行 python3 -m json.tool < file.tldr。使用 replace_all 进行增量编辑可能会损坏字符串字面量(例如,部分文本替换破坏引号)。在启动游乐场之前始终进行验证。
避免在.tldr文件上使用replace_all: true。它会在整个文件中匹配,并可能损坏恰好包含搜索文本的不相关字符串。使用具有足够周围上下文以确保唯一性的针对性编辑。
在启动游乐场之前,务必验证.tldr文件。 这可以在用户看到之前捕获崩溃。
bun run ${SKILL_DIR}/scripts/validate.ts <file.tldr>
验证器检查:
^a[0-9a-zA-Z]*[1-9a-zA-Z]$)在打开游乐场之前修复所有错误。警告是信息性的。
重要提示:游乐场是本技能的主要输出。生成 .tldr 文件后,务必启动游乐场。不要回退到渲染 SVG——整个重点是交互式的 tldraw 画布。
启动游乐场以交互方式查看和编辑图表:
bun run ${SKILL_DIR}/scripts/playground_server.ts --file <project-dir>/docs/architecture/workflow.tldr
依赖项在首次运行时自动安装。游乐场会自动在浏览器中打开。
游乐场提供:
.tldr 文件;然后用户告知智能体更改内容--wait-signal):将图表状态内联返回给等待的智能体.tldr 文件以进行完整编辑根据启动方式,游乐场显示不同的操作按钮:
正常模式(默认——无 --wait-signal):
右下角的按钮显示**“保存”**。点击它会将当前图表状态写回 .tldr 文件。会出现一个简短的“已保存到文件”确认。保存后,用户可以简单地告诉智能体:“我保存了我的更改”或“看起来对我没问题”,然后智能体可以重新读取 .tldr 文件以获取更新。
异步模式(--wait-signal —— 智能体等待回调):
右下角的按钮显示**“发送给智能体”**。点击它会将更新后的状态 POST 到 /api/signal,这会触发 playground_server.ts 监视器读取 .tldr 文件并将其内容内联返回给等待的智能体。然后服务器退出。这是用于计划-编辑-继续循环的智能体回调桥接。
该模式通过 playground_server.ts 在启动时使用 --wait-signal 设置的 NEXT_PUBLIC_WAIT_SIGNAL 环境变量检测。
SVG 导出可用,但不是主要输出。仅用于共享静态快照:
# 导出到 SVG(可选——仅用于静态共享)
bun run ${SKILL_DIR}/scripts/render_svg.ts --input workflow.tldr --output workflow.svg
# 获取 KPI 摘要
bun run ${SKILL_DIR}/scripts/stats.ts --input workflow.tldr
随着实施的进展,通过编辑 .tldr 文件或使用游乐场来更新节点阶段。阶段变化是设计和实施之间的主要反馈机制。
workflow.tldr,识别 planned 节点meta.phase 更新为 implemented,并将 color 更改为 green<project-dir>/docs/architecture/
├── workflow.tldr # 单一事实来源(.tldr 格式)
├── workflow.svg # 导出的 SVG(可选)
└── background.png # Gemini 生成的背景(可选)
.tldr 文件是单一事实来源。游乐场从中读取并写回。
对于编程式图表创建,请使用聚焦形状格式——一种比原始 .tldr 记录更容易生成的简化 JSON。create_diagram.ts 脚本接受聚焦形状并自动处理所有转换(绑定、富文本包装、ID 前缀)。
这与官方 tldraw MCP 使用的格式相同。完整的聚焦形状规范请参见 references/tldraw-mcp.md。
使用自动布局——无需坐标:
[
{ "_type": "rectangle", "shapeId": "supervisor", "w": 220, "h": 80, "color": "violet", "fill": "tint", "text": "Supervisor", "note": "Routes tasks to workers" },
{ "_type": "rectangle", "shapeId": "worker", "w": 200, "h": 80, "color": "blue", "fill": "tint", "text": "Worker" },
{ "_type": "arrow", "shapeId": "a1", "fromId": "supervisor", "toId": "worker", "color": "black", "text": "delegate" }
]
bun run ${SKILL_DIR}/scripts/create_diagram.ts --input shapes.json --output workflow.tldr --layout auto
与原始 .tldr 相比的关键简化:
fromId/toId —— 绑定自动创建(正确格式,正确的绑定记录)x1,y1,x2,y2 —— tldraw 根据绑定计算位置shape: 前缀--layout auto 时,忽略 x/y —— dagre 定位所有内容children 数组自动设置父子关系(或在手动模式下通过包含检测)references/diagram-thinking.md —— 首先阅读。 如何推理要绘制的内容:抽象级别、实体选择、视觉层次结构、信息密度、图例。设计入门。references/tldraw-best-practices.md —— 箭头绑定内部原理、dagre 布局用法、有效样式值、小数索引、richText 格式。在编程生成图表之前阅读此文件。references/tldraw-format.md —— 完整的 .tldr 模式:每种形状类型、绑定、富文本、样式枚举、布局模式以及一个工作示例references/tldraw-mcp.md —— 官方 tldraw MCP 的工作原理、聚焦形状格式规范、填充/颜色/几何映射。我们的技能提供等效功能,无需 MCP 服务器references/workflow-patterns.md —— 监督者、分层、管道、点对点和人工介入模式,以及布局建议references/design-system.md —— 规划视觉规范、阶段指示器、颜色系统每周安装次数
1
仓库
GitHub 星标
2
首次出现
1 天前
安全审计
已安装于
windsurf1
amp1
cline1
opencode1
cursor1
kimi-cli1
Create visual workflow diagrams using tldraw's .tldr format. Covers agent orchestration, data pipelines, system architecture, and any multi-step process. Diagrams open in a playground app built on the tldraw React component — no iframe, no external service.
The visual planner generates .tldr files directly. tldraw is embedded as an npm package (bun add tldraw) in our playground app — a React component with full programmatic API access.
visual-planner/
├── SKILL.md # This file
├── assets/
│ ├── supervisor.tldr # Template diagrams
│ ├── hierarchical.tldr
│ └── pipeline.tldr
├── scripts/
│ ├── create_diagram.ts # Headless: generate .tldr from description
│ ├── render_svg.ts # .tldr → polished SVG export
│ ├── validate.ts # Validate planning shapes in .tldr
│ ├── stats.ts # KPI summary from .tldr
│ └── playground_server.ts # Launch playground (tldraw + planning UI)
├── playground/ # tldraw-based canvas app
│ ├── package.json # tldraw + minimal deps
│ └── src/
│ ├── shapes/PlannerNodeShape.ts # Custom shape with phase/agent/tools
│ └── components/ # KPIBar, PlanningPanel, AgentBridge
└── references/
├── tldraw-format.md # Complete .tldr schema reference
├── tldraw-mcp.md # MCP internals, focused shape format
├── workflow-patterns.md # Agent orchestration patterns
└── design-system.md # Planning visual conventions
Readreferences/diagram-thinking.md before starting. The biggest source of bad diagrams is skipping the design reasoning and jumping straight to shapes.
Before gathering any nodes/edges, define the single question this diagram answers. If the question contains "and", you need multiple diagrams.
Examples:
Pick one C4 level per diagram:
Ask (one round, then generate):
planned, in_progress, implemented, needs_revision.Before writing shapes JSON:
references/design-system.md.note shapes for context like "30-min TTL", "Uses Claude Sonnet 4.6", "Needs retry logic" — don't cram everything into node labels.For agent systems, check if nodes map to the bopen-tools roster. Assign the agent field when there is a clear match.
See references/workflow-patterns.md for common topologies and references/diagram-thinking.md for the full design reasoning guide.
Translate the discovery conversation into a .tldr file using the create_diagram.ts script. Place the file in the project: <project-dir>/docs/architecture/workflow.tldr.
The script handles all the hard parts: arrow bindings, richText wrapping, fractional indices from @tldraw/utils, and auto-layout via dagre. You describe nodes and edges — the tooling produces a correct diagram.
Write a focused shapes JSON array with nodes and edges. You can omit x/y when using --layout auto:
[
{ "_type": "rectangle", "shapeId": "supervisor", "w": 200, "h": 80, "color": "violet", "fill": "solid", "text": "Supervisor" },
{ "_type": "rectangle", "shapeId": "worker_a", "w": 200, "h": 80, "color": "blue", "fill": "solid", "text": "Code Writer" },
{ "_type": "rectangle", "shapeId": "worker_b", "w": 200, "h": 80, "color": "blue", "fill": "solid", "text": "Reviewer" },
{ "_type": "arrow", "shapeId": "a1", "fromId": "supervisor", "toId": "worker_a", "color": "black", "text": "delegate" },
{ "_type": "arrow", "shapeId": "a2", "fromId": "supervisor", "toId": "worker_b", "color": "black", "text": "review" }
]
Save as shapes.json.
bun run ${SKILL_DIR}/scripts/create_diagram.ts \
--input shapes.json \
--output <project-dir>/docs/architecture/workflow.tldr \
--layout auto \
--name "My Workflow"
The --layout auto flag runs dagre (top-to-bottom DAG layout) and computes all node positions automatically. Use this whenever the diagram has more than 2-3 nodes or you don't want to compute coordinates manually.
When you need exact control over positions, provide x/y for every shape and use --layout manual (the default):
bun run ${SKILL_DIR}/scripts/create_diagram.ts \
--input shapes.json \
--output workflow.tldr
Spacing constants for manual layouts:
| Element | Size |
|---|---|
| Node width | 200 px |
| Node height | 80 px |
| Horizontal gap | 150 px |
| Vertical gap | 120 px |
| Frame padding | 40 px |
Prefer kind: "arc" arrows (the default). Only use kind: "elbow" when nodes have at least 80 px of gap for routing headroom.
| Node concept | _type | color | fill | size |
|---|---|---|---|---|
| Supervisor / Primary | rectangle | violet | solid | 220x80 |
| Worker | rectangle | blue | solid | 200x80 |
| Human-in-loop |
Use dash patterns and colors to create visual hierarchy:
| Relationship | dash | color | When to use |
|---|---|---|---|
| Primary flow | solid | black | Happy path, main request flow |
| Conditional dispatch | dashed | black | Supervisor routing to workers |
| Return / response | dotted | grey |
| Phase | color |
|---|---|
| Planned | grey |
| In Progress | blue |
| Implemented | green |
| Needs Revision | orange |
note / metaPass planning-specific data via the note field (stored in meta.note) or directly embed meta keys using raw .tldr. The note field is the simplest way to annotate shapes in focused format:
{ "_type": "rectangle", "shapeId": "supervisor", "w": 200, "h": 80, "color": "violet", "fill": "solid", "text": "Supervisor",
"note": "phase:in_progress | agent:orchestrator | model:claude-sonnet-4" }
Group related nodes into frames. List child shape IDs in the children array. With --layout auto, the frame is sized automatically to contain its children:
[
{ "_type": "frame", "shapeId": "phase1", "name": "Phase 1: Setup", "children": ["setup_a", "setup_b"] },
{ "_type": "rectangle", "shapeId": "setup_a", "w": 200, "h": 80, "color": "blue", "fill": "solid", "text": "Task A" },
{ "_type": "rectangle", "shapeId": "setup_b", "w": 200, "h": 80, "color": "blue", "fill": "solid", "text": "Task B" }
]
See references/tldraw-best-practices.md for arrow binding internals, valid style values, and fractional indexing details.
When writing raw .tldr store records (not focused shapes), avoid these errors:
Frame shapes requirecolor in props. Valid values: "black", "grey", "violet", "blue", "light-blue", "yellow", "orange", "green", "light-green", , , , . Omitting causes a at render time.
ALWAYS validate the.tldr file before launching the playground. This catches crashes before the user sees them.
bun run ${SKILL_DIR}/scripts/validate.ts <file.tldr>
The validator checks for:
^a[0-9a-zA-Z]*[1-9a-zA-Z]$)Fix all errors before opening the playground. Warnings are informational.
IMPORTANT: The playground is the primary output of this skill. ALWAYS launch the playground after generating a .tldr file. Do NOT fall back to rendering an SVG — the whole point is the interactive tldraw canvas.
Launch the playground to view and edit the diagram interactively:
bun run ${SKILL_DIR}/scripts/playground_server.ts --file <project-dir>/docs/architecture/workflow.tldr
Dependencies are auto-installed on first run. The playground opens in the browser automatically.
The playground provides:
.tldr file; user then tells the agent about changes--wait-signal): returns diagram state inline to the waiting agent.tldr file in standalone tldraw for full editingThe playground shows a different action button depending on how it was launched:
Normal mode (default — no --wait-signal):
The bottom-right button says "Save". Clicking it writes the current diagram state back to the .tldr file. A brief "Saved to file" confirmation appears. After saving, the user can simply tell the agent: "I saved my changes" or "it looks correct to me", and the agent can re-read the .tldr file to pick up the updates.
Async mode (--wait-signal — agent awaiting callback):
The bottom-right button says "Send to Agent". Clicking it POSTs the updated state to /api/signal, which triggers the playground_server.ts watcher to read the .tldr file and return its contents to the waiting agent inline. The server then exits. This is the agent callback bridge for plan-edit-continue loops.
The mode is detected via the NEXT_PUBLIC_WAIT_SIGNAL env var set by playground_server.ts when launched with --wait-signal.
SVG export is available but is NOT the primary output. Only use for sharing static snapshots:
# Export to SVG (optional — for static sharing only)
bun run ${SKILL_DIR}/scripts/render_svg.ts --input workflow.tldr --output workflow.svg
# Get KPI summary
bun run ${SKILL_DIR}/scripts/stats.ts --input workflow.tldr
As implementation progresses, update node phases by editing the .tldr file or using the playground. Phase changes are the primary feedback mechanism between design and implementation.
workflow.tldr, identifies planned nodesmeta.phase to implemented and changes color to green<project-dir>/docs/architecture/
├── workflow.tldr # Source of truth (.tldr format)
├── workflow.svg # Exported SVG (optional)
└── background.png # Gemini-generated background (optional)
The .tldr file is the source of truth. The playground reads from it and writes back to it.
For programmatic diagram creation, use the focused shape format — a simplified JSON that's much easier to generate than raw .tldr records. The create_diagram.ts script accepts focused shapes and handles all the conversion (bindings, rich text wrapping, ID prefixing) automatically.
This is the same format used by the official tldraw MCP. See references/tldraw-mcp.md for the complete focused shape spec.
With auto-layout — no coordinates needed:
[
{ "_type": "rectangle", "shapeId": "supervisor", "w": 220, "h": 80, "color": "violet", "fill": "tint", "text": "Supervisor", "note": "Routes tasks to workers" },
{ "_type": "rectangle", "shapeId": "worker", "w": 200, "h": 80, "color": "blue", "fill": "tint", "text": "Worker" },
{ "_type": "arrow", "shapeId": "a1", "fromId": "supervisor", "toId": "worker", "color": "black", "text": "delegate" }
]
bun run ${SKILL_DIR}/scripts/create_diagram.ts --input shapes.json --output workflow.tldr --layout auto
Key simplifications vs raw .tldr:
fromId/toId — bindings are auto-created (correct format, correct binding records)x1,y1,x2,y2 — tldraw computes position from bindingsshape: prefix--layout auto, x/y are ignored — dagre positions everythingchildren array (or containment detection in manual mode)references/diagram-thinking.md — Read first. How to reason about what to draw: abstraction levels, entity selection, visual hierarchy, information density, legends. The design primer.references/tldraw-best-practices.md — Arrow binding internals, dagre layout usage, valid style values, fractional indexing, richText format. Read this before generating diagrams programmatically.references/tldraw-format.md — Complete .tldr schema: every shape type, bindings, rich text, style enums, layout patterns, and a working examplereferences/tldraw-mcp.md — How the official tldraw MCP works, focused shape format spec, fill/color/geo mappings. Our skill provides equivalent functionality without requiring the MCP serverreferences/workflow-patterns.md — Supervisor, hierarchical, pipeline, peer-to-peer, and human-in-loop patterns with layout recommendationsreferences/design-system.md — Planning visual conventions, phase indicators, color systemWeekly Installs
1
Repository
GitHub Stars
2
First Seen
1 day ago
Security Audits
Gen Agent Trust HubWarnSocketPassSnykPass
Installed on
windsurf1
amp1
cline1
opencode1
cursor1
kimi-cli1
API设计指南:REST/GraphQL设计原则、规范文档与版本控制策略
11,500 周安装
"a9""aA""aZ""a1V""a1""a2""a3"diamond |
yellow |
solid |
| 160x100 |
| Tool/API/External | cloud | light-blue | solid | 200x80 |
| Decision | diamond | orange | solid | 160x100 |
| Start | ellipse | green | solid | 60x60 |
| End | ellipse | red | solid | 60x60 |
| Annotation | note | yellow | — | auto-sized |
| Standalone label | text | black | — | auto-sized |
| External system (out of scope) | rectangle | grey | semi | 160x60 |
| Worker reporting results back |
| Error / rejection | dashed | orange | Failed validation, loop-back |
| Async / event-driven | dashed | blue | Message queue, webhooks |
| Monitoring / heartbeat | dotted | light-blue | Health checks, metrics, crons |
"light-red""red""white""light-violet"colorValidationErrorArrowstart/end coordinates must not be null. Use { "x": 0, "y": 0 } as placeholder — tldraw recomputes positions from bindings. Setting null crashes the renderer.
Theschema record is required. Every .tldr file must include a top-level "schema" object with schemaVersion: 2 and the sequences map. Without it, tldraw throws Cannot read properties of undefined (reading 'schemaVersion').
Rich text handling. Labeled shapes need "richText": { "type": "doc", "content": [{ "type": "paragraph", "content": [{ "type": "text", "text": "Label" }] }] }. For unlabeled arrows , omit the richText key entirely — do NOT use empty content arrays ([]), empty paragraphs ({ "type": "paragraph" }), or space-only text (" "). All of these cause "Empty text nodes are not allowed" errors.
Child shapes in frames use relative coordinates. When parentId points to a frame, x and y are relative to the frame's top-left corner, not the canvas origin.
Index keys must be valid fractional index strings. tldraw uses a specific fractional indexing format. Valid examples: "a1", "a2", "a1V", "aD", "aG". Invalid : "b1", "c2", "d0", "aK0" — indices must not start with letters beyond "a" and must not end with "0". Use sequential "a1" through "a9", then "aA" through "aZ", then two-char like "a1V" for ordering. When in doubt, use "a1", "a2", "a3", etc.
Always use"size": "s" (small font). Medium and large text overflow boxes quickly and look cluttered in architecture diagrams. Small is the default for readability.
Give generous spacing between nodes. Use at least 120px vertical gap between connected nodes and 60px horizontal gap between siblings. Make boxes at least 240w x 70h for readability. Cramped diagrams are harder to read than slightly larger ones — when in doubt, add more space.
Validate JSON after every edit. Run python3 -m json.tool < file.tldr after writing or editing .tldr files. Incremental edits with replace_all can corrupt string literals (e.g., partial text replacement breaking quotes). Always validate before launching the playground.
Avoidreplace_all: true on .tldr files. It matches across the entire file and can corrupt unrelated strings that happen to contain the search text. Use targeted edits with enough surrounding context to be unique.