# Obsidian Diary

> 将会话内容按主题聚合写入 Obsidian 工作日志或个人日记，并管理待办。当用户说「记录一下」「写日记」「更新待办」等要求记录时，或在会话末尾出现结构化结论/部署完成/调研成果时加载此技能，主动询问用户是否记录。

- Skill: `cnife/obsidian-diary` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add cnife/obsidian-diary`
- Raw SKILL.md: https://api.skillmd.com/api/skills/cnife/obsidian-diary/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: cnife (https://skillmd.com/u/cnife)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/cnife/obsidian-diary

---


# Obsidian 日记与待办管理

将当前会话的内容总结并写入 Obsidian 日记，同时搜索、更新、新增待办。

日记的目的是**给人看的记录**，不是 agent 工作日志。它的价值在于几个月后翻回来看还能知道那天发生了什么、为什么做了某个决策。所以必须做两件事：**按主题组织**（而不是按对话时间顺序平铺），**合并相关事件**（而不是一条一条回忆 dump）。

## 不可违反的约束

以下规则必须严格遵守，不因任何工作流步骤或上下文而改变。

### 事实边界

只写会话/工具输出中有明确证据的内容。**禁止添加虚构细节**：不要写"根据习惯""顺手翻了翻""一般来说""按我的经验""社区也掉过坑"等会话未提供的信息。日记是真实记录，不是润色后的故事。

**人称规则**：涉及用户的感受、偏好、评价时，如果用户没有亲口说，不要替用户写。（✅ "记录一下" -> 用户说的。❌ "这是用户最介意的痛点" -> 用户没这么说。）不确定时只写客观事实，不写第三人称心理描述。

### 路径约定

路径格式：`{日记目录}/YYYY/MM/YYYY年M月D日星期X.md`。关键约束：目录用纯数字（`2026/05/`），只有文件名含中文日期字符。完整对照表和常见错误见 `references/diary-rules.md`。

**陷阱：用 write_file 直接写平级路径会创建错误位置的文件。先用 `uv run --script scripts/obsidian-helper.py --vault <变体>` 查看 DIARY_PATH 后再写入。**

## 变体选择

> ⚡ **用户指定优先**：如果用户明确说了「记工作日志」「写个人日记」「记录到 personal」「更新工作日志」等变体指示，**直接遵从用户的选择**，不要用下面的判断规则覆盖。变体判断表只在用户没有明确指定时使用。

根据会话内容判断使用哪个变体：

- **work** -> 公司项目、部署运维、代码开发（公司仓库）、正式会议、团队协作
- **personal** -> 个人技术探索、学习笔记、投资、生活记录、**个人开源项目/独立仓库维护**

### 边界情况判断

| 场景 | 变体 | 判断依据 |
|------|------|----------|
| 公司 Git 仓库的代码开发/运维 | work | 公司仓库、团队协作、交付物 |
| 个人 GitHub 仓库（如 `pi-extensions`、`opencode` fork） | **personal** | 独立项目、非公司交付物 |
| 下班后学的新技术（与公司项目无关） | personal | 个人技能提升 |
| 工作相关但属于个人探索性质的原型验证 | personal | 非交付物、非正式项目 |
| 混合内容（同一会话既有工作又有个人） | **拆分记录** | 分别写入两个变体 |

判断核心：**内容是不是公司交付物/团队协作？** 是 -> work；否 -> personal。不要因涉及代码/Git 操作就自动归 work。

为什么切分？**受众和用途不同。** 工作日志会被同事和管理层查看（或作为日报素材），需要正式、客观、按子系统组织。个人日记只有自己看，可以更轻松，按自己的兴趣领域组织。混合内容时拆分后分别写入两个变体--投资分析归 personal，线上故障排查归 work。

## 首次配置

脚本运行前需要配置文件 `~/.config/cnife-skills/obsidian-diary.json`。

当脚本输出 `CONFIG_MISSING=true` 时，脚本会打印完整配置示例（含 `base`/`diary_dir`/`template`/`exclude_meta` 字段）。执行以下流程：

1. **询问用户**每个 vault 的 Obsidian 根目录（本地绝对路径）
2. 按脚本打印的示例结构创建配置文件（`base` 字段填入用户提供的路径，其余字段用默认值，除非用户明确要求修改）
3. 创建完成后重新运行脚本

## 脚本

所有文件系统操作通过 `scripts/obsidian-helper.py` 完成，脚本路径相对于本 skill 目录。

**必须使用 uv 运行**（自动管理依赖）：

```bash
uv run --script scripts/obsidian-helper.py --vault <work|personal>
```

## 先读后写

即使今天日记已存在，也要先运行脚本获取当日全文，用 patch 追加而非 write_file 覆盖。

## 主动检查与询问

在以下时机**主动询问**用户是否需要记录，**不要自行写入**：

1. 会话末尾出现结束信号：用户说「差不多了」「先这样」「收尾吧」「没别的事了」等
2. 会话中有明确的结构化产出：技术选型结论、部署完成、调研报告
3. 用户已完成主要任务，处于收尾阶段

询问格式：

- 能判断内容性质时：「要我把这次（工作/学习）记录到（工作/个人）日记吗？」
- 没有上下文无法判断时：「今天的内容需要记到日记吗？是工作相关的还是个人的？」

如果没有会话上下文（例如在空会话或新对话中被调用），先问用户今天做了什么，再提议记录。

## 工作流

### 步骤 1：收集上下文（1 次调用）

```bash
uv run --script scripts/obsidian-helper.py --vault <变体>
```

输出包含四个段落，一次拿齐：

- **路径信息**：DIARY_PATH、DATE
- **TODOS**：近期未完成待办（14 天）
- **RECENT**：最近 2-3 篇日记的前 30 行摘要（了解近期上下文和写作风格）
- **TODAY**：今日日记全文

日记不存在时脚本会自动从模板创建。

### 步骤 2：主题识别与聚合（最重要的步骤）

这是区分「流水账」和「好日记」的关键。不要直接按对话时间顺序写--先做主题分析。

#### 2a. 列举所有 distinct topics

扫描整个会话（包括工具输出），列出所有独立的主题。例如今天的会话如果包含 install daisy -> 分析中创智领 -> 跑红利筛选 -> 分析三只持仓 -> CouchDB 部署 -> Git 备份 -> SMB 备份，第一轮清单是 7 个 topic。

#### 2b. 聚合归域

把语义相近的 topic 合并为同一个主题域。判断依据：**这些事是否属于同一个目的或领域？** 聚合示例（好/坏对照）见 `references/diary-rules.md` 的 personal/work 变体好例子。

#### 合并规则

- 同一主题域的多个事件合并为 1 个 `# 标题`，其下用子 bullet 展开
- 每个子 bullet 1-2 行，只写结论和关键数据，不要展开细节
- 明显不同域的事件不能硬塞在一起（daisy 技能本身是金融研究的一部分，但 CouchDB 部署就不是）

