@yottameta/yotta-memory 0.8.3 → 0.8.5
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 +17 -0
- package/README.md +30 -24
- package/README.zh-CN.md +32 -24
- package/SKILL.md +4 -4
- package/USER_GUIDE.md +4 -4
- package/bin/yotta-memory.js +74 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# 更新日志
|
|
2
2
|
|
|
3
|
+
## v0.8.5 (2026-08-29)
|
|
4
|
+
|
|
5
|
+
安全修复(SkillHub 安全扫描发现高危,修复后三源同步升版):
|
|
6
|
+
|
|
7
|
+
- **MCP 命令执行入口封死**:MCP `distill` 不再接受 `--model`(`callTool` 在工具边界直接拒绝),远端智能体无法再借 MCP 在引擎主机执行任意命令。
|
|
8
|
+
- **MCP 任意路径读写封死**:MCP `export` / `import` 的 `out` / `src` 必须落在记忆库根内(新增 `resolveWithinRoot` 校验,防 `..` 穿越),库外路径直接拒绝,与「远程只能读写记忆」承诺对齐。
|
|
9
|
+
- **CLI 参数解析修复**:`--model` / `--subject` / `--reason` / `--merge` 此前被 valueOpts 消费但未写入 opts,导致 `distill --model` / `--subject` 实际不生效;本版补齐映射,CLI `distill --model` 现已真正走 `runDistillModel` 安全路径(`shell:false` + 允许清单)。
|
|
10
|
+
- **CLI distill 去 shell 注入**:`distill --model` 改走 `runDistillModel` —— `spawnSync(argv[0], argv.slice(1), { shell:false, windowsHide:true })` + `splitCommandArgv` 拆分 argv,彻底移除 shell 注入面;新增 `distillModelAllowlist`(环境变量 `YOTTA_DISTILL_MODELS` 或 `config.distill_models`,未配置时放行本地 CLI,但已无 shell 注入;MCP 层已直接禁 `--model`,不达此处)。
|
|
11
|
+
- 版本对齐:package.json / SKILL.md / CHANGELOG / 引擎 VERSION / 文档边界说明 = 0.8.5。
|
|
12
|
+
- 新增回归测试:`test/security-boundary.test.js`(MCP 禁 --model / export-import 限库内 / 合法操作仍可用,6 项断言)。
|
|
13
|
+
## v0.8.4 (2026-08-29)
|
|
14
|
+
|
|
15
|
+
- 安装方式统一为四方式(对齐发布规范 §3.3.1):方式一 `npx -y @yottameta/yotta-memory --agent <name>` / `--dir <dir>`(推荐,走 npm 源);方式二 `git clone https://github.com/YottaMeta/yotta-memory.git`;方式三 GitHub Download ZIP;方式四 `bash install.sh --agent/--dir/--list`。移除 `npx skills` 与 `-g` 推荐;中英双 README 安装节同步。
|
|
16
|
+
- 版本对齐:package.json / SKILL.md / CHANGELOG / 引擎 VERSION / 测试断言 / README 锚点 = 0.8.4。
|
|
17
|
+
- 修复:SKILL.md / USER_GUIDE.md 安装命令改 `--agent <name>` 合规形式(`npx -y --package @yottameta/yotta-memory yotta-memory-install --agent <name>`),移除 `-g` 与 `npx skills` 推荐。
|
|
18
|
+
- 无功能变更(仅文档与版本同步)。
|
|
19
|
+
|
|
3
20
|
## v0.8.3 (2026-08-28)
|
|
4
21
|
|
|
5
22
|
中英双语 README 对齐(老张拍板「英文门面 + 中文全档」):
|
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
> 📖 The user-facing operations manual lives in [USER_GUIDE.md](USER_GUIDE.md).
|
|
25
25
|
|
|
26
|
-
> 🆕 **v0.8.
|
|
26
|
+
> 🆕 **v0.8.5**: security hardening — MCP `distill` no longer accepts `--model`; MCP `export` / `import` paths are restricted to the memory root; CLI `distill --model` no longer shells out (allowlist-based).
|
|
27
27
|
|
|
28
28
|
## Core value
|
|
29
29
|
|
|
@@ -93,7 +93,7 @@ Each agent has a globally unique agent ID: it is the ownership key for private m
|
|
|
93
93
|
- `maintain`: unified utility score (final score = confidence + usage + recency + type + structure) × weight; low-utility + over-age auto-archive; extreme low value listed as forget candidates (not really deleted by default; `--purge` deletes); `--dedup` dedup candidates; `--merge A,B` manual merge. Dry-run preview by default, `--apply` to execute; immutable / BOUND exempt; audit writes `.archive/audit-<date>.jsonl`.
|
|
94
94
|
- `archive`: moves low-value old memory into `.archive/` by "unified utility score + age" (immutable excluded) so the store never grows without bound.
|
|
95
95
|
- `feedback`: explicit usage feedback loop — useful → weight ×1.2 (cap 3.0) + confidence +0.05 + feedback_net +1; useless → weight ×0.8 (floor 0.2) + confidence −0.05 + feedback_net −1; `--undo` rolls back; audit writes `.archive/feedback-<date>.jsonl`.
|
|
96
|
-
- `distill`: psychological-log distillation — statistical summary (type / age / heat / feedback) + topic profile (clustered by subject) + knowledge map (type → tags); optional `--model <cmd>` external model stdin→stdout refinement; output to `private/<owner>/distills/` or `facts/distills/`.
|
|
96
|
+
- `distill`: psychological-log distillation — statistical summary (type / age / heat / feedback) + topic profile (clustered by subject) + knowledge map (type → tags); optional `--model <cmd>` external model stdin→stdout refinement (local CLI only; MCP distill does not expose `--model`); output to `private/<owner>/distills/` or `facts/distills/`.
|
|
97
97
|
- `explain`: view a single memory's utility components and archive / forget status decision.
|
|
98
98
|
- `forget`: delete a single memory (by type-dir path or file name).
|
|
99
99
|
- `reindex`: rebuild the index after manually editing `.md` files.
|
|
@@ -117,34 +117,40 @@ Each agent has a globally unique agent ID: it is the ownership key for private m
|
|
|
117
117
|
|
|
118
118
|
## Install
|
|
119
119
|
|
|
120
|
-
|
|
120
|
+
Yotta Memory ships as a **CLI + skill** pair: the `yotta-memory` command reads/writes the memory store, and the skill teaches agents the workflow. Pick any of the four methods below; the order is the recommended priority. Skill files always come from **npm** (GitHub can be slow without a proxy; npm supports mirrors).
|
|
121
121
|
|
|
122
|
-
### Method 1:
|
|
123
|
-
|
|
124
|
-
|
|
122
|
+
### Method 1: npm one-liner (recommended)
|
|
123
|
+
|
|
124
|
+
```text
|
|
125
|
+
# Optional China mirror: npm config set registry https://registry.npmmirror.com
|
|
126
|
+
npx -y --package @yottameta/yotta-memory yotta-memory-install --agent <agent-name> # install the skill to the agent's default user-level dir
|
|
127
|
+
npx -y --package @yottameta/yotta-memory yotta-memory-install --dir <your-skills-dir> # point to the skills dir itself (e.g. ~/.codex/skills)
|
|
125
128
|
```
|
|
126
|
-
> Auto-installs the skill files into detected agents (Claude Code / Codex / Cursor / OpenCode and 78+ more). This installs only the skill instructions (SKILL.md etc.); to use the `yotta-memory` read/write commands you also need the CLI: `npm install -g @yottameta/yotta-memory` (see method 2).
|
|
127
129
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
npm install -g @yottameta/yotta-memory
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
130
|
+
- `--agent <name>` installs to that agent's default user-level directory; `--list` shows each agent's default directory.
|
|
131
|
+
- `--dir <path>` installs to the given directory; for agents not in the preset list, point `--dir` at their skills directory.
|
|
132
|
+
- If the mirror has not synced the new package (404): add `--registry=https://registry.npmjs.org/` (a proxy may be needed in China), or wait for the mirror cache.
|
|
133
|
+
- To read/write memories, also install the CLI: `npm install -g @yottameta/yotta-memory` (see the CLI usage section below).
|
|
134
|
+
|
|
135
|
+
### Method 2: git clone (developers / git available)
|
|
136
|
+
|
|
137
|
+
```text
|
|
138
|
+
git clone https://github.com/YottaMeta/yotta-memory.git <your-skills-dir>/yotta-memory
|
|
135
139
|
```
|
|
136
140
|
|
|
137
|
-
|
|
141
|
+
### Method 3: GitHub Download ZIP (manual / no git)
|
|
138
142
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
bash install.sh --
|
|
143
|
+
On the GitHub repository `YottaMeta/yotta-memory`, click **Code → Download ZIP**, unzip it and put the `yotta-memory` folder into the agent's skills directory.
|
|
144
|
+
|
|
145
|
+
### Method 4: install.sh (multi-agent one-liner script)
|
|
146
|
+
|
|
147
|
+
```text
|
|
148
|
+
bash install.sh --agent <name> # install to the agent's default user-level directory
|
|
149
|
+
bash install.sh --dir <path> # install to the given directory
|
|
150
|
+
bash install.sh --list # list agents -> default directories
|
|
145
151
|
```
|
|
146
|
-
You can also copy the whole `yotta-memory` folder into the target agent's skills directory (common locations via install.sh --list).
|
|
147
152
|
|
|
153
|
+
> Method 1 uses the npm registry (npmmirror / npmjs) and does not depend on GitHub; Methods 2/3 use GitHub and may fail without a proxy in China.
|
|
148
154
|
## Upgrade
|
|
149
155
|
|
|
150
156
|
Two upgrade paths match the two install paths:
|
|
@@ -154,7 +160,7 @@ Two upgrade paths match the two install paths:
|
|
|
154
160
|
npm i -g @yottameta/yotta-memory
|
|
155
161
|
```
|
|
156
162
|
|
|
157
|
-
**Upgrade the skill**: rerun
|
|
163
|
+
**Upgrade the skill**: rerun your install command from the `## Install` section (e.g. `npx -y --package @yottameta/yotta-memory yotta-memory-install --agent <name>` or `bash install.sh --agent <name>`) to overwrite the old skill folder.
|
|
158
164
|
|
|
159
165
|
> Upgrades only affect commands and skill files — **they never touch your stored memories** (memory is independent of the install, kept in its own directory).
|
|
160
166
|
|
|
@@ -244,7 +250,7 @@ Register the connection in the agent's MCP config (`url` + two headers):
|
|
|
244
250
|
}
|
|
245
251
|
```
|
|
246
252
|
|
|
247
|
-
Once connected, MCP tools (remember / recall / search / forget / archive / reindex / export / import / agent_info) read/write memory and confirm identity; management actions (init / config / token / lan / serve) are not exposed via MCP, and token management is never exposed remotely. `X-Agent-Id` must match the token's registered agent; read-partition rules are the same as the CLI (FACT public-readable, PREF / BOUND / COMMIT private).
|
|
253
|
+
Once connected, MCP tools (remember / recall / search / forget / archive / reindex / export / import / agent_info) read/write memory and confirm identity; management actions (init / config / token / lan / serve) are not exposed via MCP, and token management is never exposed remotely. MCP `export` / `import` paths are restricted inside the memory root, and MCP `distill` does not support `--model` (local CLI only). `X-Agent-Id` must match the token's registered agent; read-partition rules are the same as the CLI (FACT public-readable, PREF / BOUND / COMMIT private).
|
|
248
254
|
|
|
249
255
|
### Location persistence
|
|
250
256
|
|
package/README.zh-CN.md
CHANGED
|
@@ -23,6 +23,8 @@
|
|
|
23
23
|
|
|
24
24
|
> 📖 面向用户的操作手册见 [USER_GUIDE.md](USER_GUIDE.md)。
|
|
25
25
|
|
|
26
|
+
> 🆕 **v0.8.5**:安全加固——MCP `distill` 不再接受 `--model`;MCP `export` / `import` 路径限记忆库内;CLI `distill --model` 不再走 shell(改为允许清单)。
|
|
27
|
+
|
|
26
28
|
> 🆕 **v0.8.2**:发布元数据修复——三次源重发带 `--name 元忆 yotta-memory`,修复 ClawHub 展示名缺失中文(原为裸 `yotta-memory`);无功能变更。
|
|
27
29
|
|
|
28
30
|
> 🆕 **v0.8.1**:`view` 用户查看平台改为服务端分页(记忆多了一次只渲染当前页,页码上下页);`recall` 增加候选预过滤(语义检索前先粗筛候选集,命中集不变,记忆量大时不再逐条全量语义 / 模糊 / 编辑距离);公共 `index.json` 超过 5000 条时按年份分片(`index-<year>.json`),避免单文件膨胀。
|
|
@@ -51,7 +53,7 @@
|
|
|
51
53
|
| **双级存储** | 用户级 `~/.yottamemory/`(跨项目)+ 项目级 `.yottamemory/`(随项目共享 / 交接)|
|
|
52
54
|
| **检索与生命周期** | 语义检索(v0.8.0:同义词 / 拼音 / 字段加权 / 模糊,零依赖)+ 效用分融合排序;统一效用分(盖棺分)规则层自动归档 / 遗忘候选 / 去重(`maintain`,默认 dry-run),记忆库越用越精简 |
|
|
53
55
|
| **越用越懂(v0.6.0)** | `profile` 画像聚合(零推断)+ `context` 开工上下文包(身份 / 画像 / 近期记忆 / 边界 / 承诺)+ SKILL「记忆守则」规则层,记忆随使用成长 |
|
|
54
|
-
| **生态分发** | GitHub + npm 双源同步发布;npx
|
|
56
|
+
| **生态分发** | GitHub + npm 双源同步发布;npx / git clone / Download ZIP / install.sh 四种安装方式,覆盖 17+ 类智能体目录 |
|
|
55
57
|
| **便携记忆盘(随盘走)** | 记忆库即引擎:装在硬盘 / 主机上,插上即恢复全部记忆;引擎主机只需装 CLI 当存放点,无需装任何 AI 智能体 |
|
|
56
58
|
| **局域网共享与自启** | 每智能体独立 token(Bearer + X-Agent-Id)鉴权、可吊销;`lan enable` 注册开机自启(Windows:优先计划任务,非管理员自动降级用户级 Startup 静默自启;Linux:systemd 用户单元,不可用时自动降级用户 crontab @reboot);MCP 工具集与 CLI 一致(8 个工具),管理动作不远程暴露 |
|
|
57
59
|
| **本地 / 局域网双模式** | 本地 `serve --stdio` 零进程、按需拉起(无常驻);局域网 streamable HTTP 常驻——两种模式可并存、按需选用 |
|
|
@@ -134,7 +136,7 @@
|
|
|
134
136
|
- **记忆库即引擎**:`serve` 把记忆目录挂成 MCP 服务,目录随盘走;引擎主机只需装 CLI 当存放点,无需装任何 AI 智能体。
|
|
135
137
|
- **双模式可并存**:本地 `serve --stdio` 零进程(客户端按需拉起);局域网 streamable HTTP(默认 `0.0.0.0:8787`)+ 每智能体 token 鉴权。
|
|
136
138
|
- **开机自启**:`lan enable` 注册开机自启——Windows 优先计划任务(默认登录自启,`--onstart` 开机即启需管理员),非管理员自动降级为**用户级 Startup 静默自启**(免管理员,启动脚本内联启动命令、被清理也会在开机时自动重建,v0.6.3 起不再弹 80070002);Linux 优先 **systemd 用户单元**(`systemctl --user`,登录自启;`--onstart` 附加 `loginctl enable-linger` 开机即启),systemd 不可用时自动降级**用户 crontab @reboot**(v0.6.4);`lan disable` 移除,`lan status` 查询。
|
|
137
|
-
- **安全边界**:管理动作(init / config / token / lan / serve)不进 MCP,token
|
|
139
|
+
- **安全边界**:管理动作(init / config / token / lan / serve)不进 MCP,token 不远程暴露;远程智能体只能读写记忆,且路径限记忆库内(export/import 的 out/src 必须落在库内)、distill 不支持 `--model`(仅本地 CLI),不能改配置、不能管 token。
|
|
138
140
|
- 完整操作步骤见上文「局域网多机共享」章节与 [USER_GUIDE.md](USER_GUIDE.md)。
|
|
139
141
|
|
|
140
142
|
## 与其他方案对比
|
|
@@ -154,34 +156,40 @@
|
|
|
154
156
|
|
|
155
157
|
## 安装
|
|
156
158
|
|
|
157
|
-
|
|
159
|
+
元忆为「CLI + 技能」双体:`yotta-memory` 命令负责读写记忆库,技能负责教智能体工作流。以下四种方式任选,顺序即推荐优先级;技能文件一律从 **npm** 获取(GitHub 无代理较慢,npm 支持镜像)。
|
|
158
160
|
|
|
159
|
-
### 方式一:
|
|
160
|
-
|
|
161
|
-
|
|
161
|
+
### 方式一:npm 一行装(推荐)
|
|
162
|
+
|
|
163
|
+
```text
|
|
164
|
+
# 可选国内加速:npm config set registry https://registry.npmmirror.com
|
|
165
|
+
npx -y --package @yottameta/yotta-memory yotta-memory-install --agent <智能体名称> # 装到指定智能体默认用户级技能目录
|
|
166
|
+
npx -y --package @yottameta/yotta-memory yotta-memory-install --dir <智能体的技能目录> # 指到技能目录本身(如 ~/.codex/skills)
|
|
162
167
|
```
|
|
163
|
-
> 自动把技能文件装到已检测到的智能体(Claude Code / Codex / Cursor / OpenCode 等 78+ 智能体)。此方式只装「技能指令」(SKILL.md 等);要使用 `yotta-memory` 读写命令,需另装 CLI:`npm install -g @yottameta/yotta-memory`(见方式二)。
|
|
164
168
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
npm install -g @yottameta/yotta-memory
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
169
|
+
- `--agent <name>` 自动装到该智能体默认用户级目录;`--list` 可查看各智能体默认目录。
|
|
170
|
+
- `--dir <路径>` 装到指定的技能目录;未收录的智能体用 `--dir` 指到它的技能目录。
|
|
171
|
+
- npmmirror 未同步新包(404):加 `--registry=https://registry.npmjs.org/`(国内需代理),或稍等镜像缓存。
|
|
172
|
+
- 若要读写记忆,需安装 CLI:`npm install -g @yottameta/yotta-memory`(用法见「CLI 用法」)。
|
|
173
|
+
|
|
174
|
+
### 方式二:git clone(开发者 / 有 git 环境)
|
|
175
|
+
|
|
176
|
+
```text
|
|
177
|
+
git clone https://github.com/YottaMeta/yotta-memory.git <智能体的技能目录>/yotta-memory
|
|
172
178
|
```
|
|
173
179
|
|
|
174
|
-
|
|
180
|
+
### 方式三:GitHub 下载压缩包(手动 / 无 git 环境)
|
|
175
181
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
bash install.sh --
|
|
182
|
+
在 GitHub 仓库 `YottaMeta/yotta-memory` 点 **Code → Download ZIP**,解压后把 `yotta-memory` 文件夹放进智能体技能目录。
|
|
183
|
+
|
|
184
|
+
### 方式四:install.sh(多智能体一键脚本)
|
|
185
|
+
|
|
186
|
+
```text
|
|
187
|
+
bash install.sh --agent <name> # 装到指定智能体默认用户级目录
|
|
188
|
+
bash install.sh --dir <path> # 装到指定目录
|
|
189
|
+
bash install.sh --list # 列出智能体 -> 默认目录
|
|
182
190
|
```
|
|
183
|
-
也可把整个 `yotta-memory` 文件夹复制到目标智能体的 skills 目录(常见位置见 install.sh --list)。
|
|
184
191
|
|
|
192
|
+
> 方式一走 npm 源(npmmirror / npmjs),不依赖 GitHub;方式二 / 三走 GitHub,国内无代理可能失败。
|
|
185
193
|
## 升级
|
|
186
194
|
|
|
187
195
|
两种升级方式对应两种安装方式:
|
|
@@ -191,7 +199,7 @@ bash install.sh --dir /path/to/skills
|
|
|
191
199
|
npm i -g @yottameta/yotta-memory
|
|
192
200
|
```
|
|
193
201
|
|
|
194
|
-
|
|
202
|
+
**升级技能**:重跑「安装」节中的命令(如 `npx -y --package @yottameta/yotta-memory yotta-memory-install --agent <name>` 或 `bash install.sh --agent <name>`),覆盖旧版技能文件夹。
|
|
195
203
|
|
|
196
204
|
> 升级只影响命令与技能文件,**不会动你已存的记忆**(记忆是独立于安装的文件,保留在原目录)。
|
|
197
205
|
|
|
@@ -282,7 +290,7 @@ yotta-memory recall --type FACT --limit 10
|
|
|
282
290
|
}
|
|
283
291
|
```
|
|
284
292
|
|
|
285
|
-
连接后可通过 MCP tools(remember / recall / search / forget / archive / reindex / export / import / agent_info)读写记忆与确认身份;管理动作(init / config / token / lan / serve)不进 MCP,token
|
|
293
|
+
连接后可通过 MCP tools(remember / recall / search / forget / archive / reindex / export / import / agent_info)读写记忆与确认身份;管理动作(init / config / token / lan / serve)不进 MCP,token 管理不远程暴露;MCP export/import 路径限记忆库内、distill 不支持 `--model`(仅本地 CLI)。`X-Agent-Id` 必须与 token 登记的智能体一致;读取分区规则与 CLI 相同(FACT 公共可读,PREF / BOUND / COMMIT 私密隔离)。
|
|
286
294
|
|
|
287
295
|
### 位置持久化
|
|
288
296
|
|
package/SKILL.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: yotta-memory
|
|
3
3
|
description: "元忆 —— 有权限边界的文件式智能体记忆。文件式、零依赖、可 diff/回滚:让任何 AI 智能体活过会话,开工 recall 恢复上下文、重要信息 remember 落盘、收工归档。类型体系 FACT(公共共享)/ PREF / BOUND / COMMIT(私密隔离)。触发:记住、别忘了、记一笔、记忆、remember、recall、跨会话、上次说到、续测、交接、归档、记忆盘、共享记忆、局域网记忆、画像、开工上下文、记忆守则、profile、context、越用越懂、语义检索、反馈、维护、蒸馏、feedback、maintain、distill、explain、自我学习、自我进化、自我提升、查看平台分页、recall 候选预过滤"
|
|
4
|
-
version: 0.8.
|
|
4
|
+
version: 0.8.5
|
|
5
5
|
license: MIT
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# yotta-memory(元忆)— 有权限边界的文件式智能体记忆
|
|
9
9
|
|
|
10
10
|
> 一句话:元忆 —— 有权限边界的文件式智能体记忆(不注入、可 diff、能回滚;FACT 共享、PREF / BOUND / COMMIT 私密隔离)。
|
|
11
|
-
> 版本:0.8.
|
|
11
|
+
> 版本:0.8.5 | 最后更新:2026-08-29
|
|
12
12
|
|
|
13
13
|
## 这是什么
|
|
14
14
|
|
|
@@ -113,7 +113,7 @@ license: MIT
|
|
|
113
113
|
- 未装 → 🔒 **征得同意后**自动安装(三选一,AI 判断;装后回读 `--version` 出版本即就绪):
|
|
114
114
|
- 临时使用:`npx -y @yottameta/yotta-memory`
|
|
115
115
|
- 长期使用:`npm i -g @yottameta/yotta-memory`
|
|
116
|
-
- 离线 / 国内 / 无 npm:git clone 仓库(或手动下载 install.sh)后执行 `bash install.sh
|
|
116
|
+
- 离线 / 国内 / 无 npm:git clone 仓库(或手动下载 install.sh)后执行 `bash install.sh --agent <name>`
|
|
117
117
|
|
|
118
118
|
**A. 确认记忆库位置**(AI 不会自动知道记忆库在哪,先检测,避免「recall 读空库 / 错库」):
|
|
119
119
|
|
|
@@ -291,7 +291,7 @@ license: MIT
|
|
|
291
291
|
4. 按当前智能体机制重载 MCP(必要时请用户重启会话);
|
|
292
292
|
5. 用 MCP tools 读写记忆。
|
|
293
293
|
|
|
294
|
-
> MCP 工具集与 CLI 一致:remember / recall / search / forget / archive / reindex / export / import / profile;管理动作(init / config / token / lan / serve)不进 MCP,token
|
|
294
|
+
> MCP 工具集与 CLI 一致:remember / recall / search / forget / archive / reindex / export / import / profile;管理动作(init / config / token / lan / serve)不进 MCP,token 管理不远程暴露;MCP export/import 路径限记忆库内、distill 不支持 `--model`(仅本地 CLI)。
|
|
295
295
|
|
|
296
296
|
### 4.7 MCP 配置位置表
|
|
297
297
|
| 智能体 | 常见 MCP 配置位置 |
|
package/USER_GUIDE.md
CHANGED
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
|---|---|---|
|
|
43
43
|
| npm 全局(推荐) | `npm i -g @yottameta/yotta-memory` | 长期使用 |
|
|
44
44
|
| npx 临时 | `npx -y @yottameta/yotta-memory` | 临时试用 |
|
|
45
|
-
| install.sh | git clone 仓库后 `bash install.sh
|
|
45
|
+
| install.sh | git clone 仓库后 `bash install.sh --agent <name>`(或手动下载 install.sh 执行)| 离线 / 国内 / 无 npm |
|
|
46
46
|
|
|
47
47
|
安装后验证:`yotta-memory --version` 能输出版本号即成功。
|
|
48
48
|
|
|
@@ -50,8 +50,8 @@
|
|
|
50
50
|
|
|
51
51
|
| 方式 | 命令 | 适用 |
|
|
52
52
|
|---|---|---|
|
|
53
|
-
| npx
|
|
54
|
-
| 安装器(npm 全局时) | `yotta-memory-install
|
|
53
|
+
| npx 一行装(推荐) | `npx -y --package @yottameta/yotta-memory yotta-memory-install --agent <name>` | 装到指定智能体默认用户级目录 |
|
|
54
|
+
| 安装器(npm 全局时) | `yotta-memory-install --agent <name>` | 装到指定智能体目录 |
|
|
55
55
|
| 手动 | 把整个 `yotta-memory` 文件夹复制到智能体的 skills 目录 | 离线 |
|
|
56
56
|
|
|
57
57
|
> CLI 与技能分工不同:CLI 让命令行能读写记忆;技能让 AI 知道「开工 recall 恢复上下文、重要信息 remember 落盘、收工归档」。只装 CLI 不装技能,AI 不会自动使用这套工作流。
|
|
@@ -356,7 +356,7 @@ yotta-memory remember FACT 主题 内容 # 智能体落盘
|
|
|
356
356
|
- token 等同密码:只给需要接入的智能体,别外传。
|
|
357
357
|
- 私密区机制级加密(v0.7 起):PREF / BOUND / COMMIT 私密记忆默认落盘为密文(AES-256-GCM 信封加密),任何没有对应 owner 密钥的 AI 即使读到密文文件也解不开;隔离 = 权限边界(scope/owner)+ 机制层机密保护。用户是数据所有者,经 `yotta-memory view` 口令解锁可看全部。
|
|
358
358
|
- 记忆读写一律走 CLI / MCP;禁止用 shell(`Get-ChildItem` / `cat` / `ls` / `type` 等)直接读改记忆库目录下的文件——否则会绕过 scope/owner 权限边界。
|
|
359
|
-
- 管理动作(init / config / token / lan / serve)不通过 MCP
|
|
359
|
+
- 管理动作(init / config / token / lan / serve)不通过 MCP 暴露,远程只能读写记忆(路径限记忆库内,export/import 的 out/src 必须落在库内;distill 不支持 `--model`,仅本地 CLI),不能改配置、不能管 token。
|
|
360
360
|
- `--no-auth` 会关闭鉴权,仅限可信内网使用。
|
|
361
361
|
- 数据主权在用户:公共 FACT 明文、随时可看可改可删;私密区加密,用户经 `yotta-memory view` 口令解锁后同样可看、可改、可删、可导出。
|
|
362
362
|
- 「记忆守则」内置底线:陪伴不操控 / 理解不越界(不贴标签)/ 诚实不伪装 / 不降格;数据安全(被遗忘权 = `forget`);宿主隔离(只写本记忆库,不读写宿主 AI 自身 memory / 配置 / 系统文件)。
|
package/bin/yotta-memory.js
CHANGED
|
@@ -22,7 +22,7 @@ const crypto = require('crypto');
|
|
|
22
22
|
const http = require('http');
|
|
23
23
|
const child_process = require('child_process');
|
|
24
24
|
|
|
25
|
-
const VERSION = '0.8.
|
|
25
|
+
const VERSION = '0.8.5';
|
|
26
26
|
const TYPES = ['FACT', 'PREF', 'BOUND', 'COMMIT'];
|
|
27
27
|
const TYPE_DIRS = { FACT: 'facts', PREF: 'prefs', BOUND: 'bounds', COMMIT: 'commits' };
|
|
28
28
|
const PUBLIC_DIR = 'facts';
|
|
@@ -100,6 +100,56 @@ function typeSubdir(type, owner) {
|
|
|
100
100
|
function defaultScope(type) {
|
|
101
101
|
return PRIVATE_TYPES.indexOf(String(type).toUpperCase()) === -1 ? 'public' : 'private';
|
|
102
102
|
}
|
|
103
|
+
// ---- 安全边界:路径必须落在记忆库根内(防 MCP 任意路径读写,v0.8.5)----
|
|
104
|
+
function resolveWithinRoot(root, p) {
|
|
105
|
+
let abs = path.isAbsolute(p) ? path.resolve(p) : path.resolve(root, p);
|
|
106
|
+
const r = path.resolve(root);
|
|
107
|
+
if (abs === r) return abs;
|
|
108
|
+
if (abs.startsWith(r + path.sep)) return abs;
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
function isWithinRoot(root, p) { return !!resolveWithinRoot(root, p); }
|
|
112
|
+
// 把命令行安全拆分为 argv(支持 ' " 引号包参,但绝不经过 shell,防元字符注入)
|
|
113
|
+
function splitCommandArgv(s) {
|
|
114
|
+
const argv = [];
|
|
115
|
+
let cur = '';
|
|
116
|
+
let quote = null;
|
|
117
|
+
for (let i = 0; i < String(s).length; i++) {
|
|
118
|
+
const c = String(s)[i];
|
|
119
|
+
if (quote) {
|
|
120
|
+
if (c === quote) { quote = null; continue; }
|
|
121
|
+
if (c === '\\' && quote === '"') { cur += String(s)[i + 1] || ''; i++; continue; }
|
|
122
|
+
cur += c; continue;
|
|
123
|
+
}
|
|
124
|
+
if (c === '"' || c === "'") { quote = c; continue; }
|
|
125
|
+
if (c === ' ' || c === '\t') { if (cur) { argv.push(cur); cur = ''; } continue; }
|
|
126
|
+
cur += c;
|
|
127
|
+
}
|
|
128
|
+
if (cur) argv.push(cur);
|
|
129
|
+
return argv;
|
|
130
|
+
}
|
|
131
|
+
// 模型命令允许清单:环境变量 YOTTA_DISTILL_MODELS(逗号分隔可执行名,不含扩展名)或 config.distill_models;
|
|
132
|
+
// 未配置时放行(本地宿主 CLI 自担风险,但已去除 shell 注入面);MCP 已在上层直接拒绝 model,不达此处。
|
|
133
|
+
function distillModelAllowlist() {
|
|
134
|
+
const env = (process.env.YOTTA_DISTILL_MODELS || '').split(',').map(function (x) { return x.trim().toLowerCase(); }).filter(Boolean);
|
|
135
|
+
if (env.length) return env;
|
|
136
|
+
const cfg = loadConfig();
|
|
137
|
+
const c = cfg && (cfg.distill_models || []);
|
|
138
|
+
if (Array.isArray(c) && c.length) return c.map(function (x) { return String(x).trim().toLowerCase(); }).filter(Boolean);
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
// 安全执行外部模型命令:仅允许清单内可执行名;argv 分离、不经 shell。
|
|
142
|
+
function runDistillModel(modelStr, payload) {
|
|
143
|
+
const argv = splitCommandArgv(modelStr);
|
|
144
|
+
if (!argv.length) throw new Error('模型命令为空');
|
|
145
|
+
const base = path.basename(argv[0]).toLowerCase().replace(/\.exe$/i, '');
|
|
146
|
+
const allow = distillModelAllowlist();
|
|
147
|
+
if (allow && allow.length && allow.indexOf(base) === -1) {
|
|
148
|
+
throw new Error('模型命令不在允许清单内: ' + base + '(可用: ' + allow.join(', ') + ';或设环境变量 YOTTA_DISTILL_MODELS)');
|
|
149
|
+
}
|
|
150
|
+
const r = child_process.spawnSync(argv[0], argv.slice(1), { input: payload, encoding: 'utf8', maxBuffer: 1024 * 1024, shell: false, windowsHide: true });
|
|
151
|
+
return r;
|
|
152
|
+
}
|
|
103
153
|
function parseFrontmatter(text) {
|
|
104
154
|
const m = text.match(/^---\s*\n([\s\S]*?)\n---/);
|
|
105
155
|
if (!m) return { meta: {}, body: text };
|
|
@@ -1626,7 +1676,7 @@ function distillCore(opts) {
|
|
|
1626
1676
|
if (opts.model) {
|
|
1627
1677
|
try {
|
|
1628
1678
|
const payload = JSON.stringify({ summary: lines.join('\n'), entries: entries.map(function (e) { return { type: e.type, subject: e.subject, statement: e.statement, tags: e.tags, confidence: e.confidence, access_count: e.access_count, feedback_net: e.feedback_net }; }).slice(0, 200) });
|
|
1629
|
-
const r =
|
|
1679
|
+
const r = runDistillModel(String(opts.model), payload);
|
|
1630
1680
|
if (r.stdout) modelOut = String(r.stdout).trim();
|
|
1631
1681
|
if (!modelOut) modelOut = '(模型无输出)';
|
|
1632
1682
|
body += '\n## 四、模型提炼(--model ' + opts.model + ')\n\n' + modelOut + '\n';
|
|
@@ -2603,13 +2653,13 @@ function mcpTools() {
|
|
|
2603
2653
|
{ name: 'forget', description: '删除一条记忆。file 为记忆文件路径(如 facts/2026-08-24-0001.md 或文件名)', inputSchema: { type: 'object', properties: { file: { type: 'string' } }, required: ['file'] } },
|
|
2604
2654
|
{ name: 'archive', description: '归档旧记忆。days 默认 180;threshold 默认 0.4', inputSchema: { type: 'object', properties: { days: { type: 'number' }, threshold: { type: 'number' } } } },
|
|
2605
2655
|
{ name: 'reindex', description: '重建索引(手动改 .md 后校正;扫描 facts/prefs/bounds/commits 四目录)', inputSchema: { type: 'object', properties: {} } },
|
|
2606
|
-
{ name: 'export', description: '
|
|
2607
|
-
{ name: 'import', description: '
|
|
2656
|
+
{ name: 'export', description: '导出全部记忆到记忆库内的 JSON 文件。out 可选(默认 <记忆库>/yottamemory-export-<日期>.json;仅限记忆库内路径)', inputSchema: { type: 'object', properties: { out: { type: 'string' } } } },
|
|
2657
|
+
{ name: 'import', description: '从记忆库内的 JSON 文件导入记忆。src 为文件路径(相对记忆库目录,或记忆库内绝对路径;仅限记忆库内)', inputSchema: { type: 'object', properties: { src: { type: 'string' } }, required: ['src'] } },
|
|
2608
2658
|
{ name: 'agent_info', description: '查看当前智能体身份与登记状态(远端读经 token 校验的 X-Agent-Id;本机读 YOTTA_AGENT_ID)。开工先确认「我是谁」,禁止从记忆里抄别人的 ID', inputSchema: { type: 'object', properties: {} } },
|
|
2609
2659
|
{ name: 'profile', description: '生成当前智能体的用户画像(只读聚合 private/<owner>/ 下 PREF/BOUND/COMMIT 原文,零推断,写入 private/<owner>/profile.md)。owner 默认当前智能体', inputSchema: { type: 'object', properties: { owner: { type: 'string' } } } },
|
|
2610
2660
|
{ name: 'feedback', description: '显式使用反馈(自我学习):useful/useless 调整记忆 weight/confidence/feedback_net。file 为记忆文件路径或文件名', inputSchema: { type: 'object', properties: { file: { type: 'string' }, useful: { type: 'boolean' }, useless: { type: 'boolean' }, reason: { type: 'string' } }, required: ['file'] } },
|
|
2611
2661
|
{ name: 'maintain', description: '记忆自组织(自我进化):规则层归档/遗忘/去重预览。默认 dry-run;apply 才执行,purge 才真删', inputSchema: { type: 'object', properties: { apply: { type: 'boolean' }, purge: { type: 'boolean' }, dedup: { type: 'boolean' }, threshold: { type: 'number' }, age: { type: 'number' } } } },
|
|
2612
|
-
{ name: 'distill', description: '心理日志蒸馏(自我提升):统计摘要/主题画像/知识地图。owner
|
|
2662
|
+
{ name: 'distill', description: '心理日志蒸馏(自我提升):统计摘要/主题画像/知识地图。owner 默认当前智能体(MCP 不支持 --model 外部命令)', inputSchema: { type: 'object', properties: { owner: { type: 'string' }, subject: { type: 'string' } } } },
|
|
2613
2663
|
{ name: 'explain', description: '解释单条记忆效用分项(为什么靠前/归档/遗忘)。file 为记忆文件路径或文件名', inputSchema: { type: 'object', properties: { file: { type: 'string' } }, required: ['file'] } },
|
|
2614
2664
|
];
|
|
2615
2665
|
}
|
|
@@ -2641,11 +2691,22 @@ function callTool(name, args, ctx) {
|
|
|
2641
2691
|
return { text: '已重建索引 ' + root + '(' + cnt + ' 条)', error: false };
|
|
2642
2692
|
}
|
|
2643
2693
|
if (name === 'export') {
|
|
2644
|
-
const
|
|
2694
|
+
const root = userRoot();
|
|
2695
|
+
let out = null;
|
|
2696
|
+
if (args.out) {
|
|
2697
|
+
const safe = resolveWithinRoot(root, String(args.out));
|
|
2698
|
+
if (!safe) return { text: '拒绝: MCP 导出路径必须位于记忆库内(' + root + '),已阻止任意路径写入。', error: true };
|
|
2699
|
+
out = safe;
|
|
2700
|
+
}
|
|
2701
|
+
const r = exportCore(root, out);
|
|
2645
2702
|
return { text: r.text, error: r.error };
|
|
2646
2703
|
}
|
|
2647
2704
|
if (name === 'import') {
|
|
2648
|
-
const
|
|
2705
|
+
const root = userRoot();
|
|
2706
|
+
const src = String(args.src || '');
|
|
2707
|
+
const safe = resolveWithinRoot(root, src);
|
|
2708
|
+
if (!safe) return { text: '拒绝: MCP 导入路径必须位于记忆库内(' + root + '),已阻止任意路径读取。', error: true };
|
|
2709
|
+
const r = importCore(root, safe);
|
|
2649
2710
|
return { text: r.text, error: r.error };
|
|
2650
2711
|
}
|
|
2651
2712
|
if (name === 'agent_info') {
|
|
@@ -2681,7 +2742,8 @@ function callTool(name, args, ctx) {
|
|
|
2681
2742
|
return { text: r.text, error: r.error };
|
|
2682
2743
|
}
|
|
2683
2744
|
if (name === 'distill') {
|
|
2684
|
-
|
|
2745
|
+
if (args.model) return { text: '拒绝: MCP 不支持 --model(任意命令执行风险);请在引擎主机本地 CLI 执行 yotta-memory distill --model <命令>。', error: true };
|
|
2746
|
+
const r = distillCore({ selfAgent: agent, owner: args.owner ? String(args.owner) : agent, subject: args.subject ? String(args.subject) : '', model: '' });
|
|
2685
2747
|
return { text: r.text, error: r.error };
|
|
2686
2748
|
}
|
|
2687
2749
|
if (name === 'explain') {
|
|
@@ -3328,6 +3390,10 @@ async function main() {
|
|
|
3328
3390
|
else if (a === '--password') opts.password = v;
|
|
3329
3391
|
else if (a === '--new-password') opts.newPassword = v;
|
|
3330
3392
|
else if (a === '--recovery-key') opts.recoveryKey = v;
|
|
3393
|
+
else if (a === '--reason') opts.reason = v;
|
|
3394
|
+
else if (a === '--merge') opts.merge = v;
|
|
3395
|
+
else if (a === '--model') opts.model = v;
|
|
3396
|
+
else if (a === '--subject') opts.subject = v;
|
|
3331
3397
|
} else if (a.startsWith('--')) {
|
|
3332
3398
|
console.error('未知选项: ' + a);
|
|
3333
3399
|
process.exit(2);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yottameta/yotta-memory",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.5",
|
|
4
4
|
"description": "Yuanyi (元忆) — boundary-aware, file-based memory for AI agents. File-based, zero-dependency, diff/rollback-able; FACT/PREF/BOUND/COMMIT four types (public shared / private isolated), user-level + project-level storage; v0.8 semantic search + usage feedback loop + rule-layer self-organization + psychological-log distillation (self-learning/self-evolving/self-improving).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|