- 新增 plugins/obsidian 插件目录,含 9 个 obsidian-* 技能 - 核心技能重构:去除 README.md 分散路由,合并 vault 自动检测 SOP(.obsidian/ 目录置信度表 + 标准进入动作)到 SKILL.md - 所有技能 description 精简重写:触发信号 + 边界 + .obsidian/ 联动激活信号,字数从 300+ 压缩至 220-250 - 更新 marketplace.json 追加 obsidian 插件条目 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
248 lines
9.0 KiB
Markdown
248 lines
9.0 KiB
Markdown
---
|
||
name: obsidian-meta
|
||
description: 管理 Obsidian 笔记元数据:YAML frontmatter 属性(status/tags/created/due 等)读写、tag 统计与体系治理、aliases 别名、bookmarks 书签、为 Dataview/Bases 设计字段规范。触发词:frontmatter、设置属性、tag、标签、别名、书签、属性读写。不用于全文搜索(obsidian-search)或 Bases 视图查询(obsidian-bases)。检测到 .obsidian/ 时与核心技能同步激活。
|
||
---
|
||
|
||
# Obsidian Meta · 元数据管理
|
||
|
||
> Frontmatter 属性、标签、别名、书签——Obsidian 的四大元数据系统。这是让 AI agent 结构化理解笔记的关键。
|
||
|
||
---
|
||
|
||
## 何时使用
|
||
|
||
- 给一篇笔记**设置或读取** frontmatter 属性(`status: draft` / `tags: [tech, arch]` / `due: 2026-05-01`)
|
||
- **批量维护** YAML 头(比如给所有 `50-Zettel/` 笔记补 `created` 字段)
|
||
- 统计 vault 中有哪些 tag、每个 tag 下有多少笔记
|
||
- 管理笔记的 **aliases**(别名,影响 wikilink 解析)
|
||
- 管理 **bookmarks**(收藏夹,快速跳转)
|
||
- 为 **Dataview** 或 **Obsidian Bases** 做字段规划
|
||
|
||
## 不用于
|
||
|
||
- 全文搜索 / 图谱分析 → **obsidian-search**
|
||
- Bases 视图的结构化查询 → **obsidian-bases**
|
||
- 任务状态管理(`- [ ]`/`- [x]`)→ **obsidian-tasks**
|
||
|
||
---
|
||
|
||
## 命令速查
|
||
|
||
### Tags 标签
|
||
|
||
```bash
|
||
obsidian tags # 列出 vault 所有 tag
|
||
obsidian tags counts # 含出现次数
|
||
obsidian tags sort=count # 按次数降序
|
||
obsidian tags format=json # JSON 输出
|
||
obsidian tags file=<name> # 某文件的 tags
|
||
obsidian tags active # 当前激活文件的 tags
|
||
obsidian tags total # 仅返回 tag 数量
|
||
|
||
obsidian tag name="tech" # 某 tag 详情
|
||
obsidian tag name="tech" verbose # 含使用该 tag 的文件列表
|
||
obsidian tag name="tech" total # 仅返回出现次数
|
||
```
|
||
|
||
### Properties(Frontmatter YAML)
|
||
|
||
```bash
|
||
obsidian properties # 列出 vault 所有属性名(YAML 默认)
|
||
obsidian properties counts # 含占用文件数
|
||
obsidian properties sort=count # 按出现次数排序
|
||
obsidian properties format=json # JSON 输出
|
||
obsidian properties file=<name> # 某文件的所有属性
|
||
obsidian properties name="status" # 查看某属性的使用情况
|
||
|
||
obsidian property:read name="status" file="项目A"
|
||
obsidian property:set name="status" value="done" file="项目A"
|
||
obsidian property:set name="tags" value="tech,arch,java" type=list file="技术笔记"
|
||
obsidian property:set name="due" value="2026-05-01" type=date file="项目A"
|
||
obsidian property:set name="priority" value=5 type=number file="项目A"
|
||
obsidian property:set name="published" value=true type=checkbox file="文章"
|
||
obsidian property:remove name="old_field" file="项目A"
|
||
```
|
||
|
||
**属性类型**:`text | list | number | checkbox | date | datetime`
|
||
|
||
### Aliases 别名
|
||
|
||
```bash
|
||
obsidian aliases # 列出 vault 所有别名
|
||
obsidian aliases verbose # 含文件路径
|
||
obsidian aliases total # 仅返回数量
|
||
obsidian aliases file=<name> # 某文件的别名
|
||
obsidian aliases active # 当前激活文件的别名
|
||
```
|
||
|
||
> 💡 Aliases 通过 frontmatter `aliases: [...]` 设置,影响 wikilink 解析——`[[别名]]` 会解析到原笔记。
|
||
|
||
### Bookmarks 书签
|
||
|
||
```bash
|
||
obsidian bookmarks # 列出所有书签(tsv 默认)
|
||
obsidian bookmarks verbose # 含类型(file/folder/search/url)
|
||
obsidian bookmarks format=json
|
||
|
||
obsidian bookmark file="重要笔记" # 添加文件书签
|
||
obsidian bookmark file="重要笔记" subpath="## 章节" # 指定标题/块
|
||
obsidian bookmark folder="10-Projects" # 文件夹书签
|
||
obsidian bookmark search="TODO" # 搜索书签
|
||
obsidian bookmark url="https://..." title="官方文档" # URL 书签
|
||
```
|
||
|
||
---
|
||
|
||
## AI Agent 最佳实践
|
||
|
||
### 场景 1 · Frontmatter 规范模板(写在 SCHEMA.md)
|
||
|
||
```yaml
|
||
---
|
||
# 身份
|
||
title: 笔记标题
|
||
aliases: [] # 别名列表
|
||
|
||
# 时间
|
||
created: 2026-04-09
|
||
updated: 2026-04-09
|
||
|
||
# 分类
|
||
type: note | project | area | resource | zettel | literature | moc
|
||
status: draft | active | done | archived
|
||
tags: [domain, subdomain]
|
||
|
||
# 项目专属
|
||
due: 2026-05-01
|
||
priority: 1-5
|
||
owner: name
|
||
|
||
# 永久笔记专属(Zettelkasten)
|
||
zettel_id: 202604091530
|
||
refs: [[[相关笔记1]], [[相关笔记2]]]
|
||
source: book | paper | url
|
||
---
|
||
```
|
||
|
||
**字段选型原则**:
|
||
- **通用字段**(所有笔记都有):`title / created / updated / status / tags`
|
||
- **可选字段**(按 type 触发):`due / priority / owner / zettel_id / source`
|
||
- **机器字段**(agent 写入):`last_ai_touched / ai_summary / review_count`
|
||
|
||
### 场景 2 · 批量补全 created/updated 字段
|
||
|
||
```bash
|
||
# 找出所有缺 created 字段的笔记
|
||
obsidian files folder="50-Zettel" format=json | \
|
||
# 由 agent 逐个 property:read name=created file=...
|
||
# 如果返回空,则从文件 mtime 推断
|
||
# obsidian property:set name=created value="2024-01-15" type=date file=...
|
||
```
|
||
|
||
### 场景 3 · 状态机流转
|
||
|
||
```bash
|
||
# 项目从 active → done
|
||
obsidian property:read name=status file="项目Alpha" # 先读现状
|
||
obsidian property:set name=status value=done file="项目Alpha"
|
||
obsidian property:set name=updated value=$(date +%Y-%m-%d) type=date file="项目Alpha"
|
||
|
||
# 可配合 obsidian-workflow-pkm 做 PARA 归档:
|
||
# done → 2 周无动作 → 移到 40-Archive/
|
||
```
|
||
|
||
### 场景 4 · Tag 体系治理
|
||
|
||
```bash
|
||
# 1. 扫描所有 tag 统计
|
||
obsidian tags counts sort=count format=json > /tmp/tags.json
|
||
|
||
# 2. 由 agent 分析:
|
||
# - 低频 tag(< 3 次)是否可合并
|
||
# - 命名不一致(#Tech vs #tech)的归一化
|
||
# - 层级化(#area/tech、#area/design)
|
||
|
||
# 3. 找出含某 tag 的所有文件,批量替换
|
||
obsidian tag name="Tech" verbose # 拿到文件列表
|
||
# 对每个文件: property:set name=tags value="..." type=list
|
||
```
|
||
|
||
**tag 层级推荐**(结合 Obsidian 原生层级 tag 支持):
|
||
|
||
```
|
||
#area/tech #status/draft
|
||
#area/design #status/active
|
||
#area/ops #status/done
|
||
#status/archived
|
||
#project/alpha
|
||
#project/beta #type/zettel
|
||
#type/moc
|
||
#type/literature
|
||
```
|
||
|
||
### 场景 5 · 用属性替代文件夹(动态视图)
|
||
|
||
Obsidian 的现代理念:**属性优于文件夹**。不用深层目录,而是用 frontmatter 做动态筛选。
|
||
|
||
```bash
|
||
# 所有 "active 项目" 用 property 查(配合 obsidian-bases)
|
||
obsidian property:set name=status value=active file="项目X"
|
||
|
||
# 然后在 obsidian-bases 里建一个视图:
|
||
# view: "进行中项目" where: status == "active" sort: due asc
|
||
```
|
||
|
||
### 场景 6 · 别名用于多语言/多写法
|
||
|
||
```yaml
|
||
---
|
||
title: Virtual Threads
|
||
aliases: [虚拟线程, 协程-Java 版, Project Loom]
|
||
---
|
||
```
|
||
|
||
wiki 中写 `[[虚拟线程]]` 或 `[[Project Loom]]` 都能链到同一篇。
|
||
|
||
---
|
||
|
||
## Dataview / Bases 字段设计建议
|
||
|
||
> 参考:dsebastien《Dataview frontmatter guide》、blacksmithgu/obsidian-dataview 文档
|
||
|
||
| 字段类型 | 示例 | Dataview 友好 | Bases 友好 | 备注 |
|
||
|---------|------|-------------|-----------|------|
|
||
| `text` | `title: 笔记` | ✅ | ✅ | 基础字符串 |
|
||
| `list` | `tags: [a,b]` | ✅ | ✅ | 多值用列表 |
|
||
| `number` | `priority: 3` | ✅(支持运算) | ✅ | 可排序可筛选 |
|
||
| `checkbox` | `done: true` | ✅ | ✅ | 布尔值 |
|
||
| `date` | `due: 2026-05-01` | ✅(支持 duration) | ✅ | 必须用 ISO 格式 |
|
||
| `datetime` | `created: 2026-04-09T10:30` | ✅ | ✅ | 含时间戳 |
|
||
| inline 字段 | `Key:: Value` | ✅ 仅 Dataview | ❌ Bases 不支持 | **Bases 只认 frontmatter,不认 inline** |
|
||
|
||
**铁律**:如果你用 Bases,**永远用 frontmatter**,不要用 `Key:: Value` inline 字段。
|
||
|
||
---
|
||
|
||
## 与其他技能的协作
|
||
|
||
| 场景 | 链路 |
|
||
|-----|------|
|
||
| 搜索命中后筛选 | **obsidian-search** → obsidian-meta(按 tag/status 二次过滤) |
|
||
| 批量属性维护 | obsidian-meta + **obsidian**(files 列出目标) |
|
||
| 按属性查询 | obsidian-meta(写入)→ **obsidian-bases**(查询展示) |
|
||
| 任务联动 | obsidian-meta(`status: done`)+ **obsidian-tasks**(`- [x]`) |
|
||
| 每日笔记自动打标签 | **obsidian-daily** + obsidian-meta |
|
||
|
||
---
|
||
|
||
## 常见陷阱
|
||
|
||
| 现象 | 原因 | 对策 |
|
||
|------|------|------|
|
||
| `property:set` 后 Obsidian 不显示 | 打开的是缓存视图 | `obsidian reload` 或重新打开笔记 |
|
||
| 日期字段在 Dataview 里无法排序 | 写成了 text 类型 | `property:set type=date` 明确类型 |
|
||
| Bases 读不到 `Key:: Value` | Bases 只认 frontmatter | 把 inline 字段改写到 YAML 头 |
|
||
| 属性值含特殊字符报错 | YAML 特殊字符未引号 | 含 `: [] {} #` 的值必须加 `""` |
|
||
| tag 层级识别错误 | 中间有空格 | 层级 tag 不能有空格:`#area/tech` ✅,`#area/ tech` ❌ |
|
||
| 批量改 tag 覆盖了已有 tag | `property:set` 是覆盖不是追加 | 先 `property:read`,合并后再 `set` |
|