@yottameta/yotta-memory 0.6.4 → 0.6.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/README.md CHANGED
@@ -97,6 +97,7 @@
97
97
  - `remember` 时自动构建 `index.json` 索引;recall 用 TF 打分排序,中文按 bigram 分词,不用额外模型。
98
98
  - `index.json` 的 `tokens` 字段是中文分词的词频表(TF 打分用),**不是**访问凭证;鉴权令牌在记忆目录下 `.server/tokens.json`。
99
99
  - 支持关键词、`--type` 过滤、`--limit` 截断、项目级优先。
100
+ - **根位置去重(v0.6.5)**:当项目级与用户级记忆库指向同一目录(如 cwd = home 或其父)时,`recall` / `context` 自动唯一化根,同一文件只展示一次。
100
101
  - 命中展示会累加 `access_count` / `last_accessed`,为生命周期管理提供依据。
101
102
 
102
103
  ### 生命周期管理
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.4
4
+ version: 0.6.5
5
5
  license: MIT
6
6
  ---
7
7
 
8
8
  # yotta-memory(元忆)— 有权限边界的文件式智能体记忆
9
9
 
10
10
  > 一句话:元忆 —— 有权限边界的文件式智能体记忆(不注入、可 diff、能回滚;FACT 共享、PREF / BOUND / COMMIT 私密隔离)。
11
- > 版本:0.6.4 | 最后更新:2026-08-26
11
+ > 版本:0.6.5 | 最后更新:2026-08-26
12
12
 
13
13
  ## 这是什么
14
14
 
@@ -9,6 +9,7 @@
9
9
  // v0.6.1 新增:灵魂盘机制精髓补齐——context --budget(token 预算,近记忆按剩余预算放行)/ context 内嵌「多智能体接入铁律」段 / remember --source/--weight(来源 + 重要性权重,去重 weight 取 max)/ 近期记忆排序融合 importance(confidence×recency+updated+weight+immutable)
10
10
  // v0.6.3 修复:lan 开机自启 VBS 自愈——VBS 内联 autostart.cmd 内容,启动时自动重建 .cmd(根治 80070002:wscript 找不到被引用启动文件)
11
11
  // v0.6.4 新增:lan 命令扩展 Linux——systemd 用户单元(systemctl --user enable/start,登录自启;--onstart 附加 loginctl enable-linger 开机即启)/ systemd 不可用时自动降级用户 crontab @reboot;lanPlatform 测试钩子(YOTTA_LAN_PLATFORM)
12
+ // v0.6.5 修复:recall/context 对同一文件显示 2 条——projectRoot 与 userRoot 指向同一目录(如 cwd=home 或其父)时同一索引被遍历两次;新增 memoryRoots() 唯一化根,hasGrant/recallCore/forgetCore/cmdReindex/contextCore 统一走 memoryRoots()
12
13
  // v0.6.2 修复:remember --verify 写后回读改为直查索引 + 权限判定 + 召回匹配性(不再依赖 recall top-N 排序,消除泛化 subject 下偶发误报「回读未命中」)
13
14
  'use strict';
14
15
 
@@ -19,7 +20,7 @@ const crypto = require('crypto');
19
20
  const http = require('http');
20
21
  const child_process = require('child_process');
21
22
 
22
- const VERSION = '0.6.4';
23
+ const VERSION = '0.6.5';
23
24
  const TYPES = ['FACT', 'PREF', 'BOUND', 'COMMIT'];
24
25
  const TYPE_DIRS = { FACT: 'facts', PREF: 'prefs', BOUND: 'bounds', COMMIT: 'commits' };
25
26
  const PUBLIC_DIR = 'facts';