### 2c. 检查今日日记已有内容（来自步骤 1 的 TODAY 输出）

**新内容能塞进已有章节的，不新开一段。** 例如今天继续做投资分析，而日记里已经有 `# 金融研究` 段落，就在那个段落追加新 bullet，不要另起 `# 金融研究（续）`。

**没找到对应章节的** -> 创建新的一级标题，插入到日记末尾（待办块之后）。

#### 2d. 排序

同一篇日记内，按重要性排序主题--通常工作/分析类在前、配置类在后。个人日记可以参考：投入时间多的 > 产出多的 > 顺手做的。

### 步骤 3：提取关键事件并写入

#### 3a. 提取内容

每个主题域内，从会话中识别**关键事件**，每个事件 1-2 行：

| 事件类型 | 记录要点 |
|----------|----------|
| 实现了功能 | 功能名称 + 核心特性 + 关键技术决策 |
| 调研了方案 | 调研对象 + 结论 + 选型判断（为什么选 A 不选 B） |
| 修复了问题 | 问题 + 根因 + 修复方式 |
| 做了决策 | 决策内容 + 理由 + 放弃的替代方案 |
| 部署/配置 | 环境 + 关键参数 + 验证结果 |

为什么只写 1-2 行？**日记是索引，不是完整文档。** 详细配置、代码片段、完整对话记录在独立文件里，日记只写结论和 links。几个月后翻回来看，看到一行就能想起当天做了什么；细节可以通过 link 或搜索找回。

