{"skill":{"slug":"organize-vault","displayName":"Organize Vault","summary":"扫描 Markdown vault 中的笔记，按语义主题生成目录层级，将笔记移动到 对应目录，并在根目录和每个主题目录下创建 MOC.md。增量维护模式下检测 git 新增笔记， 移动归类并更新对应 MOC.md。笔记内容始终不变，git 是唯一回退机制。","description":"---\nname: organize-vault\ndescription: 扫描 Markdown vault 中的笔记，按语义主题生成目录层级，将笔记移动到\n  对应目录，并在根目录和每个主题目录下创建 MOC.md。增量维护模式下检测 git 新增笔记，\n  移动归类并更新对应 MOC.md。笔记内容始终不变，git 是唯一回退机制。\norigin: OrganizeVault\nversion: \"1.1.0\"\nlicense: MIT\nhomepage: https://github.com/wanli6/OrganizeVault\nmetadata:\n  openclaw:\n    emoji: \"🗂️\"\n    os: [\"darwin\", \"linux\", \"win32\"]\n---\n\n# organize-vault\n\n知识库目录结构生成与 MOC 维护助手。\n\n## When to Use\n\n当用户说以下内容时激活：\n- \"整理一下 vault\"、\"把新笔记归类\"、\"更新 MOC\"\n- \"帮我初始化 vault 结构\"、\"生成目录层级\"\n- \"哪些笔记还没归类\"\n- \"organize my vault\"、\"update MOC\"\n\n## Core Constraints\n\n在整个执行过程中，以下约束不可违反：\n\n1. **永不修改笔记内容**：笔记的 body 文本不可改动。可移动文件位置、创建 MOC.md、在 MOC.md 中追加 wikilink。\n2. **变更必须经用户确认**：所有文件移动和写入在执行前展示完整清单，等待明确确认。\n3. **模糊性是正常状态**：无法归类的笔记归入 `misc/`，标注\"待整理\"，不强制归入不合适的主题。\n4. **git 是唯一回退**：所有变更受 git 追踪，执行前告知用户可通过 `git revert` 撤销。\n\n---\n\n## 目标结构\n\n初始化完成后，vault 应呈现如下层级：\n\n```\nvault/\n├── MOC.md                  # 根目录索引，链接所有主题目录\n├── programming/\n│   ├── MOC.md              # 本主题笔记列表（含描述）\n│   ├── python-async.md\n│   └── docker-compose.md\n├── tools/\n│   ├── MOC.md\n│   └── vim-config.md\n├── reading/\n│   ├── MOC.md\n│   └── deep-work.md\n└── misc/\n    ├── MOC.md              # 标注\"待整理\"\n    └── random-idea.md\n```\n\n---\n\n## 入口：检测场景\n\n```\n1. 若 vault_root 未知，询问用户 vault 的根目录路径\n\n2. 检测 git 状态：\n   git -C <vault_root> status --porcelain 2>&1\n   - 若返回 \"not a git repository\"：提示用户执行 git init，停止\n\n3. 检测是否存在 MOC 文件（见 MOC 识别规则）：\n   - 若无 MOC 文件 → 走【场景 B：初次初始化】\n   - 若有 MOC 文件 → 走【场景 A：增量维护】\n```\n\n### MOC 识别规则\n\n以下任一条件满足，则该文件被识别为 MOC，不参与归类：\n- 文件名为 `MOC.md`（大小写不敏感）\n- 文件顶部 frontmatter 中含 `type: moc` 或 `moc: true`\n\n---\n\n## 笔记描述提取规则\n\n在读取笔记全文时，同步提取一句简短描述，用于写入 MOC.md。提取优先级：\n\n1. frontmatter 的 `description` 字段（直接使用）\n2. H1 标题后第一个非空段落的首句（截断到 50 字以内）\n3. 以上均无：不写描述，只写 `- [[note-stem]]`\n\n描述**只写入 MOC.md**，不触碰原笔记文件。\n\n---\n\n## 场景 A：增量维护（已有 MOC）\n\n### Step 1 — 识别新增笔记\n\n```bash\n# 未提交的新增文件\ngit -C <vault_root> status --porcelain | grep '^?' | awk '{print $2}' | grep '\\.md$'\n\n# 或：相对上次 commit 新增的文件\ngit -C <vault_root> diff --name-only --diff-filter=A HEAD\n```\n\n过滤规则：\n- 只保留 `.md` 文件\n- 排除 `MOC.md`（按 MOC 识别规则）\n- 若结果为空：告知用户\"未发现新笔记（相对 git 状态）\"，结束\n\n### Step 2 — 读取现有目录结构\n\n用 find 找到所有 `MOC.md` 文件，逐一读取，理解各主题目录的内容范围。\n\n在内存中构建映射：\n```\n{\n  \"programming/MOC.md\": \"涵盖编程语言和框架，已有：[[python-async]], [[docker-compose]]...\",\n  \"tools/MOC.md\": \"开发工具配置，已有：[[vim-config]], [[git-tips]]...\"\n}\n```\n\n### Step 3 — 归类决策\n\n对每个新笔记，Read 其全文，然后：\n\n1. 按【笔记描述提取规则】提取一句描述\n2. 对比各主题目录，判断归属：\n   - **高置信度**：直接给出目标目录\n   - **低置信度**：列出候选目录，给出理由，让用户选择\n   - **无法归类**：归入 `misc/`，标注\"待整理\"\n3. 每篇笔记只移动到一个目录（主要主题）；若同时匹配多个主题，在多个 `MOC.md` 中均追加 wikilink\n4. 检查目标 `MOC.md` 是否已含该笔记链接：若已含，跳过\n\n### Step 4 — 展示变更预览\n\n```\n待执行的操作：\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n  移动：python-async.md → programming/python-async.md\n  更新：programming/MOC.md ← 追加\n        [[python-async]] — Python asyncio 事件循环机制详解\n  理由：笔记讨论 Python asyncio，归入 programming\n\n  移动：vim-config.md → tools/vim-config.md\n  更新：tools/MOC.md ← 追加\n        [[vim-config]] — Vim 配置文件与插件管理\n  理由：编辑器配置，归入 tools\n\n无法归类（共 1 篇）：\n  random-idea.md → misc/random-idea.md（标注\"待整理\"）\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n所有变更受 git 追踪，可通过 git revert 撤销。\n确认执行？（可指定\"全部\"或逐条接受/拒绝）\n```\n\n### Step 5 — 执行变更\n\n对每个用户确认的归类：\n1. `mv <vault_root>/<note>.md <vault_root>/<topic>/<note>.md`\n2. Edit `<topic>/MOC.md`，在笔记列表末尾追加：\n   - 有描述：`- [[note-stem]] — {描述}`\n   - 无描述：`- [[note-stem]]`\n\n若目标目录不存在，先 `mkdir -p` 创建，再在其中创建 `MOC.md`（格式见下文）。\n\n---\n\n## 场景 B：初次初始化（无 MOC）\n\n> 分四步执行，避免一次读取大量笔记导致上下文过长。\n\n### Step 1 — 标题扫描\n\n```bash\nfind <vault_root> -name \"*.md\" -not -path \"*/.git/*\" -not -name \"MOC.md\"\n```\n\n对每个文件，只提取：\n- 文件相对路径\n- H1 标题（首行 `# ...`）或文件名 stem（若无 H1）\n\n**不读取笔记 body。**\n\n### Step 2 — 分组提案\n\n基于文件路径（目录结构）+ 标题，推断主题分组，向用户提出候选结构：\n\n```\n建议生成以下目录结构（基于 47 篇笔记的标题和路径）：\n\n  programming/    — 约 18 篇（Python, TypeScript, 算法...）\n  tools/          — 约 12 篇（Docker, Vim, Git...）\n  reading/        — 约 9 篇（读书笔记, 摘录...）\n  projects/       — 约 5 篇（项目记录...）\n  misc/           — 约 3 篇（暂无明显归属）\n\n是否采用这个结构？可以调整目录名、合并或拆分分组。\n```\n\n等待用户确认或修改。**不执行任何文件操作。**\n\n### Step 3 — 逐组细化\n\n用户确认结构后，按分组**逐批**读取笔记全文（每批 10-15 篇），对每篇笔记：\n\n1. 按【笔记描述提取规则】提取一句描述\n2. 确认归属哪个目录：\n   - 归属明确的：记录目标目录 + 描述\n   - 跨主题的：移动到主要目录，在次要目录的 `MOC.md` 中也追加链接\n   - 完全不匹配的：归入 `misc/`，标注\"待整理\"\n\n记录所有归属决策（含描述），**不写文件**。\n\n### Step 4 — 目录重组\n\n汇总所有归属决策，展示完整预览：\n\n```\n即将执行以下操作（共 47 个笔记）：\n\n新建目录：\n  programming/    tools/    reading/    projects/    misc/\n\n移动文件（共 47 个）：\n  python-async.md          → programming/python-async.md\n  docker-compose.md        → programming/docker-compose.md\n  vim-config.md            → tools/vim-config.md\n  ...（共 47 条，全部展示）\n\n新建 MOC 文件（共 6 个）：\n  MOC.md                   （根目录索引，5 个主题）\n  programming/MOC.md       （18 个笔记，含描述）\n  tools/MOC.md             （12 个笔记，含描述）\n  reading/MOC.md           （9 个笔记，含描述）\n  projects/MOC.md          （5 个笔记，含描述）\n  misc/MOC.md              （3 个笔记，标注\"待整理\"）\n\n清理空目录（若有）：移走笔记后变空的原目录将被删除\n\n所有变更受 git 追踪，可通过 git revert 撤销。\n确认执行？\n```\n\n用户确认后，按以下顺序执行：\n1. `mkdir -p` 创建所有主题目录\n2. `mv` 移动所有笔记文件\n3. Write 创建每个 `<topic>/MOC.md`（含描述）\n4. Write 创建根目录 `MOC.md`\n5. `rmdir` 清理空目录（失败则静默跳过）\n\n---\n\n## MOC 文件格式\n\n**主题目录 `<topic>/MOC.md`**：\n```markdown\n# {主题名称}\n\n## 笔记\n\n- [[python-async]] — Python asyncio 事件循环机制详解\n- [[docker-compose]] — 多容器应用编排配置示例\n- [[algorithm-notes]]\n```\n\n（无描述的笔记直接写 `- [[note-stem]]`，不强制加破折号）\n\n**根目录 `MOC.md`**：\n```markdown\n# Vault Index\n\n## 主题\n\n- [[programming/MOC|Programming]]\n- [[tools/MOC|Tools]]\n- [[reading/MOC|Reading]]\n- [[projects/MOC|Projects]]\n- [[misc/MOC|Misc]]\n```\n\n---\n\n## 边界情况处理\n\n| 情况 | 处理方式 |\n|------|---------|\n| vault 未初始化 git | 提示执行 `git init && git add -A && git commit -m \"init\"`，停止 |\n| vault 无任何 .md 文件 | 告知 vault 为空，结束 |\n| 无法确定 vault 根目录 | 询问用户，不猜测 |\n| 根目录已有 MOC.md | 询问用户是覆盖还是追加，不默认覆盖 |\n| 笔记同时匹配多个主题 | 移动到主要目录，在次要目录 MOC.md 中追加跨目录 wikilink |\n| 移走笔记后原目录变空 | `rmdir` 删除，失败则静默跳过（可能含其他文件） |\n| MOC.md 已含该笔记链接 | 跳过，不重复添加 |\n| 新笔记本身是 MOC.md | 跳过归类，告知用户 |\n| 笔记无可提取描述 | 只写 `- [[note-stem]]`，不加破折号，不报错 |\n| 大型 vault（> 100 篇笔记）初始化 | 严格执行分步策略，每批不超过 15 篇全文读取 |\n","tags":{"latest":"1.1.0"},"stats":{"comments":0,"downloads":320,"installsAllTime":12,"installsCurrent":0,"stars":0,"versions":1},"createdAt":1778144346186,"updatedAt":1778492867743},"latestVersion":{"version":"1.1.0","createdAt":1778144346186,"changelog":"- 增加增量维护模式：自动检测 git 新增笔记，归类并更新对应 MOC.md。\n- 归类变更前提供详细清单，需用户逐条确认后执行，所有操作受 git 追踪。\n- 笔记按语义主题归入目录，无法归类的集中于 misc/，并清楚标注“待整理”。\n- 初始化和增量归类流程详细拆分，支持大型 vault 分批处理，提升安全与透明度。\n- 明确约束永不修改笔记内容，仅移动、生成或更新 MOC.md 文件，变更可用 git 回退。","license":"MIT-0"},"metadata":{"setup":[],"os":["darwin","linux","win32"],"systems":null},"owner":{"handle":"wanli6","userId":"s17bkwh69sjsrc4sayfap6rs2d83gvnz","displayName":"wl95","image":"https://avatars.githubusercontent.com/u/59633744?v=4"},"moderation":null}