---
words:
00index.canvas 不是 Obsidian 插件生成的,而是由你自建的守护脚本 /Users/ar/bin/tagfeed.py 持续重写的一个 Obsidian Canvas(JSON)文件;Obsidian 里的 Cammvas 社区插件 读取其中的 mindmap: true,把它渲染成「向右展开的目录脑图」。
~/Library/LaunchAgents/com.ar.tagfeedwatch-login.plist(Label com.ar.tagfeedwatch-login,RunAtLoad=true)执行 /usr/bin/open -g /Users/ar/Applications/TagfeedWatch.app。/Users/ar/Applications/):只是一个 ~60KB 的 Mach-O 外壳,内部用 /usr/bin/python3 调用真正的脚本。/Users/ar/bin/tagfeed.py,以 tagfeed.py --watch 常驻运行,默认 每 3 秒轮询一次 vault(检测到变化后还会等 1.5 秒防抖再处理)。核心函数:generate_canvas_index(vault, rel_dir="00index", canvas_name="00index.canvas")(tagfeed.py 约 1124–1291 行)。
canvas_signature() 计算 00index 目录的「结构指纹」——所有 .md 文件与子目录的相对路径集合。文件**改名**不改 mtime(普通内容指纹看不见),所以这个独立指纹专门捕捉「增 / 删 / 改名」。指纹变了才重画,否则跳过本轮。build():递归遍历 00index,同层文件夹在前、.md 文件在后;跳过 SKIP_DIRS(如 X.Attachment、.obsidian)和 CANVAS_SKIP_DIRS={"0inbox"}(实时聚合草稿目录,不进脑图)。place():根节点 → 文件夹节点(📁)→ 文件节点。文件节点用**文字节点 + wikilink**([[路径|文件名]])而非 file 节点,避免渲染满屏「笔记属性」预览;点击可直接打开对应笔记。节点 id 由路径经 md5 确定性生成。CANVAS_COLORS 给每个分支染红/绿/蓝,会覆盖你手动设的色,已停用)。改为「读取旧画布里已有的 color,按节点 id 匹配后保留」——所以你手动上的色在每次重画后都还在;新出现的节点默认无色,由你上色。(注:旧版遗留的默认色 1 现被视作「无色」,重画时不再继承——历史画布上被自动涂成 1 的节点会自然变回无色;你手动选的其它颜色照常保留。){nodes, edges})。mindmap: true,渲染成「向右展开的脑图」样式。.canvas 默认是自由画布视图,要看到脑图需启用 Cammvas 的 mindmap 模式。| 角色 | 名称 | 位置 |
|---|---|---|
| 启动项 | LaunchAgent plist | ~/Library/LaunchAgents/com.ar.tagfeedwatch-login.plist |
| 外壳 App | TagfeedWatch.app | /Users/ar/Applications/TagfeedWatch.app |
| 生成脚本 | tagfeed.py | /Users/ar/bin/tagfeed.py |
| 生成函数 | generate_canvas_index() / canvas_signature() |
tagfeed.py 内(约 1124–1291 行) |
| 渲染插件 | Cammvas(社区插件,mindmap 模式) | Obsidian 设置 → 社区插件 |
| 产物 | 00index.canvas | /Users/ar/Downloads/Syn/Ob/Ob.temp/00index/00index.canvas |
你把 00index/标签聚合/0inbox 移到了 00index/0inbox:
- 画布:CANVAS_SKIP_DIRS={"0inbox"} 按目录名全局跳过,位置变化不影响排除 → 画布依旧不含 0inbox。
- sync_0inbox.py:其 INBOX_DIR="0inbox" 本就拼成 00index/0inbox,与你的新位置一致 → 无需改动脚本。
- 当前画布实测:**73 节点 / 72 连线 / 0 个 0inbox / 72 个带颜色**(即你手动上的色都被成功保留)✅