@yottameta/yotta-memory 0.6.1 → 0.6.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.
package/README.md CHANGED
@@ -115,7 +115,7 @@
115
115
 
116
116
  - **记忆库即引擎**:`serve` 把记忆目录挂成 MCP 服务,目录随盘走;引擎主机只需装 CLI 当存放点,无需装任何 AI 智能体。
117
117
  - **双模式可并存**:本地 `serve --stdio` 零进程(客户端按需拉起);局域网 streamable HTTP(默认 `0.0.0.0:8787`)+ 每智能体 token 鉴权。
118
- - **开机自启**:`lan enable` 注册 Windows 开机自启——优先计划任务(默认登录自启,`--onstart` 开机即启需管理员);非管理员(计划任务被拒)自动降级为**用户级 Startup 静默自启**(免管理员);`lan disable` 移除,`lan status` 查询。
118
+ - **开机自启**:`lan enable` 注册 Windows 开机自启——优先计划任务(默认登录自启,`--onstart` 开机即启需管理员);非管理员(计划任务被拒)自动降级为**用户级 Startup 静默自启**(免管理员),启动脚本(VBS)内联启动命令,即使启动文件被外部清理也会在开机时自动重建(v0.6.3 自愈,不再出现 80070002 弹窗);`lan disable` 移除,`lan status` 查询。
119
119
  - **安全边界**:管理动作(init / config / token / lan / serve)不进 MCP,token 不远程暴露;远程智能体只能读写记忆,不能改配置、不能管 token。
120
120
  - 完整操作步骤见上文「局域网多机共享」章节与 [USER_GUIDE.md](USER_GUIDE.md)。
121
121
 
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、越用越懂"
4
- version: 0.6.1
4
+ version: 0.6.3
5
5
  license: MIT
6
6
  ---
7
7
 
8
8
  # yotta-memory(元忆)— 有权限边界的文件式智能体记忆
9
9
 
10
10
  > 一句话:元忆 —— 有权限边界的文件式智能体记忆(不注入、可 diff、能回滚;FACT 共享、PREF / BOUND / COMMIT 私密隔离)。
11
- > 版本:0.6.1 | 最后更新:2026-08-25
11
+ > 版本:0.6.3 | 最后更新:2026-08-26
12
12
 
13
13
  ## 这是什么
14
14
 
@@ -158,7 +158,7 @@ license: MIT
158
158
  | `yotta-memory iam <id> [--name <显示名>] [--user <用户名>] [--relationship <关系>] [--force]` | 登记本智能体唯一身份并自动落自我档案(`agents.json`,ID 必须唯一;可选扩展显示名 / 用户 / 关系)|
159
159
  | `yotta-memory token new --agent <id> [--force]` / `token list` / `token revoke --agent <id>` | 每智能体访问 token:生成 / 列出 / 吊销(登记 `<记忆库>/.server/tokens.json`;同 ID 已被其它来源占用需 `--force` 覆盖,防不同智能体合流)|
160
160
  | `yotta-memory serve [--host 0.0.0.0] [--port 8787] [--no-auth] [--stdio]` | 启动 MCP 记忆引擎(streamable HTTP 局域网 / --stdio 本地零进程模式;Bearer token + X-Agent-Id 鉴权)|
161
- | `yotta-memory lan enable [--onstart] / disable / status` | 开机自启管理(Windows:计划任务,默认 ONLOGON 登录自启、--onstart 开机即启需管理员;非管理员自动降级用户级 Startup 静默自启)|
161
+ | `yotta-memory lan enable [--onstart] / disable / status` | 开机自启管理(Windows:计划任务,默认 ONLOGON 登录自启、--onstart 开机即启需管理员;非管理员自动降级用户级 Startup 静默自启;v0.6.3 起 VBS 自愈:内联启动命令,.cmd 缺失/被清理时开机自动重建,不再弹 80070002)|
162
162
 
163
163
  ## 存储格式(摘要)
164
164
 
package/USER_GUIDE.md CHANGED
@@ -124,7 +124,8 @@ yotta-memory init --dir /srv/yotta-memory # 新库:初始化(
124
124
  **第 3 步:注册开机自启(可选,推荐)**
125
125
 
