dsh-prime-memory 0.24.1 → 0.24.2

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.en.md CHANGED
@@ -7,6 +7,17 @@
7
7
 
8
8
  This file covers the **0.12.0** release notes and the current **unreleased** changes in English. For the full history, see [CHANGELOG.md](./CHANGELOG.md) (Chinese).
9
9
 
10
+ ## [0.24.2] — 2026-10-14
11
+
12
+ ### Added
13
+
14
+ - **Projection identity fields in the records panel**: card headers now show "Name" and "Scope" badges, and the expanded detail adds three rows (Name / Keywords / Scope), so users can directly verify the "memory ↔ projection filename" mapping. The `UiRecord` contract (`contract.ts`) gains optional `name`/`scope`/`workspaceId`/`keywords`; `stats.ts::hitToUiRecord` reads them from the record and the `metadata.dsh_keywords` reserved key.
15
+ - **FTS keyword axis as a separate, reserved column (dormant)**: `l1_fts` is ordered `keywords → content`, so keywords form an independent BM25 axis rather than being diluted into body-text term frequency. No keyword-distillation producer exists yet ⇒ the column is always empty and retrieval behaves byte-for-byte as before (zero drift); when distillation ships, no schema change is needed (FTS5 cannot ALTER).
16
+
17
+ ### Changed
18
+
19
+ - **Hook-consolidation comment cleanup**: the retired factory name `makeSuffixSync` no longer appears anywhere in `src/` (acceptance grep = 0), leaving a single source of truth for the consolidation conclusion.
20
+
10
21
  ## [0.24.1] — 2026-10-14
11
22
 
12
23
  ### Added
package/CHANGELOG.ja.md CHANGED
@@ -9,6 +9,17 @@
9
9
 
10
10
  本ファイルは **0.12.0** リリースノートと現在の**未リリース**変更の日本語版です。全履歴は [CHANGELOG.md](./CHANGELOG.md)(中文)を参照してください。
11
11
 
12
+ ## [0.24.2] — 2026-10-14
13
+
14
+ ### 追加
15
+
16
+ - **レコードパネルの投射アイデンティティ項目**:カードヘッドに「名称」「スコープ」バッジを追加、展開詳細に3行(名称 / キーワード / スコープ)を追加し、「記憶↔投射ファイル名」の対応を直接確認できるようにした。`UiRecord` 契約(`contract.ts`)にオプションの `name`/`scope`/`workspaceId`/`keywords` を追加、`stats.ts::hitToUiRecord` がレコード本体と `metadata.dsh_keywords` 予約キーから読み出す。
17
+ - **FTS キーワード独立検索軸(予約・休止)**:`l1_fts` を「keywords → content」の2列インデックスに並べ、キーワードを本文の語頻と混ざらない独立 BM25 軸として予約。現状は蒸留の産出側がなく当該列は常に空 ⇒ 検索挙動は改修前と逐字同一(ゼロドリフト)、蒸留実装時は表構造の変更不要(FTS5 は ALTER 不可)。
18
+
19
+ ### 変更
20
+
21
+ - **フック収束コメントの整理**:退役した旧ファクトリ名 `makeSuffixSync` のリテラルが `src/` から消え(検収 grep ゼロ)、収束結論は単一の事実源のみ。
22
+
12
23
  ## [0.24.1] — 2026-10-14
13
24
 
14
25
  ### 追加
package/CHANGELOG.ko.md CHANGED
@@ -9,6 +9,17 @@
9
9
 
10
10
  이 파일은 **0.12.0** 릴리스 노트와 현재 **미출시** 변경 사항의 한국어판입니다. 전체 이력은 [CHANGELOG.md](./CHANGELOG.md)(中文)를 참조하세요.
11
11
 
