关于 superplane-canvas-builder
superplane-canvas-builder 是将工作流需求转换为 SuperPlane canvas YAML 的技能。它指导通过 CLI 核实集成、触发器、动作、架构和资源值,再创建或更新画布。
主要功能
- 01将工作流需求转为画布 YAML
- 02通过 CLI 查找触发器和动作
- 03核实集成与资源值
- 04图连接和节点定位指南
- 05表达式与载荷验证
适用场景
- 01按工作流说明构建画布
- 02生成 YAML 前检查集成
- 03根据执行载荷验证表达式
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ superplanehq/ skills --skill superplane-canvas-builder安装后在 Claude Code 中输入/superplane-canvas-builder确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/components-and-triggers.mddaytona.mdgithub.mdsentry.md详细介绍
SuperPlane Canvas 构建器
将工作流需求转换为 SuperPlane canvas YAML。
快速参考
| 任务 | 命令 |
|---|---|
| 列出操作 | superplane index actions |
| 列出集成提供的操作 | superplane index actions --from <integration> |
| 描述操作 | superplane index actions --name <name> |
| 列出触发器 | superplane index triggers --from <integration> |
| 生成初始 YAML | superplane canvases init |
| 创建 canvas | superplane canvases create --file canvas.yaml |
| 更新 canvas | superplane canvases update <name-or-id> --draft -f canvas.yaml |
操作顺序
始终遵循此顺序。CLI 是首选方式——它能提供文档无法可靠替代的准确名称、ID 和架构。
1. 验证 CLI 并连接
command -v superplane
如果没有打印路径:停止。告知用户从 https://docs.superplane.com/installation/cli 安装 CLI,然后重新运行任务。不要代替用户安装。不要悄悄改用基于文档的设计。
然后验证当前会话:
superplane whoami
如果 whoami 因身份验证、DNS、超时或连接问题而失败,则表示 CLI 已安装,但当前会话尚不可用。根据需要,请用户连接、修复上下文或允许网络访问。没有可用的 CLI 会话时,不要继续。
如果尚未连接:
superplane connect <URL> <TOKEN>
superplane whoami
如果没有连接详情:停止,请用户连接,或提供所需的 URL 和令牌。没有可用的 CLI 会话时,不要继续。
1b. 将更改作为草稿应用
此环境始终启用版本控制。跳过模式检测,并在每条 superplane canvases update 命令中使用 --draft。
superplane canvases update <name-or-id> --draft --file canvas.yaml
2. 了解工作流
运行发现命令之前,先确定工作流的需求:
- 什么会启动它? → 触发器(计划任务、webhook、GitHub 推送、手动触发)
- 需要执行哪些步骤? → 每个步骤都是一个操作节点
- 是否需要做决策? → 使用 If 或 Filter 操作进行分支
- 是否需要等待? → Approval、Time Gate、Wait 操作
- 涉及哪些外部系统? → 每个系统都对应一个提供方(例如 GitHub、Slack、Daytona)
根据此分析收集所需提供方列表——下一步会检查这些提供方。
3. 发现并验证集成
运行 superplane integrations list,获取组织中已连接的所有集成。将其与第 2 步所需的提供方进行比较。
如果缺少任何所需的提供方: 停止,并在编写任何 YAML 之前告知用户。例如:
此 canvas 需要 GitHub 和 Daytona 集成。您的组织已连接 GitHub,但尚未连接 Daytona。请先在 SuperPlane UI 中连接 Daytona(Settings → Integrations)。
不要生成引用了组织尚未连接的提供方的 YAML——每个受影响的节点都会因“integration is required”而失败。
确认所有提供方均已连接后,发现准确名称和架构:
superplane integrations list # connected instances → real integration IDs
superplane index triggers --from <provider> # exact trigger names
superplane index actions --from <provider> # exact action names
检查必需的配置字段、输出通道和负载结构:
superplane index triggers --name github.onPush --output json
superplane index actions --name semaphore.runWorkflow --output json
列出 integration-resource 字段的运行时选项:
superplane integrations list-resources --id <id> --type <type>
编写或应用 YAML 前的硬性检查: 对于设置的每个 integration-resource 字段值(例如:repository、snapshot、sandbox、project),请确认该值准确存在于对应集成的 list-resources 输出中。如果不存在,请停止并询问用户应使用哪个有效值。
架构优先级规则: 如果提供方参考示例与 CLI 架构输出(superplane index ... --output json)或当前 list-resources 值不一致,请以 CLI 输出为准。参考资料仅供辅助;CLI 才是事实来源。
4. 选择操作并连接图
使用第 3 步中的确切触发器和操作名称,不要凭文档猜测。
- 如果触发器支持内置筛选(内容筛选器、操作筛选器、ref 筛选器),请在触发器级别配置。只有当触发器的原生配置无法表达所需逻辑时,才添加单独的 Filter 或 If 节点。
- 每个操作都至少需要一条入边
- 触发器没有入边
- 使用命名通道进行分支(If →
true/false,Approval →approved/rejected) - Filter 仅在表达式为 true 时向
default输出;false 事件会静默停止 - 使用 Merge 汇入并行分支
完整列表请参阅 组件与触发器参考。
5. 放置节点
每个节点都需要一个 position: { x, y }。节点尺寸为 515px × 215px,请按以下间距规则放置,以避免重叠:
| 方向 | 增量 | 原因 |
|---|---|---|
| 水平(x) | 每列 +600px | 515 宽度 + 85 间距 |
| 垂直(y) | 每行 +300px | 215 高度 + 85 间距 |
将第一个节点(触发器)放在 { x: 120, y: 100 }。
线性管道 — y 相同,x 递增:
Trigger: { x: 120, y: 100 } → Step A: { x: 720, y: 100 } → Step B: { x: 1320, y: 100 }
分支 — 各分支共用同一 x 列,沿 y 方向展开。将源节点垂直居中,使其与各分支对齐:
┌─ Branch A: { x: 1320, y: 100 }
Source: { x: 720, y: 250 } ───┤
└─ Branch B: { x: 1320, y: 400 }
汇入(Merge) — 放在分支之后的下一 x 列,y 坐标取各分支之间的中心位置:
Branch A: { x: 1320, y: 100 } ──┐
├── Merge: { x: 1920, y: 250 }
Branch B: { x: 1320, y: 400 } ──┘
对于 3 个或更多分支,每个分支的 y 坐标都递增 300,并相应调整源节点和 Merge 节点的位置,使其居中。
6. 配置表达式
暂停。 在确认载荷字段之前,不要编写引用这些字段的表达式。不要根据触发器或操作名称猜测字段路径。
信封
每个节点的输出都封装在一个信封中:{ data: {...}, timestamp, type }。以下三种访问模式都会返回此信封,因此要访问实际载荷,始终需要 .data.:
| 模式 | 说明 |
|---|---|
$['Node Name'].data.field | 按名称访问任意上游节点的输出 |
root().data.field | 访问启动本次运行的根事件 |
previous().data.field | 访问直接上游节点的输出 |
常见错误: 写成
$['Create Sandbox'].id,而不是$['Create Sandbox'].data.id。始终包含.data.。
重要 — 示例载荷已经包含信封。
superplane index triggers --name <trigger>打印的示例载荷(以及本技能参考文件中展示的示例载荷)就是完整信封:最外层为{ data: {...}, timestamp, type }。root().data会返回顶层data对象,因此不要在其后再添加一个.data。构建正确的表达式时,请直接统计示例 JSON 中的data键:需要遍历多少层嵌套的data键,就添加多少个.data,不要多加。嵌套的
data键。 某些 webhook(尤其是 Sentry)会在载荷正文中包含自己的data字段。因此,正确路径有两个.data片段,即root().data.data.issue.title,而不是三个。root().data已经解开了信封;第二个.data才是访问 webhook 自带的data字段。如果你发现自己写出了root().data.data.data.…,说明你重复计算了信封。
在配置字段中使用双花括号 {{ }} 编写表达式:
{{ $['GitHub onPush'].data.ref }}
如何确认载荷字段
按以下顺序检查这些来源——使用第一个可用的来源:
-
现有执行记录 — 检查先前运行中的真实载荷(最可靠):
superplane executions list --canvas-id <id> --node-id <nid> -o yaml -
此技能中的提供商参考文件 — 在
references/目录中查找你所用提供商的文件。这些文件包含载荷示例和已知注意事项。 -
SuperPlane 文档 — 从面向大模型的文档中获取提供商的操作页面:
首次真实执行后,务必返回来源 1 验证并修正表达式。触发器名称与载荷结构并非一一对应——务必查阅提供商参考文件或文档,确认触发器实际对应的 webhook 事件。
6b. 命令节点最佳实践
当操作执行 shell 命令(例如 daytona.executeCommand、ssh)时:
- 使用操作原生的
workingDirectory/envVars配置,而不是在 shell 字符串中内联cd或export。这样可以减少引号处理的复杂性和故障面。 - 将冗长输出重定向到文件,并向 stdout 输出简短的状态标记(例如
STEP_OK/STEP_FAILED)。大量或二进制 stdout 可能导致节点处理问题。 - 查看提供商参考文件(
references/目录),了解该集成特有的 shell 执行模型、经过强化的命令模板和已知故障模式。 - 对于较长的多步骤脚本,优先使用 YAML 块标量(
command: |-),而不是折叠成单行字符串,以避免bash -lc解析时产生空格或换行问题。 - 发布前,手动运行一次触发器,并检查执行 YAML 中的节点
outputs,确认预期的通道路由(success与failed)与边的连接一致。
7. 应用
如果从头开始,请生成起始 YAML:
superplane canvases init --output-file canvas.yaml
# or start from a template:
superplane canvases init --template health-check-monitor --output-file canvas.yaml
然后从文件创建画布,或更新现有画布:
superplane canvases create --file canvas.yaml
# or update an existing canvas:
superplane canvases update <name-or-id> --draft --file canvas.yaml
从 YAML 创建新画布时,create --file 已会应用文件中的图:
superplane canvases create --file canvas.yaml
工作流规则:
superplane canvases create --file canvas.yaml接受规范中的资源式 Canvas YAML(apiVersion、kind、metadata、spec)。- 仅当你有意应用额外更改时,才在创建后运行
superplane canvases update ...,例如使用包含metadata.id的后续文件,或指定不同于 create 默认值的显式自动布局标志。 - 在此环境中,每条
superplane canvases update ...命令都应包含--draft。
然后进行验证:
superplane canvases get <name>
检查任何节点上是否存在 errorMessage 或 warningMessage。
8. 完成定义(画布创建)
在将画布标记为“就绪”之前,请确认以下所有事项:
- 已通过
superplane integrations list解析集成 ID - 已通过
superplane integrations list-resources验证每个integration-resource值 - 已根据预期的 YAML 载荷创建画布
superplane canvases get <name> -o yaml显示所有节点的errorMessage和warningMessage均为空- 至少检查过一次真实触发器运行,包括关键分支节点的通道级
outputs
常见模式
线性:触发器 → A → B → C
nodes:
- { id: trigger, ..., position: { x: 120, y: 100 } }
- { id: a, ..., position: { x: 720, y: 100 } }
- { id: b, ..., position: { x: 1320, y: 100 } }
- { id: c, ..., position: { x: 1920, y: 100 } }
edges:
- { sourceId: trigger, targetId: a, channel: default }
- { sourceId: a, targetId: b, channel: default }
- { sourceId: b, targetId: c, channel: default }
分支:If → true / false
nodes:
- { id: trigger, ..., position: { x: 120, y: 250 } }
- { id: check, ..., action: { name: if }, position: { x: 720, y: 250 } }
- { id: on-true, ..., position: { x: 1320, y: 100 } }
- { id: on-false, ..., position: { x: 1320, y: 400 } }
edges:
- { sourceId: trigger, targetId: check, channel: default }
- { sourceId: check, targetId: on-true, channel: true }
- { sourceId: check, targetId: on-false, channel: false }
门控:Filter(通过或停止)
Filter 仅在条件为 true 时向 default 发出事件。条件为 false 时,事件会停止——无需连接边。
nodes:
- { id: trigger, ..., position: { x: 120, y: 100 } }
- { id: filter, ..., action: { name: filter }, position: { x: 720, y: 100 } }
- { id: next-step, ..., position: { x: 1320, y: 100 } }
edges:
- { sourceId: trigger, targetId: filter, channel: default }
- { sourceId: filter, targetId: next-step, channel: default }
扇出 / 扇入
nodes:
- { id: trigger, ..., position: { x: 120, y: 250 } }
- { id: a, ..., position: { x: 720, y: 100 } }
- { id: b, ..., position: { x: 720, y: 400 } }
- { id: merge, ..., position: { x: 1320, y: 250 } }
- { id: final, ..., position: { x: 1920, y: 250 } }
edges:
- { sourceId: trigger, targetId: a, channel: default }
- { sourceId: trigger, targetId: b, channel: default }
- { sourceId: a, targetId: merge, channel: default }
- { sourceId: b, targetId: merge, channel: default }
- { sourceId: merge, targetId: final, channel: default }
审批门控
nodes:
- { id: ci-done, ..., position: { x: 120, y: 100 } }
- { id: timegate, ..., position: { x: 720, y: 100 } }
- { id: approval, ..., position: { x: 1320, y: 100 } }
- { id: deploy, ..., position: { x: 1920, y: 100 } }
edges:
- { sourceId: ci-done, targetId: timegate, channel: default }
- { sourceId: timegate, targetId: approval, channel: default }
- { sourceId: approval, targetId: deploy, channel: approved }
何时使用其他技能
| 需求 | 使用技能 |
|---|---|
| CLI 命令和身份验证 | superplane-cli |
| 调试失败的运行 | superplane-monitor |
文档
对于能够获取 URL 的 Agent,可通过面向大模型的格式获取完整的 SuperPlane 文档: