
claude-obsidian Canvas 规范详解Obsidian JSON Canvas 的节点、边、坐标系统与实战避坑指南【免费下载链接】claude-obsidianSelf-organizing AI second brain for Obsidian Claude Code. Drop any source and Claude reads, links, and files it into one connected knowledge graph of plain Markdown you own. AI note-taking, personal knowledge management (PKM), and an open-source Notion alternative. Based on Karpathys LLM Wiki pattern.项目地址: https://gitcode.com/GitHub_Trending/cl/claude-obsidian本文围绕 claude-obsidian 仓库中的 Canvas JSON 规范参考 展开系统讲解.canvas文件的双键结构、四类节点与边的字段语义、坐标系统和配色约定并进一步结合 Canvas 技能定义、事务模块 和 事务测试 说明该规范如何被工程化地执行从 ID 生成策略、图像尺寸计算到写作用法的路径与写入范围约束。读完后你可以直接手写或程序化生成合法的 canvas 文件并理解该仓库为什么要求 canvas 变更必须走可恢复的事务通道。文件格式与 ID 约定Canvas 文件本质是 UTF-8 编码的 JSON 文件扩展名为.canvas只有两个顶层键nodes节点数组edges边连接关系数组。该结构对齐 JSON Canvas 1.0 开放规范。所有结构体都支持任意附加字段[key: string]: any以保持前向兼容——Obsidian 在读写 canvas 文件时会原样保留未知字段。这一点对自动化工具很关键解析和重写 canvas 时不应丢弃自己不认识的字段否则会破坏用户在 Obsidian 中保存的视图状态等私有数据。关于 ID 格式规范中有明确的产品约定值得单独强调JSON Canvas 1.0 只要求每个节点和边的 ID 是唯一字符串不规定长度或字符集该技能的新变更mutation偏好随机 16 位小写十六进制 ID例如a1b2c3d4e5f67890并校验其未被占用规范文档较长示例里出现的描述性 ID如title-0001、zone-logos只是可读性标签不是生成规则。为什么强调随机 ID因为规范在常见错误一节把ID 冲突列为首要风险生成新 ID 前必须先读取文件中已存在的全部 ID。随机 16 位 hex 的空间足够大把碰撞概率降到可忽略水平同时校验未使用这一步是强制的。坐标系规范用一张 ASCII 图定义了坐标系统x increases → ┌───────────────────────────────── │ (-920, -2400) (0, -2400) │ y │ (-920, 0) (0, 0) ← origin ↓ │ │ (-920, 540) (500, 540)四条核心规则原点 (0, 0) 是画布视口的中心x 向右增大负 x 表示位于中心左侧y 向下增大负 y 表示位于中心上方——注意这与多数数学坐标系相反节点的x/y是节点左上角的坐标不是中心点Obsidian 首次打开画布时会自动平移视图以适配全部节点所以负坐标完全合法只是更靠左/更上而已。规范在常见错误一节专门提醒y: -2400在y: -1000上方越负越靠上。这是布局脚本中最容易写反的一维——如果你按屏幕坐标系 y 向上的直觉摆放节点整版布局会上下颠倒。四类节点Text 节点把 markdown 内容渲染为带样式的卡片{ id: text-title-4821, type: text, text: # Heading\n\nParagraph with **bold** and code., x: -400, y: -300, width: 400, height: 120, color: 6 }要点text是 markdown 字符串换行必须写成 JSON 转义的\n而不是字面的反斜杠加 n 两个字符可读的最小尺寸width ≥ 200、height ≥ 60color可选省略即为默认无颜色。Canvas 技能 在操作手册层补充了两条硬约束每个节点的x、y、width、height都必须是整数文本节点高度过小虽能渲染但可能被裁剪经验公式是height ≥ 内容行数 × 24。File 节点内联渲染库vault内的图像、PDF、markdown 笔记或其他文件{ id: img-cover-7823, type: file, file: _attachments/images/example.png, x: -900, y: -100, width: 420, height: 236 }要点file必须是vault 相对路径——不能是绝对路径也不能是~/开头的家目录快捷写法支持的类型.png.jpg.webp.gif.pdf.md.canvas.md文件渲染为预览卡片.pdf文件渲染首页预览与普通节点一样可以携带可选的color字段。Canvas 技能 对路径安全的要求比规范正文更严格file和background一律拒绝绝对路径、..目录穿越、家目录快捷路径以及通过符号链接逃逸 vault 的路径并且只能引用已经存在于 vault 内的文件。技能文档还给出了一个增强写法file可配合可选的subpath: #Heading字段让笔记节点定位到文档内某个标题。Group 节点Zone带标签的矩形区域。需要特别注意group 不裁剪也不包含节点它只是一个视觉参考框。所谓放在 group 里面只是把节点定位到了它的包围盒范围内——JSON 中不存在父子关系。{ id: zone-branding-3391, type: group, label: Brand Identity, x: -920, y: -880, width: 1060, height: 290, color: 6, background: _attachments/images/grid-bg.png, backgroundStyle: cover }字段说明label显示在 group 框顶部color同时着色 group 边框和标签background可选group 背景图vault 相对路径backgroundStyle可选背景渲染方式——cover填满 group必要时裁切默认行为ratio保持宽高比完整放入 group 内部repeat平铺背景图group 不参与自动布局纯粹是视觉容器。Link 节点把 Web URL 渲染为内嵌预览卡片{ id: link-karpathy-2233, type: link, url: https://github.com/karpathy, x: 200, y: -300, width: 400, height: 120 }要点与安全边界url必须是合法的https://URLObsidian 会抓取目标页的 Open Graph 元数据标题、描述、缩略图写入 link 节点本身不发起任何网络请求但用户在 Obsidian 中打开或渲染它时Obsidian 会访问 URL 所在主机。规范因此要求先向用户披露这一渲染期出站render-time egress如果用户不接受就改用 text 节点承载 URL 文本。Canvas 技能 对此的表述是link 节点不授予抓取该页面的许可——生成 JSON 无请求但在 Obsidian 中打开可能拉取该 URL 主机的 Open Graph 元数据必须先确认用户可接受否则用 text 节点。Edges边边表示节点之间的连接在纯排版型的画布mood board上通常留空。{ id: e-hub-cidx, fromNode: hub, fromSide: right, fromEnd: none, toNode: c-idx, toSide: left, toEnd: arrow, label: concepts, color: 5 }字段语义与默认值这里有一个容易踩坑的不对称默认值字段必填说明id是边的唯一 IDfromNode/toNode是源/目标节点的 ID必须指向已存在或同批草稿中的节点fromSide/toSide否topbottomleftright省略时 Obsidian 根据节点相对位置自动计算最佳边fromEnd否源端端帽默认none取值none|arrowtoEnd否目标端端帽默认arrow取值none|arrowlabel否显示在边上的文本color否与节点相同的调色板1–6或十六进制由于大多数边表达有向关系这个不对称的默认组合fromEnd: none、toEnd: arrow意味着什么都不写就是一条从源指向目标的单箭头。这是规范专门点名的设计意图。配色参考表编码颜色近似 Hex典型用途1红 / 番茄色#e03e3e警告、归档2橙#d09035进行中的工作3黄 / 金#d0a023未完成、笔记4绿 / 青#448361内容、来源5蓝 / 青#3ea7d3导航、信息6紫 / 罗兰#9063d2标题、身份标识完全省略color字段即为默认外观无边框色、标签透明。边的color与节点共用同一调色板额外支持十六进制值。图像尺寸计算file 节点的width/height不应拍脑袋规范给出的流程是先用工具读出图像实际像素再按宽高比查表。python3 -c from PIL import Image; imgImage.open(path.png); print(img.width, img.height) # 或 identify -format %w %h path.png宽高比对照表宽高比条件ratioCanvas 宽Canvas 高16:9宽屏1.6–2.04202362:1超宽 2.04402204:31.2–1.63802851:1正方形0.9–1.12802803:40.6–0.92403209:16竖版 0.6200356PDF任意400520未知兜底320240自动定位伪代码规范提供了一段确定性的放置算法用于向画布追加节点时的自动布局。它的核心逻辑分三种情况function place_node(canvas, zone_label, new_w, new_h): zone find group node where label zone_label padding 20 if zone not found: max_y max(n.y n.height for n in canvas.nodes) 60 return (-400, max_y) # Nodes visually inside zone inside [n for n in canvas.nodes if n.type ! group and zone.x n.x zone.x zone.width and zone.y n.y zone.y zone.height] if inside is empty: return (zone.x padding, zone.y padding) # Rightmost point in zone rightmost max(n.x n.width for n in inside) next_x rightmost 40 if next_x new_w zone.x zone.width - padding: # Overflow → new row bottom_of_row max(n.y n.height for n in inside) return (zone.x padding, bottom_of_row padding) # Same row row_y min(n.y for n in inside) # align to top of existing row return (next_x, row_y)逐条解读找不到目标 group时新节点落在整画布最底部之下 60 px、x -400 处目标 group 为空时落在 group 内左上角留 20 px 内边距同排有空位时新节点接在区域内最右点 40 px 间隙处y 对齐当前行的顶边取行内最小 y实现行首对齐横向放不下next_x new_w越过 group 右边界减去 padding时换行回到 group 左内边距y 取当前行底部 20 px。注意算法用视觉包含坐标落在包围盒内判断节点属于哪个 zone而不是任何父子字段——再次印证 group 只是视觉容器。Canvas 技能 在操作手册中把这套参数固化为硬性要求20 px 内边距、40 px 间隙、必要时换行group 扩容前需先给出预览。完整示例双 Zone 画布一个最小完整的双分区画布覆盖 text、group、file 三类节点与空 edges 数组{ nodes: [ { id: title-0001, type: text, text: # Brand Reference\n\n**AI Marketing Hub** visual assets, x: -920, y: -2440, width: 560, height: 180, color: 6 }, { id: zone-logos, type: group, label: Logos Icons, x: -920, y: -2200, width: 1800, height: 320, color: 6 }, { id: img-logo-pro, type: file, file: _attachments/images/example.png, x: -900, y: -2180, width: 420, height: 236 }, { id: img-icon-free, type: file, file: _attachments/images/example-icon.png, x: -440, y: -2180, width: 280, height: 280 }, { id: zone-covers, type: group, label: Skill Covers, x: -920, y: -1820, width: 1800, height: 340, color: 3 }, { id: img-seo, type: file, file: _attachments/images/example-cover.png, x: -900, y: -1800, width: 420, height: 236 } ], edges: [] }从这个示例可以读出几处隐含的布局约定zone 之间的垂直间距第一个 zone 底部 y-1880 到第二个 zone 顶部 y-1820 留了 60 px、图像节点相对 group 左内边距 20 px-920 → -900、标题区与第一个 zone 之间的 40 px 间隔-2440180-2260 → -2200。节点数组在技能手册中被明确说明是自底向上的 z-order重写 canvas 时必须保持现有数组顺序新节点追加即可。常见错误清单规范最后集中列出五类高频错误前四条与前面各节呼应最后一条是文本节点的尺寸经验路径格式错误应使用 vault 相对路径如_attachments/images/file.png不能是宿主机绝对路径ID 冲突生成新 ID 前必须读取全部现有 ID 并校验唯一性负 y 方向混淆y: -2400在y: -1000上方越负越靠上Group 不裁剪JSON 中没有父子关系放进 group 只是坐标落在包围盒内文本节点高度不足Obsidian 能渲染但可能裁剪建议height ≥ 内容行数 × 24。仓库实现侧规范如何被强制执行规范文档给出应该怎么写而 claude-obsidian 仓库的源码定义了写坏了会发生什么。canvas 是 事务模块 中一个独立的操作类型canvas见OPERATION_TYPES集合其写入范围在代码中被硬编码约束if operation_type canvas and not ( (relative.startswith(wiki/canvases/) and relative.endswith(.canvas)) or relative wiki/canvases/index.md ): raise TransactionValidationError( WRITE_SCOPE_VIOLATION, canvas operations may write only wiki/canvases/*.canvas fand wiki/canvases/index.md: {relative}, )transaction.py即 canvas 事务只能写wiki/canvases/下的.canvas文件和目录索引wiki/canvases/index.md任何其它目标都会抛出WRITE_SCOPE_VIOLATION。事务测试 中有对应的最小权限用例把.raw/.manifest.json受管元数据写进 canvas 包会得到MANAGED_METADATA_COLLISION把wiki/sources/NotACanvas.md写进 canvas 包会得到WRITE_SCOPE_VIOLATION。从源码结构看这套约束是刻意设计的操作类型即权限边界canvas、base、fold、capture等操作类型各自声明了内容域generic类型也被限定为 wiki-only即使它名义上最宽泛。规范与技能手册之间的分工也体现在工程流程上。Canvas 技能 规定完整的变更流程只读操作状态查询、列表直接解析.canvas文件报告节点数、group 标签、悬空边端点和缺失的 vault 相对文件目标默认画布不存在时只报告并提供创建预览不在状态请求中创建文件草稿阶段读取整个 canvas 和目录索引记录每个目标的期望 SHA-256必须不存在的文件记null保留未知字段和数组顺序新节点要求唯一 ID、整数坐标与尺寸、边端点必须存在校验与预览JSON 可解析且只用支持的节点类型、ID 唯一、边端点存在、尺寸为正整数、file/background路径安全且存在、新节点不与现有节点意外重叠或溢出目标 group应用阶段打包为一个claude-obsidian.transaction.v1bundle操作类型canvas目录索引若变化则与画布同包提交然后python3 $CORE transaction inspect BUNDLE --vault VAULT # Set APPROVAL_SHA256 to the inspect results approval_sha256 after review. python3 $CORE transaction apply BUNDLE --vault VAULT \ --approved-plan-sha256 $APPROVAL_SHA256approval_sha256来自 inspect 结果它把展开后的计划绑定到规范化的 vault 根不能复用于另一个 vault——这一机制在 操作事务参考 中有完整契约说明预期哈希、原子替换、持久化日志、可恢复回滚。对于删除、替换、改名等破坏性变更技能要求先展示预览并获得明确同意然后报告操作 ID、变更路径、板名、节点 ID 和最终坐标且不做 Git 提交——若需要版本历史走独立的显式 checkpoint 命令。另外值得一提的旁路保护仓库的 URL 凭据检测模块 会拦截 userinfo 凭据和敏感查询参数token、api_key、X-Amz-Signature 等。虽然它服务于 URL 校验场景而非 canvas JSON 本身但与规范中 link 节点披露渲染期出站的要求共同构成该仓库对外部资源的一贯审慎态度canvas 里放一个 URL 是纯本地 JSON 写入而网络行为只发生在用户在 Obsidian 里打开它的那一刻。小结把 canvas-spec.md 当作生成.canvas文件的事实标准双键结构 未知字段保留、左上角锚定的 y 向下坐标系、text/file/group/link 四类节点各自的必填与可选字段、边的不对称默认箭头、1–6调色板、按宽高比查表的图像尺寸、20/40 px 的自动定位参数加上五条常见错误清单就是一份可直接落地的生成规则。而 Canvas 技能 与 事务实现 则在其外围加了两层护栏——vault 相对路径安全校验和wiki/canvases/的写入域约束——确保程序化生成的画布既符合规范格式又不会越权改动 vault 的其他部分。【免费下载链接】claude-obsidianSelf-organizing AI second brain for Obsidian Claude Code. Drop any source and Claude reads, links, and files it into one connected knowledge graph of plain Markdown you own. AI note-taking, personal knowledge management (PKM), and an open-source Notion alternative. Based on Karpathys LLM Wiki pattern.项目地址: https://gitcode.com/GitHub_Trending/cl/claude-obsidian创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。