12
+ ## [0.24.2] — 2026-10-14
13
+
14
+ ### 신규
15
+
16
+ - **레코드 패널의 투사 정체성 필드**: 카드 헤더에 "이름" "범위" 배지를, 전개 상세에 3행(이름 / 키워드 / 범위)을 추가해 "기억↔투사 파일명" 대응을 직접 확인할 수 있게 했습니다. `UiRecord` 계약(`contract.ts`)에 선택 필드 `name`/`scope`/`workspaceId`/`keywords`를 추가하고, `stats.ts::hitToUiRecord`가 레코드 본체와 `metadata.dsh_keywords` 예약 키에서 읽어냅니다.
17
+ - **FTS 키워드 독립 검색 축(예약·휴면)**: `l1_fts`를 "keywords → content" 2열 인덱스로 배치해 키워드를 본문 어휘 빈도와 섞이지 않는 독립 BM25 축으로 예약했습니다. 현재 증류 생산자가 없어 해당 열은 항상 비어 ⇒ 검색 동작은 변경 전과 글자 그대로 동일(영 드리프트), 증류 도입 시 테이블 구조 변경 불필요(FTS5는 ALTER 불가).
18
+
19
+ ### 변경
20
+
21
+ - **훅 수렴 주석 정리**: 퇴역한 구 팩토리명 `makeSuffixSync` 리터럴이 `src/`에서 사라져(검수 grep 0), 수렴 결론은 단일 사실 소스만 남습니다.
22
+
12
23
  ## [0.24.1] — 2026-10-14
13
24
 
14
25
  ### 추가
package/CHANGELOG.md CHANGED
@@ -17,6 +17,17 @@
17
17
  - **建议状态(`longtask-hint-get`)以纯端点提供**:判定 = 上下文占用达 `contextThresholdPct` 或 todo 漂移达 `driftThreshold`(部署配置可调);配合 `longtask-compress-tail` 作手动压缩入口。
18
18
  - **撤下浮动球 UI(`client/src/longtask-fab.ts`;beta.1 起曾随包发布)**:悬浮建议面板的归属本在 context-compression 侧(「建议启动压缩」是其领域),pm 属误载——2026-10-02 用户裁定撤下。撤下不违座位契约(settings.section 恰一个 + 输入栏 pill,body 单例不占座位),但全应用级 overlay 会与其他插件的悬浮 UI 抢占屏幕角落;长任务开关与手动压缩入口待长任务定版时落记忆设置分节。
19
19
  - **`session-mode-set` 的 `mode` 转为可选**:与 `longTask` 二选一必传——纯切长任务开关不再被迫发送档位(旧客户端恒传 mode,行为不变)。响应 `mode` 改回当前生效值。
20
+ ## [0.24.2] — 2026-10-14
21
+
22
+ ### 新增
23
+
24
+ - **检索面板投射身份字段**:RecordsTab 卡头新增「名称」「作用范围」徽标,展开详情新增三行(名称 / 关键词 / 作用范围),帮助用户直观核对「记忆↔投射文件名」的对应关系。UiRecord 契约(`contract.ts`)加 `name`/`scope`/`workspaceId`/`keywords` 四个可选字段,`stats.ts::hitToUiRecord` 从记录本体和 `metadata.dsh_keywords` 保留键读出。
25
+ - **FTS 关键词独立检索轴(预留、休眠)**:`l1_fts` 排列改为「keywords → content」两列索引,关键词作为独立 BM25 命中轴、不与正文词频混淆;当前无关键词蒸馏产出方 ⇒ 该列恒空、检索行为与改动前逐字相同(零漂移),将来蒸馏上线无需再改表(FTS5 不能 ALTER)。
26
+
27
+ ### 变更
28
+
29
+ - **挂钩收口注释清理**:`src/` 内不再残留旧工厂名 `makeSuffixSync` 字面量(验收 grep 归零),收口结论只留一处事实源。
30
+
20
31
  ## [0.24.1] — 2026-10-14
21
32
 
22
33
  ### 新增
package/dist/client.js CHANGED
@@ -4495,6 +4495,39 @@ var __defProp = Object.defineProperty;
4495
4495
  children: "用 " + m.usage.used + "/" + m.usage.attempts
4496
4496
  }
4497
4497
  ) : null,