126
126
  ```bash
127
- # Windows:内置命令(优先计划任务;非管理员自动降级用户级 Startup 静默自启)
127
+ # Windows:内置命令(优先计划任务;非管理员自动降级用户级 Startup 静默自启;
128
+ # v0.6.3 起启动脚本自愈——启动文件被清理也会在开机时自动重建,无需手动处理)
128
129
  yotta-memory lan enable # 登录后自动启动(默认)
129
130
  yotta-memory lan enable --onstart # 开机即启(需管理员)
130
131
  yotta-memory lan status # 查看状态
@@ -7,6 +7,8 @@
7
7
  // v0.5.4 新增:lan enable 在非管理员(schtasks Access denied)时自动降级为用户级 Startup 静默自启(VBS sh.Run 窗口0 + autostart.cmd,node 路径 process.execPath 自动探测);lan disable/status 同时管理计划任务与 Startup 双机制
8
8
  // v0.6.0 新增:灵魂盘核心——profile(用户画像聚合,零推断)/ context(开工上下文包)/ iam 扩展(--name/--user/--relationship)/ remember --verify(写后回读)与 --no-hint(关闭类型启发式提示)+ SKILL「记忆守则」
9
9
  // v0.6.1 新增:灵魂盘机制精髓补齐——context --budget(token 预算,近记忆按剩余预算放行)/ context 内嵌「多智能体接入铁律」段 / remember --source/--weight(来源 + 重要性权重,去重 weight 取 max)/ 近期记忆排序融合 importance(confidence×recency+updated+weight+immutable)
10
+ // v0.6.3 修复:lan 开机自启 VBS 自愈——VBS 内联 autostart.cmd 内容,启动时自动重建 .cmd(根治 80070002:wscript 找不到被引用启动文件)
11
+ // v0.6.2 修复:remember --verify 写后回读改为直查索引 + 权限判定 + 召回匹配性(不再依赖 recall top-N 排序,消除泛化 subject 下偶发误报「回读未命中」)
10
12
  'use strict';
11
13
 
12
14
  const fs = require('fs');
@@ -16,7 +18,7 @@ const crypto = require('crypto');
16
18
  const http = require('http');
17
19
  const child_process = require('child_process');
18
20
 
19
- const VERSION = '0.6.1';
21
+ const VERSION = '0.6.3';
20
22
  const TYPES = ['FACT', 'PREF', 'BOUND', 'COMMIT'];
21
23
  const TYPE_DIRS = { FACT: 'facts', PREF: 'prefs', BOUND: 'bounds', COMMIT: 'commits' };
22
24
  const PUBLIC_DIR = 'facts';
@@ -366,6 +368,24 @@ function classifyRead(entry, agent, ownerFilter, unsafe, selfAgent) {
366
368
  if (hasGrant(agent || selfAgent, owner)) return 'read';
367
369
  return 'denied';
368
370
  }
371
+ // verify 写后回读:直查索引 + 权限判定 + 召回匹配性,不依赖 recall top-N 排序
372
+ // (v0.6.2 修复:泛化 subject 下新条目被挤出前 N 条导致误报「回读未命中」)
373
+ function verifyWrittenReadable(root, rel, subj, agent) {
374
+ const entries = ensureIndex(root);
375
+ let target = null;
376
+ for (const e of entries) { if (e.file === rel) { target = e; break; } }
377
+ if (!target) return false;
378
+ if (classifyRead(target, agent, '', false, agent) !== 'read') return false;
379
+ const q = String(subj || '').toLowerCase();
380
+ const qtoks = tokenize(q);
381
+ let score = 0;
382
+ for (const tt of qtoks) { if (target.tokens && target.tokens[tt]) score += target.tokens[tt]; }
383
+ if (score === 0) {
384
+ const hay = ((target.subject || '') + ' ' + (target.statement || '') + ' ' + target.tags.join(' ')).toLowerCase();
385
+ if (hay.indexOf(q) !== -1) score = 1;
386
+ }
387
+ return score > 0;
388
+ }
369
389
 
370
390
  // ---- 命令 core(CLI 与 MCP 共用;返回 { error, exitCode, text },不 process.exit)----
371
391
  function initCore(opts) {
@@ -415,8 +435,7 @@ function rememberCore(type, subject, statement, opts) {
415
435
  }
416
436
  if (opts.verify) {
417
437
  const rel = path.relative(root, fp).replace(/\\/g, '/');
418
- const rr = recallCore(subj, { limit: 10, agent: selfAgent || opts.agent });
419
- const ok = rr.text.replace(/\\/g, '/').indexOf(rel) !== -1;
438
+ const ok = verifyWrittenReadable(root, rel, subj, selfAgent || opts.agent);
420
439
  text += '\n[verify] ' + (ok ? '已写回读 OK: ' + rel : '回读未命中,请检查: ' + rel);
421
440
  }
422
441
  return { error: false, text: text };
@@ -443,8 +462,7 @@ function rememberCore(type, subject, statement, opts) {
443
462
  }
444
463
  if (opts.verify) {
445
464
  const rel = path.relative(root, file).replace(/\\/g, '/');
446
- const rr = recallCore(subj, { limit: 10, agent: selfAgent || opts.agent });
447
- const ok = rr.text.replace(/\\/g, '/').indexOf(rel) !== -1;
465
+ const ok = verifyWrittenReadable(root, rel, subj, selfAgent || opts.agent);
448
466
  text += '\n[verify] ' + (ok ? '已写回读 OK: ' + rel : '回读未命中,请检查: ' + rel);
449
467
  }
450
468
  return { error: false, text: text };
@@ -1283,23 +1301,51 @@ function lanAutostartCmdContent(opts) {
1283
1301
  const host = opts.host || '0.0.0.0';
1284
1302
  const port = opts.port || 8787;
1285
1303
  const q = (p) => '"' + String(p).replace(/"/g, '""') + '"';
1286
- // 生成文件用纯 ASCII(避免 cmd/VBS 按系统代码页读取中文注释乱码)
1304
+ // 生成文件用纯 ASCII(避免 cmd/VBS 按系统代码页读取中文注释乱码;VBS 自愈内联同一内容)
1287
1305
  return '@echo off\r\n'
1288
1306
  + 'chcp 65001 >nul\r\n'
1289
- + 'rem ' + LAN_GEN_MARKER + '; remove with: yotta-memory lan disable\r\n'
1307
+ + 'rem ' + LAN_GEN_MARKER + '; remove with: yotta-memory lan disable (English only, keep ASCII)\r\n'
1290
1308
  + q(process.execPath) + ' ' + q(__filename) + ' serve --host ' + host + ' --port ' + port + ' >> ' + q(lanLogPath(opts)) + ' 2>&1\r\n';
1291
1309
  }
1292
- function lanVbsContent() {
1293
- return "' " + LAN_GEN_MARKER + '; remove with: yotta-memory lan disable\r\n'
1294
- + 'Set sh = CreateObject("WScript.Shell")\r\n'
1295
- + 'sh.Run "' + String(lanAutostartCmdPath()).replace(/"/g, '""') + '", 0, False\r\n';
1310
+ function lanVbsContent(opts) {
1311
+ // v0.6.3 自愈:VBS 内联 autostart.cmd 内容,启动时若 .cmd 缺失/被清理即就地重建,
1312
+ // 根治 80070002(wscript 找不到被引用的启动文件)。VBS 写 UTF-16LE,wscript 按 Unicode 读取。
1313
+ const cmdContent = lanAutostartCmdContent(opts || {});
1314
+ // VBS 字符串字面量不能含原始换行:把 CRLF 编码为 Chr(13) & Chr(10) & 拼接,
1315
+ // 生成的 VBS 保持单行合法(否则 wscript 报语法错误,.cmd 重建失败)。
1316
+ const vbsCmdLiteral = cmdContent
1317
+ .replace(/\r\n/g, '\n')
1318
+ .replace(/\n/g, '\n')
1319
+ .split('\n')
1320
+ .map(function (seg) {
1321
+ // 每段都带引号(VBS 字符串字面量),换行用 Chr(13) & Chr(10) 拼接
1322
+ return '"' + seg.replace(/"/g, '""') + '"';
1323
+ })
1324
+ .join(' & Chr(13) & Chr(10) & ');
1325
+ const vbsCmdPath = String(lanAutostartCmdPath()).replace(/"/g, '""');
1326
+ const lines = [
1327
+ "' " + LAN_GEN_MARKER + '; remove with: yotta-memory lan disable',
1328
+ "' v0.6.3 self-heal: always rebuild autostart.cmd from embedded content, then run it (fix 80070002)",
1329
+ 'Set fso = CreateObject("Scripting.FileSystemObject")',
1330
+ 'Set sh = CreateObject("WScript.Shell")',
1331
+ 'cmdPath = "' + vbsCmdPath + '"',
1332
+ 'On Error Resume Next',
1333
+ 'Set dir = fso.GetParentFolderName(cmdPath)',
1334
+ 'If Not fso.FolderExists(dir) Then fso.CreateFolder(dir)',
1335
+ 'Set f = fso.CreateTextFile(cmdPath, True)',
1336
+ 'f.Write ' + vbsCmdLiteral,
1337
+ 'f.Close',
1338
+ 'sh.Run cmdPath, 0, False',
1339
+ '',
1340
+ ];
1341
+ return lines.join('\r\n') + '\r\n';
1296
1342
  }
1297
1343
  function lanInstallStartup(opts) {
1298
1344
  fs.mkdirSync(lanAutostartDir(), { recursive: true });
1299
1345
  fs.writeFileSync(lanAutostartCmdPath(), lanAutostartCmdContent(opts), 'utf8');
1300
1346
  fs.mkdirSync(lanStartupDir(), { recursive: true });
1301
1347
  // VBS 用 UTF-16LE+BOM:wscript 按 Unicode 读取,中文路径不乱码(纯 ANSI 读取会按系统代码页误读)
1302
- fs.writeFileSync(lanVbsPath(), '\ufeff' + lanVbsContent(), 'utf16le');
1348
+ fs.writeFileSync(lanVbsPath(), '\ufeff' + lanVbsContent(opts), 'utf16le');
1303
1349
  }
1304
1350
  function lanRemoveStartupFiles() {
1305
1351
  // 只删除带产品标记的生成文件,绝不误删用户自己的 Startup 文件
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yottameta/yotta-memory",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
4
4
  "description": "元忆 —— 有权限边界的文件式智能体记忆。文件式、零依赖、可 diff/回滚;FACT/PREF/BOUND/COMMIT 四分类(公共共享/私密隔离),用户级+项目级双级存储。",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -1,4 +1,4 @@
1
- # yotta-memory 协议规范 v0.6.1
1
+ # yotta-memory 协议规范 v0.6.3
2
2
 
3
3
  > 本文件定义 yotta-memory 记忆标准:存储位置、目录结构、文件格式、类型体系与 CLI 命令参考。
4
4
  > 目标:任何支持 Agent Skills 开放标准的智能体,装完即可读写同一份记忆。