dsh-prime-memory 0.20.0-beta.10 → 0.20.0-beta.12
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 +19 -0
- package/ENGINEERING-NOTES.md +17 -0
- package/dist/client.js +0 -2
- package/dist/pipeline/recluster.js +1 -1
- package/dist/room-review.js +2 -2
- package/dist/stats.js +4 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -17,6 +17,25 @@
|
|
|
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.20.0-beta.12] — 2026-10-02
|
|
21
|
+
|
|
22
|
+
> lint 清账 + 卸除纪律成文(ENGINEERING-NOTES 新增 C3)。**无功能变更**。
|
|
23
|
+
|
|
24
|
+
### 维护
|
|
25
|
+
|
|
26
|
+
- **eslint 清账(13 error → 0)**:longtask 撤除残渣(stats.ts 死 import ×2、RecordsTab 死 state)+ 更早批次欠账(recluster.ts 死接口与 let、rooms-registry.ts / ruminate.ts / room-review.ts / 两个测试文件的死 import 与 let)。余 4 个 warning 为基线既有(primitives/tools 的 any)。
|
|
27
|
+
- **ENGINEERING-NOTES 新增 C3「卸除也是 TDD」**:卸除先改测试表达新预期(红)→ 卸实现(绿);lint 是删除型改动的必跑门(unused import = 没卸干净的自动探测器)。
|
|
28
|
+
## [0.20.0-beta.11] — 2026-10-02
|
|
29
|
+
|
|
30
|
+
> Hall·Room **集成测试**入库(`tests/hall-room.integration.test.ts`:HTTP 面全链 × 真实存储的用户旅程,9 用例),集成首跑即抓到一个单测盲区并修复。
|
|
31
|
+
|
|
32
|
+
### 修复
|
|
33
|
+
|
|
34
|
+
- **rooms-get 合并视图 source 硬编码 `pre-registered`**(beta.4 引入):注册表条目并入计数列表时来源写死,收编(source=grown)的条目在面板计数 chips 上恒戴 ⭐ 预注册角标——身份失真。现用条目真实来源(⭐ 只归预注册;收编显示 grown)。单测盲区成因:rooms-registry 单测只测 store 层,端点合并行无人断言 grown 条目的 source。
|
|
35
|
+
|
|
36
|
+
### 测试
|
|
37
|
+
|
|
38
|
+
- `hall-room.integration.test.ts`:空表自生长计数 → 两级注册/非法 slug 拒绝 → 收编 → 导出三 kind → merge dryRun 零写入→实跑(备份落盘/退场行重写/metadata 保全/场景重算入队 source='room-merge')→ rename 别名 → retire/恢复 → 大类 200 上限+小类不占额 → 损坏只读降级红线(rooms-get 不阻塞、磁盘不回写)。
|
|
20
39
|
## [0.20.0-beta.10] — 2026-10-02
|
|
21
40
|
|
|
22
41
|
> **longtask(长任务模式)全量撤除**:该族功能的归属本在 context-compression 侧(「建议启动压缩」是其领域),pm 属误载——beta.8 撤浮动球、本版撤完剩余后端。pm 回归纯记忆域。将来若需要「立即蒸馏尾部」等能力,以 pm 本位重新设计再立项。
|
package/ENGINEERING-NOTES.md
CHANGED
|
@@ -282,6 +282,23 @@ const stores = { scenes: { chat: { list: () => gate }, work: { list: () => gate
|
|
|
282
282
|
|
|
283
283
|
**如何验证**:`tsc -p tsconfig.test.json` exit 0;新加入的测试文件必须落在 include 里。
|
|
284
284
|
|
|
285
|
+
## C3. 卸除也是 TDD —— 先改测试(红)再卸实现(绿)
|
|
286
|
+
|
|
287
|
+
**现象**:longtask 全量撤除(beta.10)时**先卸实现、后补测试**,测试全程没红过;
|
|
288
|
+
同一批还漏跑了 `eslint`(F 清单明列的门)。lint 补跑揪出 **13 个 error**:
|
|
289
|
+
一半正是撤除残渣(删了实现、import/局部量还在),另一半是更早批次欠账
|
|
290
|
+
(`recluster.ts` 死接口、`rooms-registry.ts` 死 import)——lint 若当时跑,当场就暴露。
|
|
291
|
+
|
|
292
|
+
**根因**:把"卸除"当成了"删代码",忘了它同样是**行为变更**——TDD 的红-绿循环
|
|
293
|
+
对撤除一样成立,只是方向反过来:测试先表达**新预期**,再让实现追上。
|
|
294
|
+
|
|
295
|
+
**正确做法(卸除三步)**:
|
|
296
|
+
1. **先改测试表达新预期**:契约键数(48→46)、"端点不存在"断言、必传字段恢复
|
|
297
|
+
必传……跑一遍,应当**红**(实现还在);
|
|
298
|
+
2. **卸实现**到**回绿**;实现删除的每一步都以"哪条红还没变绿"为准,不凭感觉删;
|
|
299
|
+
3. **lint 是交付门不是可选步骤**(F 清单"eslint 0 error"):删除型改动必跑——
|
|
300
|
+
unused import/死变量就是"没卸干净"的自动探测器。
|
|
301
|
+
|
|
285
302
|
---
|
|
286
303
|
|
|
287
304
|
# D. 环境与工具链陷阱
|
package/dist/client.js
CHANGED
|
@@ -3298,7 +3298,6 @@ var __defProp = Object.defineProperty;
|
|
|
3298
3298
|
});
|
|
3299
3299
|
const [roomPage, setRoomPage] = (0, import_react15.useState)(0);
|
|
3300
3300
|
const [orphanCount, setOrphanCount] = (0, import_react15.useState)(0);
|
|
3301
|
-
const [roomRegistry, setRoomRegistry] = (0, import_react15.useState)([]);
|
|
3302
3301
|
const [retiredFilter, setRetiredFilter] = (0, import_react15.useState)("");
|
|
3303
3302
|
const [rooms, setRooms] = (0, import_react15.useState)([]);
|
|
3304
3303
|
const [wingCatalog, setHallCatalog] = (0, import_react15.useState)(null);
|
|
@@ -3357,7 +3356,6 @@ var __defProp = Object.defineProperty;
|
|
|
3357
3356
|
if (r && r.ok) {
|
|
3358
3357
|
setRooms(r.value.rooms ?? []);
|
|
3359
3358
|
setOrphanCount(r.value.orphanCount ?? 0);
|
|
3360
|
-
setRoomRegistry(r.value.registry ?? []);
|
|
3361
3359
|
}
|
|
3362
3360
|
}).catch(() => {
|
|
3363
3361
|
});
|
|
@@ -15,7 +15,7 @@ export async function processSceneReclusterJobs(source, scenes, logger, maxJobs
|
|
|
15
15
|
const family = job.family === 'work' ? 'work' : 'chat';
|
|
16
16
|
const store = scenes[family];
|
|
17
17
|
// 快照在 try 外声明:catch 的回滚要用它
|
|
18
|
-
|
|
18
|
+
const snapshots = [];
|
|
19
19
|
try {
|
|
20
20
|
// ① 内存快照:按场景名(文件 basename)匹配当前存在的摘要文件
|
|
21
21
|
const all = await store.list();
|
package/dist/room-review.js
CHANGED
|
@@ -171,10 +171,10 @@ export async function mergeRoom(io, from, to, opts = {}) {
|
|
|
171
171
|
const backup = io.l1.backupTagRecords(from);
|
|
172
172
|
io.logger.info(`[memory] Room merge 备份:${from} → ${to},${backup.count} 条 → ${backup.file}`);
|
|
173
173
|
let applied = 0;
|
|
174
|
-
|
|
174
|
+
const hasMore = false; // 循环到收敛,单次调用内 hasMore 恒 false(重写返回值沿用结果形状)
|
|
175
175
|
const families = new Set();
|
|
176
176
|
const scenes = new Set();
|
|
177
|
-
// 游标重写:上限 cap/次,hasMore 时继续(总量受 cap×轮次约束,单飞内收敛)
|
|
177
|
+
// 游标重写:上限 cap/次,r.hasMore 时继续(总量受 cap×轮次约束,单飞内收敛)
|
|
178
178
|
for (;;) {
|
|
179
179
|
const r = io.l1.rewriteTag(from, to, cap);
|
|
180
180
|
applied += r.rewritten;
|
package/dist/stats.js
CHANGED
|
@@ -471,16 +471,17 @@ export async function handleEndpoint(endpoint, payload, deps) {
|
|
|
471
471
|
case 'dsh-memory/rooms-get': {
|
|
472
472
|
const rooms = stores.l1.listRooms();
|
|
473
473
|
// 端点层合并注册表(Agent A 设计):注册表 active 条目 count=0 补齐并带
|
|
474
|
-
// source/label
|
|
474
|
+
// source/label(source 用条目真实来源——收编 grown ≠ 预注册,⭐角标靠它区分);
|
|
475
|
+
// 自生长条目标 source='grown'。不动 listRooms() 的缓存语义。
|
|
475
476
|
const merged = rooms.map((r) => ({ ...r, source: 'grown' }));
|
|
476
477
|
const registry = roomRegistry?.listActive() ?? [];
|
|
477
478
|
for (const e of registry) {
|
|
478
479
|
const idx = merged.findIndex((r) => r.room === e.slug);
|
|
479
480
|
if (idx === -1) {
|
|
480
|
-
merged.push({ room: e.slug, count: 0, source:
|
|
481
|
+
merged.push({ room: e.slug, count: 0, source: e.source, label: e.label });
|
|
481
482
|
}
|
|
482
483
|
else {
|
|
483
|
-
merged[idx] = { ...merged[idx], source:
|
|
484
|
+
merged[idx] = { ...merged[idx], source: e.source, label: e.label ?? merged[idx].label };
|
|
484
485
|
}
|
|
485
486
|
}
|
|
486
487
|
const v = {
|