4498
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4499
+ "span",
4500
+ {
4501
+ title: m.name && m.name.length > 0 ? "名称(名称蒸馏产物;投射文件的命名取它):" + m.name : "尚未命名(名称蒸馏未产出);投射回落 mem-" + m.id.slice(-8),
4502
+ style: {
4503
+ fontSize: 11,
4504
+ padding: "1px 6px",
4505
+ borderRadius: 999,
4506
+ whiteSpace: "nowrap",
4507
+ maxWidth: 220,
4508
+ overflow: "hidden",
4509
+ textOverflow: "ellipsis",
4510
+ border: "1px solid " + (m.name && m.name.length > 0 ? "var(--dsh-mem-border)" : "var(--dsh-mem-danger)"),
4511
+ color: m.name && m.name.length > 0 ? "var(--dsh-mem-text-2)" : "var(--dsh-mem-danger)"
4512
+ },
4513
+ children: "名称 " + (m.name && m.name.length > 0 ? m.name : "未命名")
4514
+ }
4515
+ ),
4516
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4517
+ "span",
4518
+ {
4519
+ title: m.scope === "workspace" ? "作用范围:指定工作区(仅归属工作区可见)" + (m.workspaceId ? ":" + m.workspaceId : "") : "作用范围:用户默认(global,任何工作区可见)",
4520
+ style: {
4521
+ fontSize: 11,
4522
+ padding: "1px 6px",
4523
+ borderRadius: 999,
4524
+ whiteSpace: "nowrap",
4525
+ border: "1px solid var(--dsh-mem-border)",
4526
+ color: "var(--dsh-mem-text-2)"
4527
+ },
4528
+ children: m.scope === "workspace" ? "工作区" : "用户默认"
4529
+ }
4530
+ ),
4498
4531
  m.score !== null && m.score !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: "相关度 " + Number(m.score).toFixed(2) }) : null,
4499
4532
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: S.grow }),
4500
4533
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: S.muted, children: fmtTime(m.updatedAt) }),
@@ -4523,7 +4556,7 @@ var __defProp = Object.defineProperty;
4523
4556
  ) : null
4524
4557
  ] }),
4525
4558
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: S.content, children: m.content }),
4526
- open ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: S.detail, children: "id: " + m.id + "\n情境: " + (m.scene || "-") + "\n版本: v" + m.version + "(去重合并次数 " + m.version + ")\n创建: " + fmtTime(m.createdAt) + "\n活跃时间: " + (m.timestamps && m.timestamps.length > 0 ? m.timestamps.map(fmtTime).join(" → ") : "-") + "\n" + (m.sourceAnchors && m.sourceAnchors.length > 0 ? "来源锚点: " + m.sourceAnchors.join(", ") : "来源锚点: -") }) : null
4559
+ open ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: S.detail, children: "id: " + m.id + "\n名称: " + (m.name && m.name.length > 0 ? m.name : "(未命名,投射回落 mem-" + m.id.slice(-8) + ")") + "\n情境: " + (m.scene || "-") + "\n关键词: " + (m.keywords && m.keywords.length > 0 ? m.keywords.join(",") : "(暂无 · 预留检索轴)") + "\n作用范围: " + (m.scope === "workspace" ? "指定工作区" + (m.workspaceId ? ":" + m.workspaceId : "(未记录路径)") : "用户默认(global,任何工作区可见)") + "\n版本: v" + m.version + "(去重合并次数 " + m.version + ")\n创建: " + fmtTime(m.createdAt) + "\n活跃时间: " + (m.timestamps && m.timestamps.length > 0 ? m.timestamps.map(fmtTime).join(" → ") : "-") + "\n" + (m.sourceAnchors && m.sourceAnchors.length > 0 ? "来源锚点: " + m.sourceAnchors.join(", ") : "来源锚点: -") }) : null
4527
4560
  ]
4528
4561
  },
4529
4562
  m.id