@@ -57,6 +58,19 @@ function userRoot() {
57
58
  function projectRoot() {
58
59
  return path.join(process.cwd(), '.yottamemory');
59
60
  }
61
+ // 唯一化记忆库根:projectRoot 与 userRoot 可能指向同一目录(如 cwd=home 或其父时),
62
+ // 若不唯一化,recall/context 等会对同一索引遍历两次 -> 同一条记忆重复展示(v0.6.5 修复)。
63
+ function memoryRoots() {
64
+ const out = [], seen = new Set();
65
+ for (const r of [projectRoot(), userRoot()]) {
66
+ const abs = path.resolve(r);
67
+ if (!fs.existsSync(abs)) continue;
68
+ if (seen.has(abs)) continue;
69
+ seen.add(abs);
70
+ out.push(abs);
71
+ }
72
+ return out;
73
+ }
60
74
  function today() {
61
75
  const d = new Date();
62
76
  const p = (n) => String(n).padStart(2, '0');
@@ -349,7 +363,7 @@ function loadGrants(root) {
349
363
  }
350
364
  function hasGrant(userAgent, ownerAgent) {
351
365
  if (!userAgent || !ownerAgent) return false;
352
- for (const root of [projectRoot(), userRoot()]) {
366
+ for (const root of memoryRoots()) {
353
367
  if (!fs.existsSync(root)) continue;
354
368
  const grants = loadGrants(root);
355
369
  const list = grants[userAgent];
@@ -469,7 +483,7 @@ function rememberCore(type, subject, statement, opts) {
469
483
  return { error: false, text: text };
470
484
  }
471
485
  function recallCore(query, opts) {
472
- const roots = [projectRoot(), userRoot()].filter(function (r) { return fs.existsSync(r); });
486
+ const roots = memoryRoots();
473
487
  if (!roots.length) return { error: false, exitCode: 0, text: '记忆库不存在,请先运行: yotta-memory init' };
474
488
  const limit = opts.limit || 50;
475
489
  const onlyType = opts.type ? String(opts.type).toUpperCase() : null;
@@ -551,7 +565,7 @@ function relOf(root, fp) { return path.relative(root, fp).replace(/\\/g, '/'); }
551
565
  function forgetCore(fileRef, opts) {
552
566
  opts = opts || {};
553
567
  const selfAgent = opts.selfAgent || currentAgent();
554
- const roots = [projectRoot(), userRoot()].filter(function (r) { return fs.existsSync(r); });
568
+ const roots = memoryRoots();
555
569
  const ref = String(fileRef || '').replace(/\\/g, '/');
556
570
  let target = null, targetRoot = null, targetRel = null;
557
571
  for (const root of roots) {
@@ -625,7 +639,7 @@ function cmdArchive(opts) {
625
639
  console.log(r.text);
626
640
  }
627
641
  function cmdReindex() {
628
- const roots = [projectRoot(), userRoot()].filter(function (r) { return fs.existsSync(r); });
642
+ const roots = memoryRoots();
629
643
  if (!roots.length) { console.log('记忆库不存在。'); return; }
630
644
  for (const root of roots) {
631
645
  const n = buildIndex(root).length;
@@ -964,7 +978,7 @@ function selfProfileKv(root, id) {
964
978
  }
965
979
  function contextCore(opts) {
966
980
  opts = opts || {};
967
- const roots = [projectRoot(), userRoot()].filter(function (r) { return fs.existsSync(r); });
981
+ const roots = memoryRoots();
968
982
  if (!roots.length) return { error: false, exitCode: 0, text: '记忆库不存在,请先运行: yotta-memory init' };
969
983
  const root = userRoot();
970
984
  const limit = opts.limit || 10;
@@ -1830,6 +1844,7 @@ module.exports = {
1830
1844
  VERSION: VERSION,
1831
1845
  userRoot: userRoot,
1832
1846
  projectRoot: projectRoot,
1847
+ memoryRoots: memoryRoots,
1833
1848
  rememberCore: rememberCore,
1834
1849
  recallCore: recallCore,
1835
1850
  profileCore: profileCore,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yottameta/yotta-memory",
3
- "version": "0.6.4",
3
+ "version": "0.6.5",
4
4
  "description": "元忆 —— 有权限边界的文件式智能体记忆。文件式、零依赖、可 diff/回滚;FACT/PREF/BOUND/COMMIT 四分类(公共共享/私密隔离),用户级+项目级双级存储。",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -1,4 +1,4 @@
1
- # yotta-memory 协议规范 v0.6.4
1
+ # yotta-memory 协议规范 v0.6.5
2
2
 
3
3
  > 本文件定义 yotta-memory 记忆标准:存储位置、目录结构、文件格式、类型体系与 CLI 命令参考。
4
4
  > 目标:任何支持 Agent Skills 开放标准的智能体,装完即可读写同一份记忆。