Files
yixiong-claude-marketplace/plugins/obsidian/skills/obsidian-canvas/SKILL.md
T
SkyJourney ff48dcf072 feat(obsidian): 新增 obsidian-canvas skill(JSON Canvas 1.0 视觉层)
对标 kepano/obsidian-skills 与 AgriciDaniel/claude-obsidian 的 canvas 模块:
Canvas 是 Obsidian 开放格式,独立于 Markdown 笔记体系,社区共识作为独立技能维护。

内容覆盖:
- JSON Canvas 1.0 schema 速查(4 种 node + edges)
- 16 字符 hex ID 生成规范(Bash/Python 双实现)
- 直接 Read/Write JSON 文件路线(obsidian-cli 不原生支持 .canvas 写入)
- canvas 与 Markdown 笔记的协作模式(项目板/主题鸟瞰/研究地图)
- 安全 SOP 4 选项对照表(A git stash / B .bak / C 原子写 / D File Recovery)
  TODO: 团队决策由用户填入
- 默认兜底实现 = C+D(原子写 + File Recovery),团队拍板前生效
2026-06-12 19:50:55 +08:00

9.2 KiB
Raw Blame History

name, description
name description
obsidian-canvas Obsidian 视觉层操作——读写 .canvas 文件(JSON Canvas 1.0 开放格式):思维导图、项目看板、视觉知识图、AI 生成节点布局。支持 4 种 node 类型(text/file/link/group+ edges 连线(fromNode/toNode/fromSide/toSide)。触发词:canvas、画布、思维导图、视觉知识图、项目看板、白板、可视化笔记、mind map、白板视图、节点图。不用于 Markdown 笔记 CRUDobsidian 核心)、不用于 Bases 数据库视图(obsidian-bases,那是表格不是画布)。社区共识:obsidian-cli 不原生支持 .canvas 写入,本技能走直接 JSON 文件 Read/Write 路线。

Obsidian Canvas · JSON Canvas 视觉层

为什么独立成技能Canvas 是 Obsidian 的开放格式(.canvas = JSON),社区标杆(kepano/obsidian-skills、AgriciDaniel/claude-obsidian)都把它作为独立 skill 维护,因为它的 schema 完全独立于 Markdown 笔记体系——AI 不能用一句 wikilink 替代一张画布。


何时使用

  • 用户说"把这些笔记画成一张图/思维导图/项目看板"
  • 用户给一个 .canvas 文件让 AI 读取/修改
  • 大主题展开时,AI 主动建议"做成 canvas 更清晰"
  • 项目启动时,用 canvas 做"模块 - 任务 - 负责人"鸟瞰图
  • 把研究网络(多篇笔记 + 几张图片 + 几个外链)摆到一张画布上

不用于

  • Markdown 笔记本身的 CRUD → obsidian 核心技能
  • 结构化数据库视图(表格、列表、卡片) → obsidian-bases
  • 笔记间的双向链接图(Obsidian 自带 Graph Viewobsidian-search 的 graph 子集
  • 单纯画流程图/时序图(Mermaid 块) → 写在 Markdown 笔记里即可

1. JSON Canvas 1.0 Schema 速查

.canvas 文件结构:

{
  "nodes": [ /* 数组顺序 = z-index(先画的在底层) */ ],
  "edges": [ /* 连线,order 不影响 z-index */ ]
}

1.1 Node 公共字段

字段 类型 必填 说明
id string 16 字符小写 hexObsidian 约定,64-bit 随机)
type enum text / file / link / group
x, y number 画布坐标(左上原点,向右/下为正,无单位)
width, height number 节点尺寸(像素)
color string "1"-"6"(预设色)或 "#RRGGBB"(自定义)

预设色:1=红, 2=橙, 3=黄, 4=绿, 5=青, 6=紫。

1.2 四种 Node 专属字段

