memorix 0.7.8 → 0.7.10
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.
- package/CHANGELOG.md +15 -0
- package/README.md +28 -1
- package/README.zh-CN.md +360 -0
- package/dist/cli/index.js +96 -10
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +52 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.7.10] — 2026-02-24
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **Chinese README** (`README.zh-CN.md`) — Full bilingual documentation with language switcher at the top of both README files.
|
|
9
|
+
- **Antigravity config guide** — Collapsible note in README Quick Start and updated `docs/SETUP.md` Antigravity section explaining the `MEMORIX_PROJECT_ROOT` requirement, why it's needed (cwd + MCP roots both unavailable), and how to configure it.
|
|
10
|
+
- **Project detection priority documentation** — Clear detection chain (`--cwd` → `MEMORIX_PROJECT_ROOT` → `INIT_CWD` → `process.cwd()` → MCP roots → error) in README, SETUP.md, and troubleshooting section.
|
|
11
|
+
|
|
12
|
+
## [0.7.9] — 2026-02-24
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
- **Dashboard auto-switch when project changes** — When the dashboard is already running (started from project A) and `memorix_dashboard` is called from project B, the dashboard server's current project is now updated via a `/api/set-current-project` POST request before opening the browser. Previously, the dashboard always showed the project it was initially started with; now it correctly switches to the calling project. Existing browser tabs will also show the correct project on the next page load/refresh.
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- **MCP roots protocol support** — When the IDE's `cwd` is not a valid project (e.g., Antigravity sets cwd to `G:\Antigravity`), Memorix now automatically tries the MCP `roots/list` protocol to get the IDE's actual workspace path. This means standard MCP configs (`npx memorix@latest serve`) can work without `--cwd` in IDEs that support MCP roots. Falls back gracefully if the client doesn't support roots. Priority chain: `--cwd` > `MEMORIX_PROJECT_ROOT` > `INIT_CWD` > `process.cwd()` > **MCP roots** > error.
|
|
19
|
+
|
|
5
20
|
## [0.7.8] — 2026-02-24
|
|
6
21
|
|
|
7
22
|
### Fixed
|
package/README.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
<img src="assets/logo.png" alt="Memorix Logo" width="120">
|
|
3
3
|
<h1 align="center">Memorix</h1>
|
|
4
4
|
<p align="center"><strong>Cross-Agent Memory Bridge — Your AI never forgets again</strong></p>
|
|
5
|
+
<p align="center"><a href="README.zh-CN.md">中文文档</a> | English</p>
|
|
5
6
|
<p align="center">
|
|
6
7
|
<a href="https://www.npmjs.com/package/memorix"><img src="https://img.shields.io/npm/v/memorix.svg?style=flat-square&color=cb3837" alt="npm version"></a>
|
|
7
8
|
<a href="https://www.npmjs.com/package/memorix"><img src="https://img.shields.io/npm/dm/memorix.svg?style=flat-square&color=blue" alt="npm downloads"></a>
|
|
@@ -62,10 +63,33 @@ Add this to your agent's MCP config file, restart — done:
|
|
|
62
63
|
```
|
|
63
64
|
|
|
64
65
|
> 📖 **Where is my config file?** → [Full setup guide for all 7 agents](docs/SETUP.md)
|
|
65
|
-
> Windsurf • Cursor • Claude Code • Codex • VS Code Copilot •
|
|
66
|
+
> Windsurf • Cursor • Claude Code • Codex • VS Code Copilot • Kiro • Antigravity
|
|
66
67
|
|
|
67
68
|
That's it. No API keys. No cloud accounts. No dependencies. Just works.
|
|
68
69
|
|
|
70
|
+
<details>
|
|
71
|
+
<summary>⚠️ <strong>Antigravity users: extra config required</strong></summary>
|
|
72
|
+
|
|
73
|
+
Antigravity sets its working directory to its own install path (e.g., `G:\Antigravity`) instead of your project directory, and does not support the MCP roots protocol. You **must** add `MEMORIX_PROJECT_ROOT`:
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"mcpServers": {
|
|
78
|
+
"memorix": {
|
|
79
|
+
"command": "npx",
|
|
80
|
+
"args": ["-y", "memorix@latest", "serve"],
|
|
81
|
+
"env": {
|
|
82
|
+
"MEMORIX_PROJECT_ROOT": "E:/your/project/path"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
You'll need to update `MEMORIX_PROJECT_ROOT` when switching projects. All other IDEs work without this.
|
|
90
|
+
|
|
91
|
+
</details>
|
|
92
|
+
|
|
69
93
|
---
|
|
70
94
|
|
|
71
95
|
## 🎬 Real-World Scenarios
|
|
@@ -259,10 +283,13 @@ With vector search, queries like "authentication" also match memories about "log
|
|
|
259
283
|
## 🔒 Project Isolation
|
|
260
284
|
|
|
261
285
|
- **Auto-detected** — Project identity from `git remote` URL, zero config needed
|
|
286
|
+
- **MCP roots fallback** — If `cwd` is not a project (e.g., Antigravity), Memorix tries the [MCP roots protocol](https://modelcontextprotocol.io/docs/concepts/roots) to get your workspace path from the IDE
|
|
262
287
|
- **Per-project storage** — `~/.memorix/data/<owner--repo>/` per project
|
|
263
288
|
- **Scoped search** — Defaults to current project; `scope: "global"` to search all
|
|
264
289
|
- **Zero cross-contamination** — Project A's decisions never leak into project B
|
|
265
290
|
|
|
291
|
+
**Detection priority:** `--cwd` → `MEMORIX_PROJECT_ROOT` → `INIT_CWD` → `process.cwd()` → MCP roots → error
|
|
292
|
+
|
|
266
293
|
---
|
|
267
294
|
|
|
268
295
|
## ❓ Frequently Asked Questions
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/logo.png" alt="Memorix Logo" width="120">
|
|
3
|
+
<h1 align="center">Memorix</h1>
|
|
4
|
+
<p align="center"><strong>跨 Agent 记忆桥梁 — 让你的 AI 再也不会忘记</strong></p>
|
|
5
|
+
<p align="center">中文文档 | <a href="README.md">English</a></p>
|
|
6
|
+
<p align="center">
|
|
7
|
+
<a href="https://www.npmjs.com/package/memorix"><img src="https://img.shields.io/npm/v/memorix.svg?style=flat-square&color=cb3837" alt="npm version"></a>
|
|
8
|
+
<a href="https://www.npmjs.com/package/memorix"><img src="https://img.shields.io/npm/dm/memorix.svg?style=flat-square&color=blue" alt="npm downloads"></a>
|
|
9
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache%202.0-green.svg?style=flat-square" alt="License"></a>
|
|
10
|
+
<a href="https://github.com/AVIDS2/memorix"><img src="https://img.shields.io/github/stars/AVIDS2/memorix?style=flat-square&color=yellow" alt="GitHub stars"></a>
|
|
11
|
+
<img src="https://img.shields.io/badge/tests-422%20passed-brightgreen?style=flat-square" alt="Tests">
|
|
12
|
+
</p>
|
|
13
|
+
<p align="center">
|
|
14
|
+
<img src="https://img.shields.io/badge/Works%20with-Cursor-orange?style=flat-square" alt="Cursor">
|
|
15
|
+
<img src="https://img.shields.io/badge/Works%20with-Windsurf-blue?style=flat-square" alt="Windsurf">
|
|
16
|
+
<img src="https://img.shields.io/badge/Works%20with-Claude%20Code-purple?style=flat-square" alt="Claude Code">
|
|
17
|
+
<img src="https://img.shields.io/badge/Works%20with-Codex-green?style=flat-square" alt="Codex">
|
|
18
|
+
<img src="https://img.shields.io/badge/Works%20with-Copilot-lightblue?style=flat-square" alt="Copilot">
|
|
19
|
+
<img src="https://img.shields.io/badge/Works%20with-Kiro-red?style=flat-square" alt="Kiro">
|
|
20
|
+
<img src="https://img.shields.io/badge/Works%20with-Antigravity-grey?style=flat-square" alt="Antigravity">
|
|
21
|
+
</p>
|
|
22
|
+
<p align="center">
|
|
23
|
+
<a href="#-别再反复解释你的项目了">痛点</a> •
|
|
24
|
+
<a href="#-30-秒快速开始">快速开始</a> •
|
|
25
|
+
<a href="#-真实使用场景">场景</a> •
|
|
26
|
+
<a href="#-memorix-能做什么">功能</a> •
|
|
27
|
+
<a href="#-与同类工具对比">对比</a> •
|
|
28
|
+
<a href="docs/SETUP.md">完整配置指南</a>
|
|
29
|
+
</p>
|
|
30
|
+
</p>
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 😤 别再反复解释你的项目了
|
|
35
|
+
|
|
36
|
+
你的 AI 助手每次新对话都会忘记一切。你要花 10 分钟重新解释架构。**又一次。** 如果从 Cursor 切到 Claude Code?所有上下文全部丢失。**又一次。**
|
|
37
|
+
|
|
38
|
+
| 没有 Memorix | 有 Memorix |
|
|
39
|
+
|-------------|-----------|
|
|
40
|
+
| **第 2 次对话:** "我们的技术栈是什么?" | **第 2 次对话:** "我记得——Next.js + Prisma + tRPC。接下来做什么?" |
|
|
41
|
+
| **切换 IDE:** 全部上下文丢失 | **切换 IDE:** 上下文立即跟随 |
|
|
42
|
+
| **新同事的 AI:** 从零开始 | **新同事的 AI:** 已了解整个代码库 |
|
|
43
|
+
| **50 次工具调用后:** 上下文爆炸,需要重开 | **重开后:** 无缝恢复到上次状态 |
|
|
44
|
+
| **MCP 配置:** 在 7 个 IDE 之间手动复制粘贴 | **MCP 配置:** 一条命令全部同步 |
|
|
45
|
+
|
|
46
|
+
**Memorix 解决所有这些问题。** 一个 MCP 服务器。七个 Agent。零上下文丢失。
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## ⚡ 30 秒快速开始
|
|
51
|
+
|
|
52
|
+
在你的 Agent 的 MCP 配置文件中添加以下内容,重启即可:
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"mcpServers": {
|
|
57
|
+
"memorix": {
|
|
58
|
+
"command": "npx",
|
|
59
|
+
"args": ["-y", "memorix@latest", "serve"]
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
> 📖 **配置文件在哪里?** → [7 个 Agent 的完整配置指南](docs/SETUP.md)
|
|
66
|
+
> Windsurf • Cursor • Claude Code • Codex • VS Code Copilot • Kiro • Antigravity
|
|
67
|
+
|
|
68
|
+
就是这样。不需要 API Key,不需要云账号,不需要额外依赖。开箱即用。
|
|
69
|
+
|
|
70
|
+
<details>
|
|
71
|
+
<summary>⚠️ <strong>Antigravity 用户:需要额外配置</strong></summary>
|
|
72
|
+
|
|
73
|
+
Antigravity 会将工作目录设为自身安装路径(如 `G:\Antigravity`),而不是你的项目目录,且不支持 MCP roots 协议。你**必须**添加 `MEMORIX_PROJECT_ROOT`:
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"mcpServers": {
|
|
78
|
+
"memorix": {
|
|
79
|
+
"command": "npx",
|
|
80
|
+
"args": ["-y", "memorix@latest", "serve"],
|
|
81
|
+
"env": {
|
|
82
|
+
"MEMORIX_PROJECT_ROOT": "E:/your/project/path"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
切换项目时需要更新 `MEMORIX_PROJECT_ROOT`。其他所有 IDE 都不需要这个配置。
|
|
90
|
+
|
|
91
|
+
</details>
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## 🎬 真实使用场景
|
|
96
|
+
|
|
97
|
+
### 场景 1:跨会话记忆
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
周一早上 — 你和 Cursor 讨论认证架构:
|
|
101
|
+
你: "用 JWT + refresh token,15 分钟过期"
|
|
102
|
+
→ Memorix 自动存储为 🟤 决策
|
|
103
|
+
|
|
104
|
+
周二 — 新的 Cursor 会话:
|
|
105
|
+
你: "添加登录接口"
|
|
106
|
+
→ AI 调用 memorix_search("auth") → 找到周一的决策
|
|
107
|
+
→ "好的,我按之前的决策用 JWT + 15 分钟 refresh token 来实现"
|
|
108
|
+
→ 零重复解释!
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### 场景 2:跨 Agent 协作
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
你用 Windsurf 写后端,用 Claude Code 做代码审查:
|
|
115
|
+
|
|
116
|
+
Windsurf: 你修复了支付模块的一个竞态条件
|
|
117
|
+
→ Memorix 存储为 🟡 问题-解决方案,包含修复细节
|
|
118
|
+
|
|
119
|
+
Claude Code: "审查支付模块"
|
|
120
|
+
→ AI 调用 memorix_search("payment") → 找到竞态条件修复
|
|
121
|
+
→ "我看到最近有个竞态条件修复,让我确认一下是否正确..."
|
|
122
|
+
→ 知识在 Agent 之间无缝流转!
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### 场景 3:踩坑预防
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
第 1 周: 你遇到一个 Windows 路径分隔符 bug
|
|
129
|
+
→ Memorix 存储为 🔴 gotcha:"用 path.join(),永远不要字符串拼接"
|
|
130
|
+
|
|
131
|
+
第 3 周: AI 正要写 `baseDir + '/' + filename`
|
|
132
|
+
→ 会话启动 hook 已将 gotcha 注入到上下文中
|
|
133
|
+
→ AI 改写为 `path.join(baseDir, filename)`
|
|
134
|
+
→ bug 在发生前就被阻止了!
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### 场景 4:跨 IDE 工作区同步
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
你在 Cursor 里配置了 12 个 MCP 服务器。
|
|
141
|
+
现在想试试 Kiro。
|
|
142
|
+
|
|
143
|
+
你: "把我的工作区同步到 Kiro"
|
|
144
|
+
→ memorix_workspace_sync 扫描 Cursor 的 MCP 配置
|
|
145
|
+
→ 生成 Kiro 兼容的 .kiro/settings/mcp.json
|
|
146
|
+
→ 同时同步你的规则、技能和工作流
|
|
147
|
+
→ Kiro 几秒内就绑定好了,不用花几个小时!
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### 场景 5:自动生成项目技能
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
开发两周后,你有了 50+ 条观察记录:
|
|
154
|
+
- 8 个关于 Windows 路径问题的 gotcha
|
|
155
|
+
- 5 个关于认证模块的决策
|
|
156
|
+
- 3 个数据库迁移的问题-解决方案
|
|
157
|
+
|
|
158
|
+
你: "生成项目技能"
|
|
159
|
+
→ memorix_skills 按实体聚类观察记录
|
|
160
|
+
→ 自动生成 SKILL.md 文件:
|
|
161
|
+
- "auth-module-guide.md" — JWT 设置、刷新流程、常见陷阱
|
|
162
|
+
- "database-migrations.md" — Prisma 模式、回滚策略
|
|
163
|
+
→ 同步技能到任何 Agent:Cursor、Claude Code、Kiro...
|
|
164
|
+
→ 新同事的 AI 立即掌握你项目的最佳实践!
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## 🧠 Memorix 能做什么
|
|
170
|
+
|
|
171
|
+
### 智能记忆(17 个 MCP 工具)
|
|
172
|
+
|
|
173
|
+
| 你说的 | Memorix 做的 |
|
|
174
|
+
|--------|-------------|
|
|
175
|
+
| "记住这个架构决策" | `memorix_store` — 分类为 🟤 决策,提取实体,创建图关系 |
|
|
176
|
+
| "我们之前关于认证决定了什么?" | `memorix_search` → `memorix_detail` — 3 层渐进式展示,节省约 10 倍 token |
|
|
177
|
+
| "那个 bug 修复前后发生了什么?" | `memorix_timeline` — 按时间显示前后上下文 |
|
|
178
|
+
| "显示知识图谱" | `memorix_dashboard` — 打开交互式 Web UI,含 D3.js 图谱 |
|
|
179
|
+
| "哪些记忆快过期了?" | `memorix_retention` — 指数衰减评分,识别归档候选 |
|
|
180
|
+
|
|
181
|
+
### 跨 Agent 工作区同步
|
|
182
|
+
|
|
183
|
+
| 你说的 | Memorix 做的 |
|
|
184
|
+
|--------|-------------|
|
|
185
|
+
| "把 MCP 服务器同步到 Kiro" | `memorix_workspace_sync` — 迁移配置,合并(永不覆盖) |
|
|
186
|
+
| "检查我的 Agent 规则" | `memorix_rules_sync` — 扫描 7 个 Agent,去重,检测冲突 |
|
|
187
|
+
| "为 Cursor 生成规则" | `memorix_rules_sync` — 跨格式转换(`.mdc` ↔ `CLAUDE.md` ↔ `.kiro/steering/`) |
|
|
188
|
+
| "生成项目技能" | `memorix_skills` — 从观察模式创建 SKILL.md |
|
|
189
|
+
| "注入认证技能" | `memorix_skills` — 将技能内容直接返回到 Agent 上下文 |
|
|
190
|
+
|
|
191
|
+
### 知识图谱(兼容 MCP 官方接口)
|
|
192
|
+
|
|
193
|
+
| 工具 | 功能 |
|
|
194
|
+
|------|-----|
|
|
195
|
+
| `create_entities` | 构建项目知识图谱 |
|
|
196
|
+
| `create_relations` | 用类型化边连接实体(causes、fixes、depends_on) |
|
|
197
|
+
| `add_observations` | 将观察附加到实体 |
|
|
198
|
+
| `search_nodes` / `open_nodes` | 查询图谱 |
|
|
199
|
+
| `read_graph` | 导出完整图谱用于可视化 |
|
|
200
|
+
|
|
201
|
+
> **即插即用**,兼容 [MCP 官方 Memory Server](https://github.com/modelcontextprotocol/servers/tree/main/src/memory) — 相同 API,更多功能。
|
|
202
|
+
|
|
203
|
+
### 9 种观察类型
|
|
204
|
+
|
|
205
|
+
每条记忆都有分类标签,用于智能检索:
|
|
206
|
+
|
|
207
|
+
| 图标 | 类型 | 使用场景 |
|
|
208
|
+
|------|------|---------|
|
|
209
|
+
| 🎯 | `session-request` | 本次会话的原始任务/目标 |
|
|
210
|
+
| 🔴 | `gotcha` | 关键陷阱 — "永远不要做 X,因为 Y" |
|
|
211
|
+
| 🟡 | `problem-solution` | bug 修复,含根因和解决方案 |
|
|
212
|
+
| 🔵 | `how-it-works` | 系统的技术解释 |
|
|
213
|
+
| 🟢 | `what-changed` | 代码/配置变更记录 |
|
|
214
|
+
| 🟣 | `discovery` | 新的洞见或发现 |
|
|
215
|
+
| 🟠 | `why-it-exists` | 设计选择背后的原因 |
|
|
216
|
+
| 🟤 | `decision` | 架构/设计决策 |
|
|
217
|
+
| ⚖️ | `trade-off` | 取舍权衡,含利弊分析 |
|
|
218
|
+
|
|
219
|
+
### 可视化 Dashboard
|
|
220
|
+
|
|
221
|
+
运行 `memorix_dashboard` 在 `http://localhost:3210` 打开 Web UI:
|
|
222
|
+
|
|
223
|
+
- **交互式知识图谱** — D3.js 力导向图,可视化实体和关系
|
|
224
|
+
- **观察浏览器** — 按类型筛选,高亮搜索,展开/折叠详情
|
|
225
|
+
- **记忆衰减面板** — 查看哪些记忆活跃、过期或待归档
|
|
226
|
+
- **项目切换器** — 无需切换 IDE 即可查看任何项目的数据
|
|
227
|
+
- **批量清理** — 自动检测并批量删除低质量观察
|
|
228
|
+
- **明暗主题** — 玻璃拟态设计,中英双语界面
|
|
229
|
+
|
|
230
|
+
### 自动记忆 Hook
|
|
231
|
+
|
|
232
|
+
Memorix 可以**自动捕获**编码会话中的决策、错误和踩坑经验:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
memorix hooks install # 一条命令安装
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
- **隐式记忆** — 检测 "I decided to..."、"bug 是因为..."、"永远不要用 X" 等模式
|
|
239
|
+
- **会话启动注入** — 自动将近期高价值记忆加载到 Agent 上下文
|
|
240
|
+
- **多语言** — 支持英文 + 中文关键词匹配
|
|
241
|
+
- **智能过滤** — 30 秒冷却,跳过无关命令(ls、cat、pwd)
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## 📊 与同类工具对比
|
|
246
|
+
|
|
247
|
+
| | [Mem0](https://github.com/mem0ai/mem0) | [mcp-memory-service](https://github.com/doobidoo/mcp-memory-service) | [claude-mem](https://github.com/anthropics/claude-code) | **Memorix** |
|
|
248
|
+
|---|---|---|---|---|
|
|
249
|
+
| **支持的 Agent** | SDK 集成 | 13+(MCP) | 仅 Claude Code | **7 个 IDE(MCP)** |
|
|
250
|
+
| **跨 Agent 同步** | 否 | 否 | 否 | **是(配置、规则、技能、工作流)** |
|
|
251
|
+
| **规则同步** | 否 | 否 | 否 | **是(7 种格式)** |
|
|
252
|
+
| **技能引擎** | 否 | 否 | 否 | **是(从记忆自动生成)** |
|
|
253
|
+
| **知识图谱** | 否 | 是 | 否 | **是(兼容 MCP 官方)** |
|
|
254
|
+
| **混合搜索** | 否 | 是 | 否 | **是(BM25 + 向量)** |
|
|
255
|
+
| **Token 高效** | 否 | 否 | 是(3 层) | **是(3 层渐进式展示)** |
|
|
256
|
+
| **自动记忆 Hook** | 否 | 否 | 是 | **是(多语言)** |
|
|
257
|
+
| **记忆衰减** | 否 | 是 | 否 | **是(指数衰减 + 豁免)** |
|
|
258
|
+
| **可视化面板** | 云端 UI | 是 | 否 | **是(Web UI + D3.js 图谱)** |
|
|
259
|
+
| **隐私** | 云端 | 本地 | 本地 | **100% 本地** |
|
|
260
|
+
| **费用** | 按量付费 | $0 | $0 | **$0** |
|
|
261
|
+
| **安装** | `pip install` | `pip install` | 内置于 Claude | **`npx memorix serve`** |
|
|
262
|
+
|
|
263
|
+
**Memorix 是唯一同时桥接记忆和工作区跨 Agent 共享的工具。**
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## 🔮 可选:向量搜索
|
|
268
|
+
|
|
269
|
+
开箱即用,Memorix 使用 BM25 全文搜索(对代码已经足够好)。一条命令添加语义搜索:
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
# 方案 A:原生速度(推荐)
|
|
273
|
+
npm install -g fastembed
|
|
274
|
+
|
|
275
|
+
# 方案 B:通用兼容
|
|
276
|
+
npm install -g @huggingface/transformers
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
有了向量搜索,"authentication" 这样的查询也能匹配到关于 "login flow" 的记忆。两种方案都 **100% 本地运行** — 零 API 调用,零费用。
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## 🔒 项目隔离
|
|
284
|
+
|
|
285
|
+
- **自动检测** — 通过 `git remote` URL 识别项目,零配置
|
|
286
|
+
- **MCP roots 回退** — 如果 `cwd` 不是项目目录(如 Antigravity),Memorix 会尝试 [MCP roots 协议](https://modelcontextprotocol.io/docs/concepts/roots) 从 IDE 获取工作区路径
|
|
287
|
+
- **按项目存储** — `~/.memorix/data/<owner--repo>/` 每个项目独立
|
|
288
|
+
- **作用域搜索** — 默认搜索当前项目;`scope: "global"` 搜索所有项目
|
|
289
|
+
- **零交叉污染** — 项目 A 的决策永远不会泄漏到项目 B
|
|
290
|
+
|
|
291
|
+
**检测优先级:** `--cwd` → `MEMORIX_PROJECT_ROOT` → `INIT_CWD` → `process.cwd()` → MCP roots → 报错
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
## ❓ 常见问题
|
|
296
|
+
|
|
297
|
+
**在 Cursor 和 Claude Code 之间切换时如何保持上下文?**
|
|
298
|
+
在两个 IDE 都安装 Memorix。它们共享相同的本地记忆目录 — 在 Cursor 中做的架构决策在 Claude Code 中立即可搜索,无需云同步。
|
|
299
|
+
|
|
300
|
+
**如何防止 AI 忘记之前的会话?**
|
|
301
|
+
Memorix 将观察记录持久存储在磁盘上。下次会话,AI 调用 `memorix_search` 即可检索之前的决策、踩坑和知识。配合自动记忆 Hook,甚至可以自动捕获上下文。
|
|
302
|
+
|
|
303
|
+
**如何在 IDE 之间同步 MCP 服务器配置?**
|
|
304
|
+
运行 `memorix_workspace_sync`,设置 action 为 `"migrate"`,指定目标 IDE。它会扫描源配置并生成兼容的目标配置 — 合并,永不覆盖。
|
|
305
|
+
|
|
306
|
+
**如何从 Cursor 迁移到 Windsurf / Kiro / Claude Code?**
|
|
307
|
+
Memorix 工作区同步可以迁移 MCP 配置、Agent 规则(`.mdc` ↔ `CLAUDE.md` ↔ `.kiro/steering/`)、技能和工作流。一条命令,几秒完成。
|
|
308
|
+
|
|
309
|
+
**有没有用于持久 AI 编码记忆的 MCP 服务器?**
|
|
310
|
+
有 — Memorix 是一个跨 Agent 记忆 MCP 服务器,支持 7 个 IDE,提供知识图谱、3 层渐进式搜索、工作区同步和自动生成项目技能。
|
|
311
|
+
|
|
312
|
+
**和 mcp-memory-service 有什么区别?**
|
|
313
|
+
两个都是优秀的记忆服务器。Memorix 额外提供:跨 Agent 工作区同步(MCP 配置、规则、技能)、从记忆模式自动生成项目技能、3 层 token 高效搜索、会话启动记忆注入 Hook。
|
|
314
|
+
|
|
315
|
+
**支持离线/本地运行吗?**
|
|
316
|
+
完全支持。所有数据存储在 `~/.memorix/data/`。无云端,无 API Key,无外部服务。可选的向量搜索也通过 ONNX/WASM 本地运行。
|
|
317
|
+
|
|
318
|
+
> 📖 AI 系统参考:查看 [`llms.txt`](llms.txt) 和 [`llms-full.txt`](llms-full.txt) 获取机器可读的项目文档。
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
## 🧑💻 开发
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
git clone https://github.com/AVIDS2/memorix.git
|
|
326
|
+
cd memorix
|
|
327
|
+
npm install
|
|
328
|
+
|
|
329
|
+
npm run dev # tsup 监听模式
|
|
330
|
+
npm test # vitest(422 个测试)
|
|
331
|
+
npm run lint # TypeScript 类型检查
|
|
332
|
+
npm run build # 生产构建
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
> 📚 **文档:** [架构设计](docs/ARCHITECTURE.md) • [API 参考](docs/API_REFERENCE.md) • [模块说明](docs/MODULES.md) • [设计决策](docs/DESIGN_DECISIONS.md) • [配置指南](docs/SETUP.md) • [已知问题与路线图](docs/KNOWN_ISSUES_AND_ROADMAP.md)
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
## 🙏 致谢
|
|
340
|
+
|
|
341
|
+
Memorix 站在这些优秀项目的肩膀上:
|
|
342
|
+
|
|
343
|
+
- [mcp-memory-service](https://github.com/doobidoo/mcp-memory-service) — 混合搜索、指数衰减、访问追踪
|
|
344
|
+
- [MemCP](https://github.com/maydali28/memcp) — MAGMA 四图、实体提取、保留生命周期
|
|
345
|
+
- [claude-mem](https://github.com/anthropics/claude-code) — 3 层渐进式展示
|
|
346
|
+
- [Mem0](https://github.com/mem0ai/mem0) — 记忆层架构模式
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
## 📄 许可证
|
|
351
|
+
|
|
352
|
+
Apache 2.0 — 详见 [LICENSE](LICENSE)
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
356
|
+
<p align="center">
|
|
357
|
+
<strong>Made with ❤️ by <a href="https://github.com/AVIDS2">AVIDS2</a></strong>
|
|
358
|
+
<br>
|
|
359
|
+
<sub>如果 Memorix 对你有帮助,欢迎在 GitHub 上给个 ⭐!</sub>
|
|
360
|
+
</p>
|
package/dist/cli/index.js
CHANGED
|
@@ -4412,13 +4412,47 @@ function openBrowser(url) {
|
|
|
4412
4412
|
exec(cmd, () => {
|
|
4413
4413
|
});
|
|
4414
4414
|
}
|
|
4415
|
+
function readBody(req) {
|
|
4416
|
+
return new Promise((resolve2, reject) => {
|
|
4417
|
+
const chunks = [];
|
|
4418
|
+
req.on("data", (c) => chunks.push(c));
|
|
4419
|
+
req.on("end", () => resolve2(Buffer.concat(chunks).toString("utf-8")));
|
|
4420
|
+
req.on("error", reject);
|
|
4421
|
+
});
|
|
4422
|
+
}
|
|
4415
4423
|
async function startDashboard(dataDir, port, staticDir, projectId, projectName, autoOpen = true) {
|
|
4416
4424
|
const resolvedStaticDir = staticDir;
|
|
4417
4425
|
const baseDir = getBaseDataDir();
|
|
4426
|
+
const state = { projectId, projectName, dataDir };
|
|
4418
4427
|
const server = createServer(async (req, res) => {
|
|
4419
4428
|
const url = req.url || "/";
|
|
4429
|
+
if (url.startsWith("/api/set-current-project") && req.method === "POST") {
|
|
4430
|
+
try {
|
|
4431
|
+
const body = JSON.parse(await readBody(req));
|
|
4432
|
+
if (body.projectId) {
|
|
4433
|
+
const sanitized = body.projectId.replace(/\//g, "--").replace(/[<>:"|?*\\]/g, "_");
|
|
4434
|
+
const candidateDir = path6.join(baseDir, sanitized);
|
|
4435
|
+
try {
|
|
4436
|
+
await fs4.access(candidateDir);
|
|
4437
|
+
} catch {
|
|
4438
|
+
sendError(res, `Project data directory not found: ${candidateDir}`, 404);
|
|
4439
|
+
return;
|
|
4440
|
+
}
|
|
4441
|
+
state.projectId = body.projectId;
|
|
4442
|
+
state.projectName = body.projectName || body.projectId.split("/").pop() || body.projectId;
|
|
4443
|
+
state.dataDir = candidateDir;
|
|
4444
|
+
console.error(`[dashboard] Switched current project to: ${state.projectId}`);
|
|
4445
|
+
sendJson(res, { ok: true, projectId: state.projectId, projectName: state.projectName });
|
|
4446
|
+
} else {
|
|
4447
|
+
sendError(res, "Missing projectId in body", 400);
|
|
4448
|
+
}
|
|
4449
|
+
} catch {
|
|
4450
|
+
sendError(res, "Invalid JSON body", 400);
|
|
4451
|
+
}
|
|
4452
|
+
return;
|
|
4453
|
+
}
|
|
4420
4454
|
if (url.startsWith("/api/")) {
|
|
4421
|
-
await handleApi(req, res, dataDir, projectId, projectName, baseDir);
|
|
4455
|
+
await handleApi(req, res, state.dataDir, state.projectId, state.projectName, baseDir);
|
|
4422
4456
|
} else {
|
|
4423
4457
|
await serveStatic(req, res, resolvedStaticDir);
|
|
4424
4458
|
}
|
|
@@ -4474,7 +4508,7 @@ __export(server_exports2, {
|
|
|
4474
4508
|
import { watch } from "fs";
|
|
4475
4509
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4476
4510
|
import { z } from "zod";
|
|
4477
|
-
async function createMemorixServer(cwd) {
|
|
4511
|
+
async function createMemorixServer(cwd, existingServer) {
|
|
4478
4512
|
const project = detectProject(cwd);
|
|
4479
4513
|
if (project.id === "__invalid__") {
|
|
4480
4514
|
const resolvedCwd = cwd ?? process.cwd();
|
|
@@ -4586,7 +4620,7 @@ async function createMemorixServer(cwd) {
|
|
|
4586
4620
|
} catch {
|
|
4587
4621
|
console.error(`[memorix] Warning: could not watch observations file for hot-reload`);
|
|
4588
4622
|
}
|
|
4589
|
-
const server = new McpServer({
|
|
4623
|
+
const server = existingServer ?? new McpServer({
|
|
4590
4624
|
name: "memorix",
|
|
4591
4625
|
version: "0.1.0"
|
|
4592
4626
|
});
|
|
@@ -5248,13 +5282,27 @@ ${skill.content}` }]
|
|
|
5248
5282
|
}, 1e3);
|
|
5249
5283
|
});
|
|
5250
5284
|
if (isAlive) {
|
|
5285
|
+
const http = await import("http");
|
|
5286
|
+
const postData = JSON.stringify({ projectId: project.id, projectName: project.name });
|
|
5287
|
+
await new Promise((resolve2) => {
|
|
5288
|
+
const req = http.request({
|
|
5289
|
+
hostname: "127.0.0.1",
|
|
5290
|
+
port: portNum,
|
|
5291
|
+
path: "/api/set-current-project",
|
|
5292
|
+
method: "POST",
|
|
5293
|
+
headers: { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(postData) }
|
|
5294
|
+
}, () => resolve2());
|
|
5295
|
+
req.on("error", () => resolve2());
|
|
5296
|
+
req.write(postData);
|
|
5297
|
+
req.end();
|
|
5298
|
+
});
|
|
5251
5299
|
const projectUrl = `${url}?project=${encodeURIComponent(project.id)}`;
|
|
5252
5300
|
const { exec: exec2 } = await import("child_process");
|
|
5253
5301
|
const cmd = process.platform === "win32" ? `start "" "${projectUrl}"` : process.platform === "darwin" ? `open "${projectUrl}"` : `xdg-open "${projectUrl}"`;
|
|
5254
5302
|
exec2(cmd, () => {
|
|
5255
5303
|
});
|
|
5256
5304
|
return {
|
|
5257
|
-
content: [{ type: "text", text: `Dashboard is already running at ${url}.
|
|
5305
|
+
content: [{ type: "text", text: `Dashboard is already running at ${url}. Switched to project: ${project.name} (${project.id}).` }]
|
|
5258
5306
|
};
|
|
5259
5307
|
}
|
|
5260
5308
|
console.error("[memorix] Dashboard process no longer running, restarting...");
|
|
@@ -5389,14 +5437,52 @@ var init_serve = __esm({
|
|
|
5389
5437
|
},
|
|
5390
5438
|
run: async ({ args }) => {
|
|
5391
5439
|
const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
|
|
5440
|
+
const { McpServer: McpServer2 } = await import("@modelcontextprotocol/sdk/server/mcp.js");
|
|
5392
5441
|
const { createMemorixServer: createMemorixServer2 } = await Promise.resolve().then(() => (init_server2(), server_exports2));
|
|
5393
|
-
const
|
|
5442
|
+
const { detectProject: detectProject2 } = await Promise.resolve().then(() => (init_detector(), detector_exports));
|
|
5443
|
+
let projectRoot = args.cwd || process.env.MEMORIX_PROJECT_ROOT || process.env.INIT_CWD || process.cwd();
|
|
5394
5444
|
console.error(`[memorix] Starting with cwd: ${projectRoot}`);
|
|
5395
|
-
const
|
|
5396
|
-
const
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5445
|
+
const earlyDetect = detectProject2(projectRoot);
|
|
5446
|
+
const needsRoots = earlyDetect.id === "__invalid__" || earlyDetect.id.startsWith("local/");
|
|
5447
|
+
if (needsRoots) {
|
|
5448
|
+
console.error(`[memorix] cwd is not a valid project, trying MCP roots protocol...`);
|
|
5449
|
+
const mcpServer = new McpServer2({ name: "memorix", version: "0.1.0" });
|
|
5450
|
+
const transport = new StdioServerTransport();
|
|
5451
|
+
await mcpServer.connect(transport);
|
|
5452
|
+
let rootResolved = false;
|
|
5453
|
+
try {
|
|
5454
|
+
const rootsResult = await Promise.race([
|
|
5455
|
+
mcpServer.server.listRoots(),
|
|
5456
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error("timeout")), 5e3))
|
|
5457
|
+
]);
|
|
5458
|
+
if (rootsResult && "roots" in rootsResult && Array.isArray(rootsResult.roots) && rootsResult.roots.length > 0) {
|
|
5459
|
+
const rootUri = rootsResult.roots[0].uri;
|
|
5460
|
+
if (rootUri.startsWith("file://")) {
|
|
5461
|
+
const urlPath = decodeURIComponent(new URL(rootUri).pathname);
|
|
5462
|
+
const normalizedPath = process.platform === "win32" && urlPath.match(/^\/[A-Za-z]:/) ? urlPath.slice(1) : urlPath;
|
|
5463
|
+
console.error(`[memorix] MCP client root: ${normalizedPath}`);
|
|
5464
|
+
projectRoot = normalizedPath;
|
|
5465
|
+
rootResolved = true;
|
|
5466
|
+
}
|
|
5467
|
+
}
|
|
5468
|
+
} catch {
|
|
5469
|
+
console.error(`[memorix] MCP roots not available (client may not support it)`);
|
|
5470
|
+
}
|
|
5471
|
+
if (!rootResolved && earlyDetect.id === "__invalid__") {
|
|
5472
|
+
console.error(`[memorix] ERROR: Could not detect a valid project.`);
|
|
5473
|
+
console.error(`[memorix] Fix: set --cwd or MEMORIX_PROJECT_ROOT, or use an IDE that supports MCP roots.`);
|
|
5474
|
+
process.exit(1);
|
|
5475
|
+
}
|
|
5476
|
+
const { projectId } = await createMemorixServer2(projectRoot, mcpServer);
|
|
5477
|
+
console.error(`[memorix] MCP Server running on stdio (project: ${projectId})`);
|
|
5478
|
+
console.error(`[memorix] Project root: ${projectRoot}`);
|
|
5479
|
+
} else {
|
|
5480
|
+
const { server, projectId } = await createMemorixServer2(projectRoot);
|
|
5481
|
+
const transport = new StdioServerTransport();
|
|
5482
|
+
await server.connect(transport);
|
|
5483
|
+
console.error(`[memorix] MCP Server running on stdio (project: ${projectId})`);
|
|
5484
|
+
console.error(`[memorix] Project root: ${projectRoot}`);
|
|
5485
|
+
}
|
|
5400
5486
|
}
|
|
5401
5487
|
});
|
|
5402
5488
|
}
|