@synth-coder/memhub 0.2.2 → 0.2.3

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.
Files changed (71) hide show
  1. package/.eslintrc.cjs +45 -45
  2. package/.factory/commands/opsx-apply.md +150 -0
  3. package/.factory/commands/opsx-archive.md +155 -0
  4. package/.factory/commands/opsx-explore.md +171 -0
  5. package/.factory/commands/opsx-propose.md +104 -0
  6. package/.factory/skills/openspec-apply-change/SKILL.md +156 -0
  7. package/.factory/skills/openspec-archive-change/SKILL.md +114 -0
  8. package/.factory/skills/openspec-explore/SKILL.md +288 -0
  9. package/.factory/skills/openspec-propose/SKILL.md +110 -0
  10. package/.github/workflows/ci.yml +74 -74
  11. package/.iflow/commands/opsx-apply.md +152 -152
  12. package/.iflow/commands/opsx-archive.md +157 -157
  13. package/.iflow/commands/opsx-explore.md +173 -173
  14. package/.iflow/commands/opsx-propose.md +106 -106
  15. package/.iflow/skills/openspec-apply-change/SKILL.md +156 -156
  16. package/.iflow/skills/openspec-archive-change/SKILL.md +114 -114
  17. package/.iflow/skills/openspec-explore/SKILL.md +288 -288
  18. package/.iflow/skills/openspec-propose/SKILL.md +110 -110
  19. package/.prettierrc +11 -11
  20. package/AGENTS.md +169 -26
  21. package/README.md +195 -195
  22. package/README.zh-CN.md +193 -193
  23. package/dist/src/contracts/mcp.js +34 -34
  24. package/dist/src/server/mcp-server.d.ts +8 -0
  25. package/dist/src/server/mcp-server.d.ts.map +1 -1
  26. package/dist/src/server/mcp-server.js +23 -2
  27. package/dist/src/server/mcp-server.js.map +1 -1
  28. package/dist/src/services/memory-service.d.ts +1 -0
  29. package/dist/src/services/memory-service.d.ts.map +1 -1
  30. package/dist/src/services/memory-service.js +125 -82
  31. package/dist/src/services/memory-service.js.map +1 -1
  32. package/docs/architecture-diagrams.md +368 -0
  33. package/docs/architecture.md +381 -349
  34. package/docs/contracts.md +190 -119
  35. package/docs/prompt-template.md +33 -79
  36. package/docs/proposals/mcp-typescript-sdk-refactor.md +568 -568
  37. package/docs/proposals/proposal-close-gates.md +58 -58
  38. package/docs/tool-calling-policy.md +101 -107
  39. package/docs/vector-search.md +306 -0
  40. package/package.json +59 -58
  41. package/src/contracts/index.ts +12 -12
  42. package/src/contracts/mcp.ts +222 -222
  43. package/src/contracts/schemas.ts +307 -307
  44. package/src/contracts/types.ts +410 -410
  45. package/src/index.ts +8 -8
  46. package/src/server/index.ts +5 -5
  47. package/src/server/mcp-server.ts +185 -161
  48. package/src/services/embedding-service.ts +114 -114
  49. package/src/services/index.ts +5 -5
  50. package/src/services/memory-service.ts +663 -621
  51. package/src/storage/frontmatter-parser.ts +243 -243
  52. package/src/storage/index.ts +6 -6
  53. package/src/storage/markdown-storage.ts +236 -236
  54. package/src/storage/vector-index.ts +160 -160
  55. package/src/utils/index.ts +5 -5
  56. package/src/utils/slugify.ts +63 -63
  57. package/test/contracts/schemas.test.ts +313 -313
  58. package/test/contracts/types.test.ts +21 -21
  59. package/test/frontmatter-parser-more.test.ts +94 -94
  60. package/test/server/mcp-server.test.ts +210 -169
  61. package/test/services/memory-service-edge.test.ts +248 -248
  62. package/test/services/memory-service.test.ts +278 -278
  63. package/test/storage/frontmatter-parser.test.ts +222 -222
  64. package/test/storage/markdown-storage.test.ts +216 -216
  65. package/test/storage/storage-edge.test.ts +238 -238
  66. package/test/storage/vector-index.test.ts +153 -153
  67. package/test/utils/slugify-edge.test.ts +94 -94
  68. package/test/utils/slugify.test.ts +68 -68
  69. package/tsconfig.json +25 -25
  70. package/tsconfig.test.json +8 -8
  71. package/vitest.config.ts +29 -29