type 专属字段 用途
text text: stringMarkdown 内容,换行用 \n,不要字面量 \\n 在画布上写笔记片段
file file: stringvault 内相对路径,如 "50-Zettel/abc.md");可选 subpath: 跳转锚点(#标题#^blockid 嵌入一篇笔记/图片/PDF
link url: string 嵌入外部网页
group label: string(分组标题);通常配 color 区分 视觉容器(不是真包含,只是覆盖矩形)

1.3 Edge 字段

字段 类型 必填 说明
id string 同 16 字符 hex
fromNode / toNode string 引用 node 的 id
fromSide / toSide enum top / right / bottom / left(默认自动选最近边)
fromEnd / toEnd enum none / arrow(默认 toEnd=arrowfromEnd=none
color string 同 node color
label string 连线上的文字

2. 16 字符 hex ID 生成

# BashGit Bash 可用)
openssl rand -hex 8                  # 推荐
# 或
head -c 8 /dev/urandom | xxd -p     # POSIX 兼容

# Python
python -c "import secrets; print(secrets.token_hex(8))"

# 节点和边的 ID 不要复用;同一 canvas 内全局唯一

3. 标准操作模式

社区共识obsidian-cli 原生支持 .canvas 写入。本技能走 Read + Write 工具直接编辑 JSON。

3.1 读取一张 canvas

# 列 vault 中所有 canvas
obsidian files ext=canvas format=json

# 直接读(用 Read 工具或 cat)
cat "MyVault/项目鸟瞰.canvas" | jq .

3.2 新建一张空 canvas

echo '{"nodes":[],"edges":[]}' > "MyVault/项目鸟瞰.canvas"

3.3 添加节点(Python helper 比 bash 安全)

# add_node.py
import json, secrets, sys

path = sys.argv[1]
with open(path, 'r', encoding='utf-8') as f:
    data = json.load(f)

data['nodes'].append({
    "id": secrets.token_hex(8),
    "type": "text",
    "x": 0, "y": 0, "width": 250, "height": 60,
    "text": "新节点"
})

with open(path, 'w', encoding='utf-8') as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

3.4 布局建议

  • 网格起步:节点 250×60,间隔 80px,AI 先排成网格再让用户手动调
  • 文本节点行高:每行约 22px,预估 height = 行数 × 22 + 16padding
  • group 覆盖范围:先算所有子节点的 bounding box,再 x -= 20, y -= 40, width += 40, height += 60
  • 文件节点:默认 400×400(带预览渲染),单行文本节点 250×60

4. 与 Markdown 笔记的协作模式

最强用法:canvas 当成"鸟瞰图 + 入口",节点 = 笔记 file 引用。 不要在 canvas 里写大段正文——那是 Markdown 的活;canvas 只承担空间关系

模式 怎么做
项目板 4 个 groupBacklog/Doing/Done/Archive),每个任务一个 file 节点
主题鸟瞰 中心 group = 主题名,周围环绕 file 节点(每篇相关 zettel
研究地图 text 节点写问题,file 节点放参考资料,edge 标关系("支持/反驳/引用"
AI 生成 AI 读多篇笔记后生成 canvas:自动布局 + 用 edge.label 标"先验/同源/对立"

5. 安全 SOP(AI 大批量写入的回滚策略)

决策待定:以下 4 选项需要团队定调。在写入前防止半写状态导致 canvas 损坏。

选项 操作 依赖 失败回退 适用边界
A · git stash 写前 git stash;失败 git stash pop vault 是 git repo stash 仍在 stash 栈 vault 用 git 托管
B · .bak 备份 写前 cp x.canvas x.canvas.bak;失败手动 mv 回滚 半人工 任何 vault
C · 原子写 x.canvas.tmpmv .tmp .canvasrename 原子操作) tmp 残留可清理 任何 vault
D · 依赖 File Recovery 不做额外保护,靠 Obsidian 内置 File Recovery(默认 7 天)回滚 Obsidian 内置 需手动进入 obsidian-history 找版本 vault 用户启用 File Recovery 且能及时发现失败

决策(团队规范)

当前[ 留待填入 ]

在确认前,AI agent 默认采用选项 C(原子写)+ 选项 D(File Recovery 兜底)——成本最低、不依赖 git、对 vault 无侵入。但这不是最终决策,请团队确认。

# 选项 C 默认实现(在团队决策前生效的兜底)
canvas_atomic_write() {
  local path="$1"
  local new_content="$2"
  local tmp="${path}.tmp.$$"
  echo "$new_content" > "$tmp" && \
    python -c "import json,sys; json.load(open('$tmp'))" && \
    mv "$tmp" "$path"
  # JSON 校验失败时不 mv,原文件不受影响,tmp 残留待清理
}

6. 常见陷阱

现象 原因 对策
Canvas 打开后空白 JSON 不合法(缺逗号、注释) JSON Canvas 不支持注释;用 jq . 先校验
节点位置错乱 x/y 用了字符串 必须是 number,不要 "x": "100"
中文字符乱码 编码不是 UTF-8 Python 打开/保存必须 encoding='utf-8'ensure_ascii=False
\n 显示为字面量 用了 \\n(双反斜杠) JSON 字符串里换行就是单 \n
Edge 不显示 fromNode/toNode 引用的 ID 不存在 写 edge 前先确认两端 node 已写入
文件节点没预览 file 路径错误(不是 vault 内相对路径) obsidian files 获取的标准路径

7. 与社区 schema 兼容性

本技能严格遵循 JSON Canvas Spec 1.0Obsidian、Logseq、Anytype 等多家共用)。 即便用户离开 Obsidian,.canvas 文件依然可被其他兼容工具读取——这是 Obsidian 开放格式承诺的核心价值。


8. 与其他 obsidian-* 技能的关系

graph LR
    canvas["obsidian-canvas<br/>(视觉层)"]
    core["obsidian<br/>(Markdown CRUD)"]
    search["obsidian-search<br/>(找节点要的笔记)"]
    meta["obsidian-meta<br/>(节点的 frontmatter)"]
    workflow["obsidian-workflow-pkm<br/>(MOC 编排时调用)"]

    workflow -- "MOC Builder 可输出 canvas" --> canvas
    canvas -- "file 节点引用" --> core
    canvas -- "新建 file 节点前查重" --> search
    canvas -- "节点字段约定" --> meta