@@ -852,6 +852,28 @@ export interface UiRecord {
852
852
  maturity?: 'low' | 'mid' | 'high';
853
853
  /** 使用场景(G1):从 metadata.dsh_usage_scenario 读出;功能关/无则 undefined。 */
854
854
  usageScenario?: string[];
855
+ /**
856
+ * 名称(md 投射相,N1):名称蒸馏产出的短标题,**投射文件名就取它**
857
+ * (`<type>/<name>.memory.md` 的 stem)。`undefined`/`null` = 还没名字(存量记录),
858
+ * 投射器回落 `mem-<id8>`。面板显示它是为了核对“这条记忆对应哪个投射文件”。
859
+ * 纯投影字段:读时从 `l1_records.name` 带出,不进存储改动。
860
+ */
861
+ name?: string | null;
862
+ /**
863
+ * 可见范围(§E):`global` = 用户默认(任何工作区可见);`workspace` = 仅归属工作区可见。
864
+ * 展示用(读时从 `l1_records.scope` 带出,纯投影)。
865
+ */
866
+ scope?: 'global' | 'workspace';
867
+ /** 归属工作区路径(仅 `scope='workspace'` 时非空;`global` 恒为 `null`)。展示用。 */
868
+ workspaceId?: string | null;
869
+ /**
870
+ * 关键词(保留字段,**用于 BM25 匹配**):从 `metadata.dsh_keywords` 读出。
871
+ *
872
+ * 与 `usageScenario` 同范式(保留键、随 metadata 落库、不进 `l1_records` DDL)。
873
+ * **当前无产出方**——抽取/命名尚未产出该键,故实机上恒为空;先预留字段与检索轴,
874
+ * 让 UI 与 BM25 都就位。无键 → `undefined`(缺席 ≠ 空数组)。
875
+ */
876
+ keywords?: string[];
855
877
  /**
856
878
  * 人给的相关度均值(0..5);从未被 0..5 打过分为 undefined(**缺席 ≠ 0 分**)。
857
879
  * 读时从 recall-feedback sidecar 派生,不进存储/快照。
package/dist/stats.d.ts CHANGED
@@ -177,6 +177,12 @@ export declare function hitToUiRecord(r: {
177
177
  metadata?: Record<string, unknown>;
178
178
  score?: number;
179
179
  family?: string;
180
+ /** 名称(md 投射相):投射文件名取它;无名字 = undefined。 */
181
+ name?: string;
182
+ /** 可见范围(§E):'workspace' 才带归属,其余一律归一 'global'。 */
183
+ scope?: string;
184
+ /** 归属工作区路径(仅 scope='workspace' 时非空)。 */
185
+ workspaceId?: string;
180
186
  /** 退场判据:`valid_to` 闭合即已退场(软删)。由 `listL1`/`getByIds` 透传。 */
181
187
  validTo?: number;
182
188
  }, extra?: {
package/dist/stats.js CHANGED
@@ -2226,6 +2226,16 @@ export function hitToUiRecord(r, extra) {
2226
2226
  }),
2227
2227
  // G1 使用场景:从命名空间保留键读出(功能关/无键 → undefined)。
2228
2228
  usageScenario: Array.isArray(r.metadata?.dsh_usage_scenario) ? r.metadata?.dsh_usage_scenario : undefined,
2229
+ // 投射身份三项(N1):名称 / 可见范围 / 归属工作区。面板靠它们核对“这条记忆
2230
+ // 对应哪个投射文件、对谁可见”——这三个值此前从不进 UiRecord,于是面板上
2231
+ // 无法把记忆与投射文件对上。纯投影,不从存储侧另算。
2232
+ name: r.name ?? null,
2233
+ scope: r.scope === 'workspace' ? 'workspace' : 'global',
2234
+ workspaceId: r.scope === 'workspace' ? (r.workspaceId ?? '') || null : null,
2235
+ // 关键词(保留字段,用于 BM25):与 usageScenario 同范式,从保留键读出(无键 → undefined)。
2236
+ keywords: Array.isArray(r.metadata?.dsh_keywords)
2237
+ ? (r.metadata?.dsh_keywords).filter((k) => typeof k === 'string' && k !== '')
2238
+ : undefined,
2229
2239
  // 人给相关度均值:读时从 sidecar 派生(不进存储/快照);未打分 → 字段缺席。
2230
2240
  userRelevance: extra?.userRelevance ?? undefined,
2231
2241
  };
@@ -12,7 +12,7 @@
12
12
  * 「文件存在性 + 当前后缀 + 指纹一致性」三项检查重算一遍,与退场路径无关。
13
13
  *
14
14
  * 点火已由 `L1Store` 的汇流口接管(`store/memory-md-sync.ts`),本模块只供收敛器与
15
- * 单条凭证两个原件——曾经在这里的 `makeSuffixSync` 点火器已退役,不留第二事实源。
15
+ * 单条凭证两个原件——曾经住在这里的旧「后缀点火器工厂」已退役,不留第二事实源。
16
16
  *