package/docs/contracts.md CHANGED
@@ -1,119 +1,190 @@
1
- # MemHub 契约文档(vNext
2
-
3
- 当前对外 MCP 工具仅保留两项:
4
-
5
- 1. `memory_load`(首轮)
6
- 2. `memory_update`(末轮)
7
-
8
- 目标是形成稳定闭环:**先读 STM,再回写 STM**。
9
-
10
- ---
11
-
12
- ## 1) memory_load
13
-
14
- 用于用户输入后第一轮主动加载短期记忆。
15
-
16
- ### 输入
17
-
18
- ```ts
19
- interface MemoryLoadInput {
20
- id?: string; // 指定单条记忆
21
- sessionId?: string; // 会话 UUID
22
- date?: string; // YYYY-MM-DD
23
- query?: string; // 文本检索
24
- category?: string;
25
- tags?: string[];
26
- limit?: number; // 默认 20
27
- scope?: 'stm' | 'all'; // 默认 stm
28
- }
29
- ```
30
-
31
- ### 输出
32
-
33
- ```ts
34
- interface MemoryLoadOutput {
35
- items: Memory[];
36
- total: number;
37
- }
38
- ```
39
-
40
- ---
41
-
42
- ## 2) memory_update
43
-
44
- 用于本轮结束前主动回写记忆。
45
-
46
- ### 输入
47
-
48
- ```ts
49
- type EntryType = 'decision' | 'preference' | 'knowledge' | 'todo' | 'state_change';
50
-
51
- interface MemoryUpdateInput {
52
- id?: string; // 有 id 则更新;无 id 则追加
53
- sessionId?: string; // 无则服务端自动生成并返回
54
- mode?: 'append' | 'upsert'; // 默认 append
55
- entryType?: EntryType;
56
- title?: string;
57
- content: string; // 必填
58
- tags?: string[];
59
- category?: string;
60
- importance?: number; // 1-5
61
- }
62
- ```
63
-
64
- ### 输出
65
-
66
- ```ts
67
- interface MemoryUpdateOutput {
68
- id: string;
69
- sessionId: string;
70
- filePath: string;
71
- created: boolean;
72
- updated: boolean;
73
- memory: Memory;
74
- }
75
- ```
76
-
77
- ---
78
-
79
- ## Memory 数据模型
80
-
81
- ```ts
82
- interface Memory {
83
- id: string;
84
- createdAt: string;
85
- updatedAt: string;
86
- sessionId?: string;
87
- entryType?: EntryType;
88
- tags: string[];
89
- category: string;
90
- importance: number;
91
- title: string;
92
- content: string;
93
- }
94
- ```
95
-
96
- ---
97
-
98
- ## 存储路径契约(并发安全)
99
-
100
- 为避免多个 CLI 同日写入冲突,采用分层目录:
101
-
102
- ```text
103
- {storageRoot}/YYYY-MM-DD/{session_uuid}/{timestamp}-{slug}.md
104
- ```
105
-
106
- 例如:
107
-
108
- ```text
109
- memories/2026-03-03/550e8400-e29b-41d4-a716-446655440111/2026-03-03T16-40-12-123Z-task-summary.md
110
- ```
111
-
112
- ---
113
-
114
- ## 调用策略契约(强建议)
115
-
116
- - 用户输入后第一轮:调用 `memory_load`
117
- - 最终输出前最后一轮:调用 `memory_update`
118
-
119
- 详细策略见:`docs/tool-calling-policy.md`
1
+ # MemHub 契约文档(v0.2.0
2
+
3
+ 当前对外 MCP 工具采用简化的 2-tool 接口:
4
+
5
+ 1. `memory_load`(首轮):统一记忆加载接口
6
+ 2. `memory_update`(末轮):统一记忆回写接口
7
+
8
+ 目标是形成稳定闭环:**先读 STM,再回写 STM**。
9
+
10
+ ## 核心特性
11
+
12
+ - **向量语义搜索**: 支持基于 query 的语义相似度搜索
13
+ - **元数据过滤**: 支持按 tags、category、date 过滤
14
+ - **混合搜索**: 可组合向量搜索和元数据过滤
15
+ - **并发安全**: 按 session_uuid 分目录存储,支持多 CLI 并发
16
+
17
+ ---
18
+
19
+ ## 1) memory_load
20
+
21
+ 用于用户输入后第一轮主动加载短期记忆。支持向量语义搜索和元数据过滤。
22
+
23
+ ### 输入
24
+
25
+ ```ts
26
+ interface MemoryLoadInput {
27
+ id?: string; // 指定单条记忆 ID(优先级最高)
28
+ query?: string; // 语义搜索查询(启用向量搜索)
29
+ category?: string; // 分类过滤
30
+ tags?: string[]; // 标签过滤
31
+ limit?: number; // 返回数量限制,默认 20
32
+ }
33
+ ```
34
+
35
+ ### 行为说明
36
+
37
+ 1. **向量搜索** (当提供 `query` 时):
38
+ - 使用 ONNX 模型将 query 转换为 384 维向量
39
+ - 在 LanceDB 中搜索最相似的向量
40
+ - 返回按相似度排序的结果
41
+
42
+ 2. **元数据过滤** (当提供 `tags`、`category`、`date` 时):
43
+ - 在文件系统中扫描匹配的 Markdown 文件
44
+ - 解析 YAML Front Matter 进行过滤
45
+ - 支持多条件组合
46
+
47
+ 3. **混合模式**:
48
+ - 先进行向量搜索获取候选集
49
+ - 再按元数据条件过滤
50
+ - 结合相似度得分和匹配度排序
51
+
52
+ 4. **降级处理**:
53
+ - 向量搜索失败时自动降级为文本搜索
54
+ - 保证基本功能可用
55
+
56
+ ### 输出
57
+
58
+ ```ts
59
+ interface MemoryLoadOutput {
60
+ items: Memory[];
61
+ total: number;
62
+ }
63
+ ```
64
+
65
+ ---
66
+
67
+ ## 2) memory_update
68
+
69
+ 用于本轮结束前主动回写记忆。自动维护 Markdown 文件和向量索引。
70
+
71
+ ### 输入
72
+
73
+ ```ts
74
+ type EntryType = 'preference' | 'decision' | 'context' | 'fact';
75
+
76
+ interface MemoryUpdateInput {
77
+ id?: string; // 有则更新;无则创建新记录
78
+ sessionId?: string; // 无则服务端自动生成并返回
79
+ mode?: 'append' | 'upsert'; // 默认 append
80
+ entryType?: EntryType; // 记忆类型
81
+ title?: string; // 标题(Markdown H1)
82
+ content: string; // 内容(必填,Markdown 格式)
83
+ tags?: string[]; // 标签数组
84
+ category?: string; // 分类
85
+ importance?: number; // 重要性 1-5,默认 3
86
+ }
87
+ ```
88
+
89
+ ### 行为说明
90
+
91
+ 1. **Markdown 写入** (同步):
92
+ - 生成或更新 Markdown 文件
93
+ - 路径格式: `YYYY-MM-DD/session_uuid/timestamp-title-slug.md`
94
+ - 写入 YAML Front Matter 和 Markdown 正文
95
+
96
+ 2. **向量索引更新** (异步):
97
+ - 使用 Embedding 服务生成 384 维向量
98
+ - 在 LanceDB 中 upsert 向量记录
99
+ - 包含元数据字段用于过滤
100
+
101
+ 3. **并发安全**:
102
+ - 按 `session_uuid` 分目录,避免多 CLI 冲突
103
+ - 文件名包含时间戳,保证唯一性
104
+
105
+ 4. **容错处理**:
106
+ - 向量索引失败不影响 Markdown 写入
107
+ - 记录错误日志,不中断主流程
108
+
109
+ ### 输出
110
+
111
+ ```ts
112
+ interface MemoryUpdateOutput {
113
+ id: string;
114
+ sessionId: string;
115
+ filePath: string;
116
+ created: boolean;
117
+ updated: boolean;
118
+ memory: Memory;
119
+ }
120
+ ```
121
+
122
+ ---
123
+
124
+ ## Memory 数据模型
125
+
126
+ ```ts
127
+ type EntryType = 'preference' | 'decision' | 'context' | 'fact';
128
+
129
+ interface Memory {
130
+ id: string; // UUID v4
131
+ createdAt: string; // ISO 8601
132
+ updatedAt: string; // ISO 8601
133
+ sessionId?: string; // 会话 UUID
134
+ entryType?: EntryType; // 记忆类型
135
+ tags: string[]; // 标签数组
136
+ category: string; // 分类
137
+ importance: number; // 1-5
138
+ title: string; // Markdown H1 标题
139
+ content: string; // Markdown 正文
140
+ }
141
+ ```
142
+
143
+ ### EntryType 说明
144
+
145
+ - **preference**: 用户偏好和习惯
146
+ - **decision**: 技术决策及其理由
147
+ - **context**: 项目和环境信息
148
+ - **fact**: 客观知识和事实
149
+
150
+ ---
151
+
152
+ ## 存储路径契约(并发安全)
153
+
154
+ 为避免多个 CLI 同日写入冲突,采用分层目录:
155
+
156
+ ```text
157
+ {storageRoot}/YYYY-MM-DD/{session_uuid}/{timestamp}-{slug}.md
158
+ ```
159
+
160
+ 例如:
161
+
162
+ ```text
163
+ memories/2026-03-03/550e8400-e29b-41d4-a716-446655440111/2026-03-03T16-40-12-123Z-task-summary.md
164
+ ```
165
+
166
+ ### 向量索引存储
167
+
168
+ 向量数据存储在独立的 LanceDB 目录中:
169
+
170
+ ```text
171
+ {storageRoot}/.lancedb/
172
+ ├── versions/
173
+ ├── manifest.json
174
+ └── ...
175
+ ```
176
+
177
+ **重要特性**:
178
+
179
+ - Markdown 文件是唯一数据源
180
+ - 向量索引可随时从 Markdown 重建
181
+ - 删除 `.lancedb/` 目录不影响数据完整性
182
+
183
+ ---
184
+
185
+ ## 调用策略契约(强建议)
186
+
187
+ - 用户输入后第一轮:调用 `memory_load`
188
+ - 最终输出前最后一轮:调用 `memory_update`
189
+
190
+ 详细策略见:`docs/tool-calling-policy.md`
@@ -1,79 +1,33 @@
1
- # Prompt Template for Coding Agents (MemHub STM Loop)
2
-
3
- Use this template in Codex / Claude Code / OpenCode system prompt or task preamble.
4
-
5
- ---
6
-
7
- ## System Rule: STM Closed Loop
8
-
9
- You are connected to MemHub MCP.
10
-
11
- ### Mandatory tool-calling behavior
12
-
13
- 1. **First round after receiving user prompt**: call `memory_load`.
14
- 2. **Final round before sending final answer**: call `memory_update`.
15
-
16
- Do not skip these two calls unless tool is unavailable.
17
-
18
- ---
19
-
20
- ## Tool usage policy
21
-
22
- ### On first round (`memory_load`)
23
-
24
- Call with the most specific context available:
25
-
26
- ```json
27
- {
28
- "sessionId": "<session-uuid-if-known>",
29
- "scope": "stm",
30
- "limit": 20
31
- }
32
- ```
33
-
34
- If task is date-scoped, add `date: "YYYY-MM-DD"`.
35
- If task is keyword-driven, add `query`.
36
-
37
- ### On final round (`memory_update`)
38
-
39
- Write only high-value context likely reused in next 3 turns:
40
-
41
- - decisions
42
- - preference changes
43
- - constraints
44
- - task state changes
45
- - reusable conclusions
46
-
47
- Example:
48
-
49
- ```json
50
- {
51
- "sessionId": "<session-uuid-if-known>",
52
- "mode": "append",
53
- "entryType": "decision",
54
- "title": "Storage architecture decision",
55
- "content": "Use date/session_uuid nested markdown storage to avoid multi-CLI collision.",
56
- "tags": ["architecture", "storage", "stm"],
57
- "category": "engineering",
58
- "importance": 4
59
- }
60
- ```
61
-
62
- ---
63
-
64
- ## Minimal execution checklist
65
-
66
- - [ ] First tool call is `memory_load`
67
- - [ ] Final tool call is `memory_update`
68
- - [ ] `memory_update` content is concise and reusable
69
- - [ ] No sensitive secrets in memory payload
70
-
71
- ---
72
-
73
- ## Failure fallback
74
-
75
- If tool call fails:
76
-
77
- 1. continue task execution
78
- 2. mention memory tool failure briefly in internal reasoning/logs
79
- 3. still provide final user answer
1
+ # Prompt Template for Coding Agents (MemHub)
2
+
3
+ ## Why Memory Matters
4
+
5
+ You have access to persistent memory across conversations. Use it wisely:
6
+
7
+ - **Remember preferences** Learn what the user likes and avoid repeating mistakes
8
+ - **Recall decisions** — Build on past reasoning instead of starting from scratch
9
+ - **Store context** Project knowledge that survives session boundaries
10
+
11
+ ## When to Use
12
+
13
+ ### `memory_load`
14
+
15
+ Call when you need context from past conversations:
16
+ - User references something from before
17
+ - You're unsure about user preferences
18
+ - A decision needs historical context
19
+
20
+ Don't call for simple, self-contained tasks.
21
+
22
+ ### `memory_update`
23
+
24
+ Call when you discover something worth remembering:
25
+ - User expresses a preference
26
+ - You made a significant decision with reasoning
27
+ - Project context changed
28
+
29
+ Don't call for temporary or one-time information.
30
+
31
+ ## Principle
32
+
33
+ Memory should feel natural — triggered by context, not by schedule. When in doubt, ask: "Would future me benefit from knowing this?"