运行时依赖
安装命令
点击复制技能文档
organize-vault 知识库目录结构生成与 MOC 维护助手。
当用户说以下内容时激活: "整理一下 vault"、"把新笔记归类"、"更新 MOC"、"帮我初始化 vault 结构"、"生成目录层级"、"哪些笔记还没归类"、"organize my vault"、"update MOC"
Core Constraints 在整个执行过程中,以下约束不可违反: 永不修改笔记内容:笔记的 body 文本不可改动。可移动文件位置、创建 MOC.md、在 MOC.md 中追加 wikilink。 变更必须经用户确认:所有文件移动和写入在执行前展示完整清单,等待明确确认。 模糊性是正常状态:无法归类的笔记归入 misc/,标注"待整理",不强制归入不合适的主题。 git 是唯一回退:所有变更受 git 追踪,执行前告知用户可通过 git revert 撤销。
目标结构 初始化完成后,vault 应呈现如下层级: vault/ ├── MOC.md # 根目录索引,链接所有主题目录 ├── programming/ │ ├── MOC.md # 本主题笔记列表(含描述) │ ├── python-async.md │ └── docker-compose.md ├── tools/ │ ├── MOC.md │ └── vim-config.md ├── reading/ │ ├── MOC.md │ └── deep-work.md └── misc/ ├── MOC.md # 标注"待整理" └── random-idea.md
入口:检测场景
- 若 vault_root 未知,询问用户 vault 的根目录路径
- 检测 git 状态: git -C status --porcelain 2>&1 -
- 检测是否存在 MOC 文件(见 MOC 识别规则):
- 若无 MOC 文件 → 走【场景 B:初次初始化】
- 若有 MOC 文件 → 走【场景 A:增量维护】
MOC 识别规则 以下任一条件满足,则该文件被识别为 MOC,不参与归类: 文件名为 MOC.md(大小写不敏感) 文件顶部 frontmatter 中含 type: moc 或 moc: true
笔记描述提取规则 在读取笔记全文时,同步提取一句简短描述,用于写入 MOC.md。提取优先级: frontmatter 的 description 字段(直接使用) H1 标题后第一个非空段落的首句(截断到 50 字以内) 以上均无:不写描述,只写 - [[note-stem]] 描述只写入 MOC.md,不触碰原笔记文件。
场景 A:增量维护(已有 MOC) Step 1 — 识别新增笔记 # 未提交的新增文件 git -C status --porcelain | grep '^?' | awk '{print $2}' | grep '\.md$' # 或:相对上次 commit 新增的文件 git -C diff --name-only --diff-filter=A HEAD 过滤规则: 只保留 .md 文件 排除 MOC.md(按 MOC 识别规则) 若结果为空:告知用户"未发现新笔记(相对 git 状态)",结束
Step 2 — 读取现有目录结构 用 find 找到所有 MOC.md 文件,逐一读取,理解各主题目录的内容范围。 在内存中构建映射: { "programming/MOC.md": "涵盖编程语言和框架,已有:[[python-async]], [[docker-compose]]...", "tools/MOC.md": "开发工具配置,已有:[[vim-config]], [[git-tips]]..." }
Step 3 — 归类决策 对每个新笔记,Read 其全文,然后: 按【笔记描述提取规则】提取一句描述 对比各主题目录,判断归属: 高置信度:直接给出目标目录 低置信度:列出候选目录,给出理由,让用户选择 无法归类:归入 misc/,标注"待整理" 每篇笔记只移动到一个目录(主要主题);若同时匹配多个主题,在多个 MOC.md 中均追加 wikilink 检查目标 MOC.md 是否已含该笔记链接:若已含,跳过
Step 4 — 展示变更预览 待执行的操作: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 移动:python-async.md → programming/python-async.md 更新:programming/MOC.md ← 追加 [[python-async]] — Python asyncio 事件循环机制详解 理由:笔记讨论 Python asyncio,归入 programming 移动:vim-config.md → tools/vim-config.md 更新:tools/MOC.md ← 追加 [[vim-config]] — Vim 配置文件与插件管理 理由:编辑器配置,归入 tools 无法归类(共 1 篇): random-idea.md → misc/random-idea.md(标注"待整理") ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 所有变更受 git 追踪,可通过 git revert 撤销。 确认执行?(可指定"全部"或逐条接受/拒绝)
Step 5 — 执行变更 对每个用户确认的归类: mv /.md //.md Edit /MOC.md,在笔记列表末尾追加: 有描述:- [[note-stem]] — {描述} 无描述:- [[note-stem]] 若目标目录不存在,先 mkdir -p 创建,再在其中创建 MOC.md(格式见下文)。
场景 B:初次初始化(无 MOC) 分四步执行,避免一次读取大量笔记导致上下文过长。
Step 1 — 标题扫描 find -name ".md" -not -path "/.git/*" -not -name "MOC.md" 对每个文件,只提取: 文件相对路径 H1 标题(首行 # ...)或文件名 stem(若无 H1) 不读取笔记 body。
Step 2 — 分组提案 基于文件路径(目录结构)+ 标题,推断主题分组,向用户提出候选结构: 建议生成以下目录结构(基于 47 篇笔记的标题和路径): programming/ — 约 18 篇(Python, TypeScript, 算法...) tools/ — 约 12 篇(Docker, Vim, Git...) reading/ — 约 9 篇(读书笔记, 摘录...) projects/ — 约 5 篇(项目记录...) misc/ — 约 3 篇(暂无明显归属) 是否采用这个结构?可以调整目录名、合并或拆分分组。 等待用户确认或修改。不执行任何文件操作。
Step 3 — 逐组细化 用户确认结构后,按分组逐批读取笔记全文(每批 10-15 篇),对每篇笔记: 按【笔记描述提取规则】提取一句描述 确认归属哪个目录: 归属明确的:记录目标目录 + 描述 跨主题的:移动到主要目录,在次要目录的 MOC.md 中也追加链接 完全不匹配的:归入 misc/,标注"待整理" 记录所有归属决策(含描述),不写文件。
Step 4 — 目录重组 汇总所有归属决策,展示完整预览: 即将执行以下操作(共 47 个笔记): 新建目录: programming/ tools/ reading/ projects/ misc/ 移动文件(共 47 个): python-async.md → programming/python-async.md docker-compose.md → programming/docker-compose.md vim-config.md → tools/vim-config.md ...(共 47 条,全部展示) 新建 MOC 文件(共 6 个): MOC.md (根目录索引,5 个主题) programming/MOC.md (18 个笔记,含描述) tools/MOC.md (12 个笔记,含描述) reading/MOC.md (9 个笔记,含描述) projects/MOC.md (5 个笔记,含描述) misc/MOC.md (3 个笔记,标注"待整理") 清理空目录(若有):移走笔记后变空的原目录将被删除 所有变更受 git 追踪,可通过 git revert 撤销