@meitouai/mem-note-cli 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,346 @@
1
+ # mem-note 数据约定
2
+
3
+ > 这份文档是 mem-note 数据目录的**真源约定**。所有写入该目录的代理(人、CLI、AI agent、外部脚本)都必须遵守。
4
+ >
5
+ > AI agent 在任何 mem-note skill 开始时应首先 `Read` 本文件,作为判断的依据。
6
+
7
+ ## 1. 核心哲学
8
+
9
+ 1. **文件即数据库**。所有数据是 markdown 文件,无隐藏索引 / 数据库 / 二进制状态。
10
+ 2. **CLI 最小化**。CLI 只覆盖 5 个场景:(a) hook 时 AI 不在场、(b) 人需要快捷入口、(c) 多步易错操作的封装、(d) 跨会话的一致性检查、(e) 初始化。其他所有读写由 AI agent 用原生工具(`Read` / `Write` / `Edit` / `Glob` / `Grep` / `Bash`)完成。
11
+ 3. **AI agent 负责智能**。语义判断、矛盾识别、重复检测、groom 决策全部由 skill 里的 AI agent 完成,CLI 不包含任何智能逻辑。
12
+ 4. **约定优于配置**。本文档定义的格式是硬约束;漂移由 `mem-note doctor` 发现。
13
+
14
+ ## 2. 目录布局
15
+
16
+ ```
17
+ ~/.aibox-mem-note/ # 数据根(可由 $MEM_NOTE_DATA_DIR 覆盖)
18
+ ├── CONVENTIONS.md # 本文件(mem-note init 写入;已存在则跳过)
19
+ ├── notes/ # 永久 note
20
+ │ ├── NOTES.md # 根索引
21
+ │ ├── <topic>/
22
+ │ │ ├── NOTES.md # 子目录索引(必维护)
23
+ │ │ └── <slug>.md # 具体 note
24
+ │ ├── skills/ # 用户自定义 skill(保留子目录,不是 note)
25
+ │ │ └── <skill-name>/
26
+ │ │ ├── SKILL.md # skill 本体(frontmatter: name, description)
27
+ │ │ └── evals/ # 可选:该 skill 的 eval workspace
28
+ │ └── _archived/ # 归档的 note
29
+ │ └── <YYYY-MM-DD>_<slug>.md
30
+ ├── inbox/ # 待 groom 的原始输入池
31
+ │ ├── <YYYY-MM-DD-HHMMSS>_<slug>.md
32
+ │ └── .processed/ # 已处理的 entry(merged / discarded)
33
+ ├── insights/ # groom 过程产出的洞察
34
+ │ └── <id>.md
35
+ ├── .context/ # SessionStart / PreCompact 注入的上下文
36
+ │ └── index.md # 由 groom skill 维护
37
+ ├── .reports/ # 操作审计日志(append-only)
38
+ │ └── <YYYY-MM-DD>.md
39
+ └── .snapshots/ # 可选:groom 前的快照
40
+ └── <snapshot-id>/
41
+ ```
42
+
43
+ **特殊目录约定**:
44
+
45
+ - `notes/_archived/` **不**参与任何 Glob scanning;AI agent 应显式排除
46
+ - `notes/**/NOTES.md` 不是 note,AI agent 应显式排除
47
+ - `notes/skills/` 是**保留子目录**,里面存的是用户自定义 skill 而不是 note:
48
+ - groom 不要 triage 它(不当作 inbox 输出目标,不更新 NOTES.md 条目)
49
+ - 任何 `Glob notes/**/*.md` 应显式排除 `notes/skills/**` 以免混入 SKILL.md
50
+ - 发现 user skill 时用 `Glob notes/skills/*/SKILL.md`,读 frontmatter 的 `name` + `description` 即可
51
+ - `inbox/.processed/` 是软删除区,不参与 pending 统计
52
+
53
+ ## 3. Frontmatter Schema
54
+
55
+ 除 `CONVENTIONS.md`、`NOTES.md`、`.context/index.md`、`.reports/*.md`、
56
+ `notes/skills/**/SKILL.md`(遵循 Claude Code skill 自有格式)外,
57
+ 所有 `.md` 文件必须有 YAML frontmatter。
58
+
59
+ ### 3.1 Note (`notes/**/*.md`,除 NOTES.md)
60
+
61
+ ```yaml
62
+ ---
63
+ type: preference # 必填:preference | fact | lesson | reminder | note
64
+ title: Dark mode preference # 必填:人类可读,用于 NOTES.md 索引展示
65
+ description: > # 必填:一句话摘要,用于 NOTES.md 索引描述
66
+ Prefers dark mode across all editors, Monokai Pro theme.
67
+ tags: [ui, editor] # 必填(可为空数组):小写 kebab-case
68
+ updated: 2026-04-10 # 必填:ISO 日期
69
+ related: # 可选:相关 note 路径
70
+ - notes/user/editor-theme.md
71
+ source: # 可选:原始来源 inbox entry 路径
72
+ - inbox/2026-04-09-142030_dark-mode.md
73
+ ---
74
+ ```
75
+
76
+ ### 3.2 Inbox entry (`inbox/**/*.md`)
77
+
78
+ ```yaml
79
+ ---
80
+ type: note # 可选:保存者的初步判断;groom 时可被 AI agent 修改
81
+ tags: [] # 可选:groom 时补充
82
+ created: 2026-04-10-142030 # 必填:ISO 时间戳
83
+ source:
84
+ terminal # 可选但推荐:去重 key
85
+ # 取值:terminal | hook:stop | hook:sync | auto-memory:<path>
86
+ ---
87
+ ```
88
+
89
+ - `type` / `tags` **可为空**。inbox 的语义是"未分类的原始输入",分类是 groom 的职责。
90
+ - `source`:`mem-note save --source X` 会拒绝 source 已存在的导入(去重)。
91
+ - 顶层 `inbox/*.md` 保持原始输入语义;当条目被移动到 `inbox/.processed/` 后,
92
+ 处理后的副本**可以**追加一个 `processed` 对象记录处理结果,例如:
93
+
94
+ ```yaml
95
+ processed:
96
+ status: user-ignored
97
+ at: 2026-04-11-090807
98
+ reason: Ignored by user from the mem-note inbox UI.
99
+ ```
100
+
101
+ ### 3.3 Insight (`insights/*.md`)
102
+
103
+ ```yaml
104
+ ---
105
+ id: insight-v1K2p7 # 必填:短 nanoid
106
+ kind: clarification # 必填:clarification | pattern | skill-candidate | contradiction | <custom>
107
+ status: open # 必填:open | resolved | dismissed
108
+ title: Testing framework contradiction
109
+ created: 2026-04-10
110
+ related:
111
+ - notes/user/testing-jest.md
112
+ - notes/user/testing-vitest.md
113
+ ---
114
+ <自由 markdown 正文:evidence、reasoning、建议行动>
115
+ ```
116
+
117
+ ### 3.4 Archived note (`notes/_archived/**/*.md`)
118
+
119
+ 与原 note frontmatter 相同,追加一个 `archived` 字段:
120
+
121
+ ```yaml
122
+ ---
123
+ type: fact
124
+ title: Old deployment tool
125
+ ---
126
+ archived: 2026-04-10 # 归档日期
127
+ ---
128
+ ```
129
+
130
+ ## 4. 文件命名
131
+
132
+ | 类型 | 路径模板 | 示例 |
133
+ | ------------- | ------------------------------------------------- | ----------------------------------------- |
134
+ | Note | `notes/<topic>/<slug>.md` | `notes/user/dark-mode.md` |
135
+ | Inbox entry | `inbox/<YYYY-MM-DD-HHMMSS>_<slug>.md` (collisions within the same second get a `-<n>` suffix before `.md`) | `inbox/2026-04-10-142030_dark-mode.md` |
136
+ | Archived note | `notes/_archived/<YYYY-MM-DD>_<original-slug>.md` | `notes/_archived/2026-04-10_dark-mode.md` |
137
+ | Insight | `insights/<id>.md` | `insights/insight-v1K2p7.md` |
138
+
139
+ **slug 约定**:小写 kebab-case,只含 `[a-z0-9-]`,最长 60 字符。`mem-note save` 自动从内容前若干字生成。
140
+
141
+ ## 5. NOTES.md 索引规则
142
+
143
+ 每个 `notes/` 子目录(包括 `notes/` 本身)必须维护一份 `NOTES.md` 作为该目录的人类可读索引。
144
+
145
+ ### 5.1 格式
146
+
147
+ ```markdown
148
+ # notes/user
149
+
150
+ User-scope preferences, facts, and lessons.
151
+
152
+ ## Notes
153
+
154
+ - [Dark mode preference](dark-mode.md) — Prefers dark mode, Monokai Pro theme.
155
+ - [Deploy lesson](deploy-lesson.md) — Always run DB migrations before deploying.
156
+
157
+ ## Subdirectories
158
+
159
+ - [editor/](editor/NOTES.md) — Editor-specific preferences
160
+ ```
161
+
162
+ ### 5.2 维护契约
163
+
164
+ **任何创建、重命名、归档 note 的代理都必须同步更新对应目录的 `NOTES.md`**:
165
+
166
+ - 创建新 note → `## Notes` 追加 `- [<title>](<file>.md) — <description>`
167
+ - 更新 note 的 title 或 description → 更新对应行
168
+ - 归档 note → 从 `## Notes` 删除该行
169
+ - 创建子目录 → `## Subdirectories` 追加条目
170
+ - 删除空子目录 → 从 `## Subdirectories` 删除条目
171
+
172
+ `<title>` 和 `<description>` 直接来自 note 的 frontmatter 同名字段。
173
+
174
+ ### 5.3 为什么不自动维护
175
+
176
+ - NOTES.md 就地可读(人 / AI agent / git diff 都一目了然)
177
+ - 避免"CLI 自动维护 + AI agent 手动维护"的 race
178
+ - `mem-note doctor` 负责定期检查漂移,不靠运行时
179
+
180
+ ## 6. `.context/index.md` 约定
181
+
182
+ `.context/index.md` 是 **groom skill 编译**出的"本会话 AI agent 应记住的核心信息"。
183
+ SessionStart 和 PreCompact hook 都会注入它。
184
+
185
+ ### 6.1 结构
186
+
187
+ ```markdown
188
+ # Context — 2026-04-10
189
+
190
+ ## Preferences
191
+
192
+ - Dark mode, Monokai Pro, JetBrains Mono
193
+ - Functional style, named exports, files under 200 lines
194
+
195
+ ## Active Reminders
196
+
197
+ - API design review deadline: April 15
198
+ - Tuesday 10am standup — prepare notes
199
+
200
+ ## Key Facts
201
+
202
+ - Uses PostgreSQL 15 with PgBouncer
203
+ - Tests: Jest (unit) + Playwright (e2e), 80% coverage
204
+ - Planning REST → GraphQL migration (Apollo Server) in Q3
205
+ ```
206
+
207
+ ### 6.2 约束
208
+
209
+ - `## Active Reminders` 是**必须**段落(可以为空)。groom skill 必须在每次
210
+ 编译时扫描所有 `type: reminder` 的 note 重新生成这一段 —— 因为 PreCompact
211
+ hook 依赖它。
212
+ - 整体文件大小建议 **< 2KB**。SessionStart 和 PreCompact 每次都注入,太大
213
+ 会吃掉宝贵的 session context。
214
+ - 由 groom skill 的最后一步 `Write` 生成,**不**由 CLI 维护。
215
+
216
+ ## 7. Inbox / Archive 生命周期
217
+
218
+ ```
219
+ mem-note save
220
+
221
+
222
+ inbox/<ts>_<slug>.md ────── groom skill reads ──┐
223
+
224
+ ┌────────────────────┤
225
+ │ │
226
+ merge discard
227
+ │ │
228
+ ▼ ▼
229
+ notes/<topic>/<slug>.md inbox/.processed/<original>.md
230
+ (+ update NOTES.md) (软删除)
231
+
232
+ mem-note archive notes/<topic>/<slug>.md
233
+
234
+
235
+ notes/_archived/<date>_<slug>.md (+ remove from topic's NOTES.md)
236
+ ```
237
+
238
+ `.processed/` 保留所有历史 inbox entry,便于回溯;不再在 listing 中出现。
239
+
240
+ ## 8. AI agent 的工具使用优先级
241
+
242
+ AI agent 在 skill 会话中处理数据时,**优先使用原生文件工具**。
243
+ CLI 只在下表标注的少数场景调用。
244
+
245
+ | 操作 | 首选 | 不要用 |
246
+ | ------------------------ | ------------------------------------------------------------------ | ---------------------------------- |
247
+ | 列出所有 note | `Glob notes/**/*.md`(记得排除 `_archived/**`、`skills/**`、`NOTES.md`) | ❌ `mem-note list-notes`(不存在) |
248
+ | 发现用户 skill | `Glob notes/skills/*/SKILL.md` + 读 frontmatter | ❌ 任何 CLI |
249
+ | 读一个 note | `Read notes/path/foo.md` | ❌ CLI |
250
+ | 读某目录的索引视图 | `Read notes/<topic>/NOTES.md` | ❌ CLI |
251
+ | 写 / 更新 note | `Write` / `Edit` + 记得同步 `NOTES.md` | ❌ CLI |
252
+ | 搜索 note 内容 | `Grep "query" notes/**/*.md` | ❌ CLI |
253
+ | 处理 inbox entry | `Bash mv inbox/x.md inbox/.processed/` | ❌ CLI |
254
+ | 写 insight | `Write insights/<id>.md` | ❌ CLI |
255
+ | 编译 `.context/index.md` | `Write .context/index.md` | ❌ CLI |
256
+ | **归档 note** | ✅ `mem-note archive <path>`(封装多步操作) | `mv` + 手动更新 NOTES.md(易漏) |
257
+ | **检查一致性** | ✅ `mem-note doctor`(每次 groom 末尾) | 手动检查(不现实) |
258
+ | 追加 audit log | `Bash` 追加 `.reports/<date>.md` 或最后一次 `Write` | — |
259
+
260
+ ## 9. CLI 命令清单(5 个)
261
+
262
+ | # | 命令 | 职责 | 典型调用方 |
263
+ | --- | ------------------------- | ------------------------------------------------------ | -------------------------------- |
264
+ | 1 | `mem-note init` | 幂等创建目录 + 写入 `CONVENTIONS.md`(已存在则跳过) | 人(首次安装) |
265
+ | 2 | `mem-note save <content>` | 存一条 inbox entry。支持 `--type`、`--source`、stdin | 人 / hook / 外部脚本 |
266
+ | 3 | `mem-note archive <path>` | 封装 "加日期前缀 + mv 到 `_archived/` + 更新 NOTES.md" | 人 / AI agent |
267
+ | 4 | `mem-note doctor` | 检查 frontmatter schema、NOTES.md 漂移、归档命名一致性 | 人 / AI agent(每次 groom 结束时) |
268
+ | 5 | `mem-note quick-context` | 输出 `.context/index.md` 内容(封装路径解析) | hook (SessionStart / PreCompact) |
269
+
270
+ 其他一切都是 AI agent / 人用原生工具直接做。
271
+
272
+ ## 10. Groom Skill 默认工作流
273
+
274
+ 作为参考,groom skill 按以下顺序处理:
275
+
276
+ 1. `Read CONVENTIONS.md` —— 加载约定(若当前会话已加载可跳过)
277
+ 2. `Read notes/NOTES.md` + 感兴趣子目录的 `NOTES.md` —— 拿目录视图
278
+ 3. `Glob inbox/*.md` —— 列 pending inbox entries
279
+ 4. `Read` 每个 inbox entry
280
+ 5. 对每条 entry 决策 **create** / **merge** / **discard**:
281
+ - **create**:`Write notes/<topic>/<slug>.md` + `Edit notes/<topic>/NOTES.md`
282
+ - **merge**:`Edit notes/<topic>/existing.md` 合入新信息 + 更新 NOTES.md 的 description
283
+ - **discard**:无动作
284
+ 6. 所有情况都 `Bash mv inbox/<entry> inbox/.processed/`
285
+ 7. 如有冲突 / 过期 note,`mem-note archive <path>` 归档
286
+ 8. 如发现矛盾 / 模式,`Write insights/<id>.md`
287
+ 9. 重新编译 `.context/index.md`:`Write .context/index.md` 包含 Preferences / **Active Reminders** / Key Facts
288
+ 10. `Bash mem-note doctor` 检查一致性;有警告则修正
289
+ 11. `Bash` 追加一段 audit 到 `.reports/<YYYY-MM-DD>.md`
290
+
291
+ ## 11. Git 集成(可选但推荐)
292
+
293
+ `mem-note init` 会检测 git 是否可用,可用则在数据根执行 `git init`、写入
294
+ `.gitignore`、并做一次初始 commit。之后:
295
+
296
+ - `mem-note save` / `mem-note archive` 每次成功写入后自 commit,message 形如
297
+ `save: <slug>` / `archive: <slug>`。
298
+ - 插件的 Stop hook (`session-commit.sh`) 在每次 Claude Code 会话结束时兜底
299
+ commit 剩余未提交的改动,message 形如 `session: <ISO timestamp>`,
300
+ 用于捕获 skill 通过 `Write`/`Edit`/`Bash mv` 直接做的写入。
301
+
302
+ git 不可用时 mem-note 完全回退:所有功能照常工作,只是没有版本历史。
303
+
304
+ **`.gitignore` 默认内容**:忽略 `.snapshots/` 和 OS 垃圾(`.DS_Store` 等)。
305
+ 其余所有内容(包括 `notes/`、`inbox/`、`inbox/.processed/`、`insights/`、
306
+ `.context/index.md`、`.reports/`、`notes/skills/`)都进入 git。
307
+
308
+ **为什么 `.processed/` 也 track**:虽然和 git 历史有重合,但它保留了"已处理
309
+ inbox entry"的语义维度,方便后续 groom 或人类直接 `Read` 回溯;grep 友好。
310
+
311
+ ## 12. FAQ
312
+
313
+ **Q: 为什么 inbox entry 的 frontmatter 可以为空?**
314
+ A: inbox 是原始输入池。人 / hook / 外部脚本 save 时不应该被分类 schema 绑架。分类是 groom 的职责。
315
+
316
+ **Q: 为什么 `archive` 有 CLI 但 `create-note` 没有?**
317
+ A: archive 涉及"加日期前缀 + mv + 更新 NOTES.md"多步操作,手动容易漏;create 只是一次 `Write` + 一次 `Edit NOTES.md`,原生工具更透明。
318
+
319
+ **Q: AI agent 怎么在会话里搜 note?**
320
+ A: 用 `Grep "query" notes/**/*.md` 或 `Grep --glob '!**/NOTES.md' --glob '!**/_archived/**' "query" notes/`。
321
+
322
+ **Q: 人想在 terminal 快速搜 note?**
323
+ A: 用 ripgrep:`rg -i "query" ~/.aibox-mem-note/notes/`。懒的话 shell rc 加:
324
+
325
+ ```sh
326
+ alias mns='rg -i ~/.aibox-mem-note/notes/'
327
+ ```
328
+
329
+ **Q: 插件升级时 `CONVENTIONS.md` 会被覆盖吗?**
330
+ A: 不会。`mem-note init` 检测到已存在的 `CONVENTIONS.md` 会跳过写入。如果 schema 升级需要迁移,由 `mem-note doctor --migrate` 处理(未来扩展)。
331
+
332
+ **Q: `doctor` 检查哪些东西?**
333
+ A:
334
+
335
+ 1. 每个 note 的 frontmatter 是否有必填字段(`type`、`title`、`description`、`tags`、`updated`)
336
+ 2. 每个 note 是否在对应目录的 `NOTES.md` 里有对应条目
337
+ 3. 每个 `NOTES.md` 条目是否指向存在的文件
338
+ 4. `notes/_archived/` 下的文件名是否符合 `<YYYY-MM-DD>_<slug>.md` 格式
339
+ 5. Inbox entry 的 `created` 字段是否存在
340
+ 6. `.context/index.md` 是否存在 `## Active Reminders` 段落
341
+
342
+ **Q: 多个 AI agent 会话并发写怎么办?**
343
+ A: 不支持真正的并发(没有锁)。groom 是单会话操作,假设没有并发 writer。
344
+
345
+ **Q: 归档后能恢复吗?**
346
+ A: 能。`Bash mv notes/_archived/<date>_<slug>.md notes/<topic>/<slug>.md` + `Edit NOTES.md`。没有专门 CLI 命令,因为是罕见操作。