#### 3b. 写入方式

**使用 Edit（patch）工具直接编辑日记文件**：

1. 根据步骤 2d 确定每个主题的插入位置
2. 已有章节 -> 找到该章节末尾插入新 bullet
3. 新章节 -> 在日记末尾（待办块之后、其他已有章节之前或之后，按排序决定）插入 `# 标题` + 内容

示例：

```text
# context 输出显示今日日记已有章节：
# Genos Reg Server
## 生产环境故障排查与修复
## IGV 可视化 Access forbidden 修复
# OneReason Backend

# 新内容（Genos 部署记录）的第 6 行后有 # Genos Reg Server，应在第 17 行之前插入
# 新主题如 # CouchDB 同步部署 -> 在文件末尾追加
```

**更新已有段落**（补充、修正、状态变更）：

- 只修改与本次会话相关的段落
- 不修改无关内容
- 合并重复而非追加--如果今天已经记过"daisy 技能安装"，补充结果时修改那条，不另起一行

**更新历史待办**：将对应文件中的 `- [ ]` 改为 `- [x]`，添加 `✅ YYYY-MM-DD`，同时在今日日记添加 Obsidian 链接：

```text
- [x] 任务描述 ✅ 2026-04-19  完成于 [[2026年4月15日星期三##任务标题]]
```

为什么加日期？**因为 Tasks 插件按完成日期查询。** 不加日期的话，回看时只知道"做过"，不知道什么时候做的，无法做周/月回顾。

#### 3c. 新增待办

本次会话产生的新待办，添加到今日日记末尾：

- 格式：`- [ ] 描述`
- 有计划日期时添加 `📅 YYYY-MM-DD`

### 步骤 3d：写入前强制门禁

动笔之前，在心里打好草稿，逐项检查以下 3 个 blocker。**任一 blocker 不通过 -> 必须先修正草稿再写入文件：**

| Blocker | 检查项 | 不通过则 |
|---------|--------|---------|
| ① 事实虚构 | 每条 bullet 是否能追溯到会话中的具体对话或工具输出？不要写"根据习惯""随手""一般来说"等无来源内容 | 删除虚构内容 |
| ② 结构散乱 | 是按主题域聚合而非按时间流程平铺？新内容是否塞进了今日日记已有章节？ | 重新聚合主题 |
| ③ 流程噪音 | 是否混入了 agent 操作日志（Git 提交、验证流程、开发阶段标记、AGENTS.md 规则沉淀、配置文件路径、发布部署操作）？ | 删除噪音，只保留人的结论和决策 |

### 步骤 4：确认（须附门禁报告）

门禁未通过时不得确认。全部通过后，在内容摘要之前加一行门禁报告：

```text
自检：事实✅ 结构✅ 噪音✅

新增的日记条目：
...
```

> ⚠️ 门禁报告只出现在确认摘要中，**不要写入日记正文**。

内容摘要：

- 新增的日记条目（按主题分组展示）
- 更新的待办（状态变化 + 链接）
- 新增的待办

如果本次没有实质性内容，询问用户是否仍要写入。

## Obsidian 待办状态

使用 Tasks 插件标准状态：

| 标记 | 状态 | 用途 |
|------|------|------|
| `[ ]` | 待办 | 未完成的任务 |
| `[x]` | 已完成 | 完成的任务，末尾加 `✅ YYYY-MM-DD` |
| `[-]` | 已取消 | 不再需要的任务，末尾加 `❌ YYYY-MM-DD` |

可选状态（按需使用）：

- `[/]` 进行中 - 已开始但未完成
- `[>]` 延期 - 推迟到以后
- `[!]` 重要 - 高优先级
- `[?]` 疑问 - 需要确认
- `[h]` 搁置 - 等待外部条件

跨文件引用已完成待办时，使用 Obsidian 链接：`[[日期文件名#任务标题]]`

## 内容注意事项

个人日记中涉及成人/R18 内容时使用隐喻和省略，不要直白描写。

> 只针对 R18 内容做隐晦化处理，不限制其他内容。