17
17
  * 单点失效联动(`disableProjectionFile`)的三种落点:
18
18
  * - 盘上有 `.memory.md`(**不再要求有 workspace**:无归属那条也要改,它的文件本来就在单根)→ **改名**成 `.memory.md.disable`;
@@ -14,7 +14,7 @@
14
14
  *
15
15
  * 一句话口径:**投射文件形状是库状态的函数,不是任何调用点的事件**(事件只是重算契机)。
16
16
  *
17
- * 四条契约(前三条与 `makeSuffixSync` 时期一致,收口没有放宽):
17
+ * 四条契约(前三条与收口前一致,收口没有放宽):
18
18
  * 1. **不阻塞库**:钩子同步返回,文件侧在后台跑;磁盘满不能变成「记忆删不掉」。
19
19
  * 2. **绝不抛**:异常一律收敛成 warn(与 `disableProjectionFile` 同纪律)。
20
20
  * 3. **现读配置与账本**:`memExport` 是 volatile,快照会让「事后打开旋钮」一直到下次启动
@@ -561,10 +561,10 @@ export class MemoryDb {
561
561
  const savedStamp = this.readMetaString('fts_tokenizer') ?? 'bigram-v1';
562
562
  const tokenizerChanged = savedStamp !== wantStamp;
563
563
  let ftsRebuilt = false;
564
- if (this.tableExists('l1_fts') && (!this.hasColumn('l1_fts', 'family') || !this.hasColumn('l1_fts', 'scope') || tokenizerChanged)) {
564
+ if (this.tableExists('l1_fts') && (!this.hasColumn('l1_fts', 'family') || !this.hasColumn('l1_fts', 'scope') || !this.hasColumn('l1_fts', 'keywords') || tokenizerChanged)) {
565
565
  this.db.exec('DROP TABLE l1_fts');
566
566
  ftsRebuilt = true;
567
- this.logger?.info(`${TAG} l1_fts 缺 family/scope 列或分词器已变更(${savedStamp} → ${wantStamp}),重建全文索引`);
567
+ this.logger?.info(`${TAG} l1_fts 缺 family/scope/keywords 列或分词器已变更(${savedStamp} → ${wantStamp}),重建全文索引`);
568
568
  }
569
569
  let l0FtsRebuilt = false;
570
570
  if (this.tableExists('l0_fts') && tokenizerChanged) {
@@ -574,6 +574,7 @@ export class MemoryDb {
574
574
  }
575
575
  this.db.exec(`
576
576
  CREATE VIRTUAL TABLE IF NOT EXISTS l1_fts USING fts5(
577
+ keywords,
577
578
  content,
578
579
  content_original UNINDEXED,
579
580
  record_id UNINDEXED,
@@ -603,10 +604,10 @@ export class MemoryDb {
603
604
  )
604
605
  `);
605
606
  this.stmtL1FtsInsert = this.db.prepare(`
606
- INSERT INTO l1_fts (content, content_original, record_id, type, priority, scene_name,
607
+ INSERT INTO l1_fts (keywords, content, content_original, record_id, type, priority, scene_name,
607
608
  session_id, version, timestamp_str, timestamp_start, timestamp_end, metadata_json, family,
608
609
  scope, workspace_id)
609
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
610
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
610
611
  `);
611
612
  this.stmtL1FtsDelete = this.db.prepare('DELETE FROM l1_fts WHERE record_id = ?');
612
613
  // §E 可见范围过滤的**唯一缝**。设计要点:
@@ -783,7 +784,7 @@ export class MemoryDb {
783
784
  WHERE NOT (${retiredL1Sql()})`);
784
785
  for (const r of stmt.iterate()) {
785
786
  try {
786
- this.stmtL1FtsInsert.run(tokenizeForFts(String(r.content ?? '')), String(r.content ?? ''), String(r.record_id ?? ''), String(r.type ?? ''), Number(r.priority ?? 50), String(r.scene_name ?? ''), String(r.session_id ?? 'default'), Number(r.version ?? 0), String(r.timestamp_str ?? ''), String(r.timestamp_start ?? ''), String(r.timestamp_end ?? ''), String(r.metadata_json ?? '{}'), String(r.family ?? 'chat'),
787
+ this.stmtL1FtsInsert.run(tokenizeForFts(ftsKeywordText(parseMetadataJson(String(r.metadata_json ?? '{}')))), tokenizeForFts(String(r.content ?? '')), String(r.content ?? ''), String(r.record_id ?? ''), String(r.type ?? ''), Number(r.priority ?? 50), String(r.scene_name ?? ''), String(r.session_id ?? 'default'), Number(r.version ?? 0), String(r.timestamp_str ?? ''), String(r.timestamp_start ?? ''), String(r.timestamp_end ?? ''), String(r.metadata_json ?? '{}'), String(r.family ?? 'chat'),
787
788
  // §E:回灌必须带上可见范围——漏掉这两列等于**每次 FTS 重建都把隔离抹平**
788
789
  // (所有行回落 'global',跨工作区记忆瞬间互相可见),且没有任何报错。
789
790
  normScope(r.scope), String(r.workspace_id ?? ''));
@@ -1011,7 +1012,7 @@ export class MemoryDb {
1011
1012
  if (ftsExisted || retiredNow)
1012
1013
  this.stmtL1FtsDelete.run(record.id);
1013
1014
  if (!retiredNow) {
1014
- this.stmtL1FtsInsert.run(tokenizeForFts(record.content), record.content, record.id, type, priority, sceneName, record.sessionId ?? 'default', record.version ?? 0, ts.str, ts.start, ts.end, JSON.stringify(record.metadata ?? {}), family, scope, workspaceId);
1015
+ this.stmtL1FtsInsert.run(tokenizeForFts(ftsKeywordText(record.metadata)), tokenizeForFts(record.content), record.content, record.id, type, priority, sceneName, record.sessionId ?? 'default', record.version ?? 0, ts.str, ts.start, ts.end, JSON.stringify(record.metadata ?? {}), family, scope, workspaceId);
1015
1016
  }
1016
1017
  }
1017
1018
  }
@@ -2598,6 +2599,23 @@ export class MemoryDb {
2598
2599
  }
2599
2600
  }
2600
2601
  }
2602
+ /**
2603
+ * 关键词轴的索引文本(保留字段 `metadata.dsh_keywords`)。
2604
+ *
2605
+ * 为什么是**独立列**而不是并进 `content`:关键词是一条**独立的检索轴**——它要么
2606
+ * 精确命中、要么不命中,与正文里的 BM25 词频不是一回事(并进正文等于让关键词的
2607
+ * 权重被正文长度稀释)。`l1_fts` 因此排成「keywords → content」两列索引:将来
2608
+ * 关键词蒸馏上线时**先命中关键词轴、再回落到全文**,无需再改表结构(FTS5 不能 ALTER)。
2609
+ *
2610
+ * 目前无产出方(抽取/命名尚未产出该键)⇒ 恒为空串:空串不产生任何 token,
2611
+ * 索引与改动前逐字相同(零漂移),所以先接线、后接产线是安全的。
2612
+ */
2613
+ function ftsKeywordText(metadata) {
2614
+ const kw = Array.isArray(metadata?.dsh_keywords)
2615
+ ? metadata.dsh_keywords.filter((k) => typeof k === 'string' && k.trim() !== '')
2616
+ : [];
2617
+ return kw.join('\n');
2618
+ }
2601
2619
  /** 容忍坏 JSON 的 metadata 解析(与 rowToRecord 同口径:解析失败退化为空对象,不抛)。 */
2602
2620
  function parseMetadataJson(raw) {
2603
2621
  try {
package/dsh.plugin.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "dsh-prime-memory",
3
3
  "name": "dsh-prime-memory",
4
- "version": "0.24.1",
4
+ "version": "0.24.2",
5
5
  "description": {
6
6
  "en": "Layered distilled memory plugin (L0 capture → L1 atomic memory → L2 scenes → L3 persona) with automatic recall injection before each model step.",
7
7
  "zh": "L0~L3 分层蒸馏记忆插件:自动捕获对话、抽取原子记忆、整合场景块、蒸馏核心画像,并在模型步骤前自动召回注入。"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-prime-memory",
3
- "version": "0.24.1",
3
+ "version": "0.24.2",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org",
6
6
  "access": "public",