json-canvas
💡 摘要
该技能使AI代理能够以编程方式创建和编辑用于Obsidian中视觉知识映射的JSON Canvas文件。
🎯 适合人群
🤖 AI 吐槽: “这不过是个华丽的JSON格式化工具,让你的AI感觉像个调像素的实习生。”
风险包括通过'file'和'background'节点属性进行文件系统路径遍历,以及链接节点('url')可能包含恶意内容。缓解措施:在处理前,对所有用户提供的文件路径和URL进行清理和验证。
name: json-canvas description: Create and edit JSON Canvas files (.canvas) with nodes, edges, groups, and connections. Use when working with .canvas files, creating visual canvases, mind maps, flowcharts, or when the user mentions Canvas files in Obsidian.
JSON Canvas Skill
This skill enables skills-compatible agents to create and edit valid JSON Canvas files (.canvas) used in Obsidian and other applications.
Overview
JSON Canvas is an open file format for infinite canvas data. Canvas files use the .canvas extension and contain valid JSON following the JSON Canvas Spec 1.0.
File Structure
A canvas file contains two top-level arrays:
{ "nodes": [], "edges": [] }
nodes(optional): Array of node objectsedges(optional): Array of edge objects connecting nodes
Nodes
Nodes are objects placed on the canvas. There are four node types:
text- Text content with Markdownfile- Reference to files/attachmentslink- External URLgroup- Visual container for other nodes
Z-Index Ordering
Nodes are ordered by z-index in the array:
- First node = bottom layer (displayed below others)
- Last node = top layer (displayed above others)
Generic Node Attributes
All nodes share these attributes:
| Attribute | Required | Type | Description |
|-----------|----------|------|-------------|
| id | Yes | string | Unique identifier for the node |
| type | Yes | string | Node type: text, file, link, or group |
| x | Yes | integer | X position in pixels |
| y | Yes | integer | Y position in pixels |
| width | Yes | integer | Width in pixels |
| height | Yes | integer | Height in pixels |
| color | No | canvasColor | Node color (see Color section) |
Text Nodes
Text nodes contain Markdown content.
{ "id": "6f0ad84f44ce9c17", "type": "text", "x": 0, "y": 0, "width": 400, "height": 200, "text": "# Hello World\n\nThis is **Markdown** content." }
| Attribute | Required | Type | Description |
|-----------|----------|------|-------------|
| text | Yes | string | Plain text with Markdown syntax |
File Nodes
File nodes reference files or attachments (images, videos, PDFs, notes, etc.).
{ "id": "a1b2c3d4e5f67890", "type": "file", "x": 500, "y": 0, "width": 400, "height": 300, "file": "Attachments/diagram.png" }
{ "id": "b2c3d4e5f6789012", "type": "file", "x": 500, "y": 400, "width": 400, "height": 300, "file": "Notes/Project Overview.md", "subpath": "#Implementation" }
| Attribute | Required | Type | Description |
|-----------|----------|------|-------------|
| file | Yes | string | Path to file within the system |
| subpath | No | string | Link to heading or block (starts with #) |
Link Nodes
Link nodes display external URLs.
{ "id": "c3d4e5f678901234", "type": "link", "x": 1000, "y": 0, "width": 400, "height": 200, "url": "https://obsidian.md" }
| Attribute | Required | Type | Description |
|-----------|----------|------|-------------|
| url | Yes | string | External URL |
Group Nodes
Group nodes are visual containers for organizing other nodes.
{ "id": "d4e5f6789012345a", "type": "group", "x": -50, "y": -50, "width": 1000, "height": 600, "label": "Project Overview", "color": "4" }
{ "id": "e5f67890123456ab", "type": "group", "x": 0, "y": 700, "width": 800, "height": 500, "label": "Resources", "background": "Attachments/background.png", "backgroundStyle": "cover" }
| Attribute | Required | Type | Description |
|-----------|----------|------|-------------|
| label | No | string | Text label for the group |
| background | No | string | Path to background image |
| backgroundStyle | No | string | Background rendering style |
Background Styles
| Value | Description |
|-------|-------------|
| cover | Fills entire width and height of node |
| ratio | Maintains aspect ratio of background image |
| repeat | Repeats image as pattern in both directions |
Edges
Edges are lines connecting nodes.
{ "id": "f67890123456789a", "fromNode": "6f0ad84f44ce9c17", "toNode": "a1b2c3d4e5f67890" }
{ "id": "0123456789abcdef", "fromNode": "6f0ad84f44ce9c17", "fromSide": "right", "fromEnd": "none", "toNode": "b2c3d4e5f6789012", "toSide": "left", "toEnd": "arrow", "color": "1", "label": "leads to" }
| Attribute | Required | Type | Default | Description |
|-----------|----------|------|---------|-------------|
| id | Yes | string | - | Unique identifier for the edge |
| fromNode | Yes | string | - | Node ID where connection starts |
| fromSide | No | string | - | Side where edge starts |
| fromEnd | No | string | none | Shape at edge start |
| toNode | Yes | string | - | Node ID where connection ends |
| toSide | No | string | - | Side where edge ends |
| toEnd | No | string | arrow | Shape at edge end |
| color | No | canvasColor | - | Line color |
| label | No | string | - | Text label for the edge |
Side Values
| Value | Description |
|-------|-------------|
| top | Top edge of node |
| right | Right edge of node |
| bottom | Bottom edge of node |
| left | Left edge of node |
End Shapes
| Value | Description |
|-------|-------------|
| none | No endpoint shape |
| arrow | Arrow endpoint |
Colors
The canvasColor type can be specified in two ways:
Hex Colors
{ "color": "#FF0000" }
Preset Colors
{ "color": "1" }
| Preset | Color |
|--------|-------|
| "1" | Red |
| "2" | Orange |
| "3" | Yellow |
| "4" | Green |
| "5" | Cyan |
| "6" | Purple |
Note: Specific color values for presets are intentionally undefined, allowing applications to use their own brand colors.
Complete Examples
Simple Canvas with Text and Connections
{ "nodes": [ { "id": "8a9b0c1d2e3f4a5b", "type": "text", "x": 0, "y": 0, "width": 300, "height": 150, "text": "# Main Idea\n\nThis is the central concept." }, { "id": "1a2b3c4d5e6f7a8b", "type": "text", "x": 400, "y": -100, "width": 250, "height": 100, "text": "## Supporting Point A\n\nDetails here." }, { "id": "2b3c4d5e6f7a8b9c", "type": "text", "x": 400, "y": 100, "width": 250, "height": 100, "text": "## Supporting Point B\n\nMore details." } ], "edges": [ { "id": "3c4d5e6f7a8b9c0d", "fromNode": "8a9b0c1d2e3f4a5b", "fromSide": "right", "toNode": "1a2b3c4d5e6f7a8b", "toSide": "left" }, { "id": "4d5e6f7a8b9c0d1e", "fromNode": "8a9b0c1d2e3f4a5b", "fromSide": "right", "toNode": "2b3c4d5e6f7a8b9c", "toSide": "left" } ] }
Project Board with Groups
{ "nodes": [ { "id": "5e6f7a8b9c0d1e2f", "type": "group", "x": 0, "y": 0, "width": 300, "height": 500, "label": "To Do", "color": "1" }, { "id": "6f7a8b9c0d1e2f3a", "type": "group", "x": 350, "y": 0, "width": 300, "height": 500, "label": "In Progress", "color": "3" }, { "id": "7a8b9c0d1e2f3a4b", "type": "group", "x": 700, "y": 0, "width": 300, "height": 500, "label": "Done", "color": "4" }, { "id": "8b9c0d1e2f3a4b5c", "type": "text", "x": 20, "y": 50, "width": 260, "height": 80, "text": "## Task 1\n\nImplement feature X" }, { "id": "9c0d1e2f3a4b5c6d", "type": "text", "x": 370, "y": 50, "width": 260, "height": 80, "text": "## Task 2\n\nReview PR #123", "color": "2" }, { "id": "0d1e2f3a4b5c6d7e", "type": "text", "x": 720, "y": 50, "width": 260, "height": 80, "text": "## Task 3\n\n~~Setup CI/CD~~" } ], "edges": [] }
Research Canvas with Files and Links
{ "nodes": [ { "id": "1e2f3a4b5c6d7e8f", "type": "text", "x": 300, "y": 200, "width": 400, "height": 200, "text": "# Research Topic\n\n## Key Questions\n\n- How does X affect Y?\n- What are the implications?", "color": "5" }, { "id": "2f3a4b5c6d7e8f9a", "type": "file", "x": 0, "y": 0, "width": 250, "height": 150, "file": "Literature/Paper A.pdf" }, { "id": "3a4b5c6d7e8f9a0b", "type": "file", "x": 0, "y": 200, "width": 250, "height": 150, "file": "Notes/Meeting Notes.md", "subpath": "#Key Insights" }, { "id": "4b5c6d7e8f9a0b1c", "type": "link", "x": 0, "y": 400, "width": 250, "height": 100, "url": "https://example.com/research" }, { "id": "5c6d7e8f9a0b1c2d", "type": "file", "x": 750, "y": 150, "width": 300, "height": 250, "file": "Attachments/diagram.png" } ], "edges": [ { "id": "6d7e8f9a0b1c2d3e", "fromNode": "2f3a4b5c6d7e8f9a", "fromSide": "right", "toNode": "1e2f3a4b5c6d7e8f", "toSide": "left", "label": "supports" }, { "id": "7e8f9a0b1c2d3e4f", "fromNode": "3a4b5c6d7e8f9a0b", "fromSide": "right", "toNode": "1e2f3a4b5c6d7e8f", "toSide": "left", "label": "informs" }, { "id": "8f9a0b1c2d3e4f5a", "fromNode": "4b5c6d7e8f9a0b1c", "fromSide": "right", "toNode": "1e2f3a4b5c6d7e8f", "toSide": "left", "toEnd": "arrow", "color": "6" }, { "id": "9a0b1c2d3e4f5a6b", "fromNode": "1e2f3a4b5c6d7e8f", "fromSide": "right", "toNode": "5c6d
优点
- 为可视化画布格式提供了结构化的、程序化的访问方式。
- 文档完善,示例清晰,遵循规范。
- 支持自动化创建复杂的视觉布局和连接。
缺点
- 实用性紧密依赖于小众的Obsidian Canvas生态系统。
- 没有直接的可视化预览;输出是原始JSON。
- 作为现有文件格式的封装,新颖性有限。
相关技能
免责声明:本内容来源于 GitHub 开源项目,仅供展示和评分分析使用。
版权归原作者所有 kepano.
