@a9i5k4/dsh-auto-memory 2.5.0 → 2.5.1

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.
@@ -2,7 +2,7 @@
2
2
 
3
3
  > 用途:**唯一待办入口**。跨会话/跨工具(DSH、ZCode)通用 —— 不依赖任何一方的工作记忆,全部写路径与判据。
4
4
  > 状态约定:🔴 阻塞或高优先 / 🟡 应做但可排期 / ⚪ 可选或长期 / ✅ 已关闭(留在 §J 备查,别重复劳动)
5
- > 事实基线(2026-09-13 实测):npm latest = **2.4.2**;pre 线 `D:\dsh-auto-memory` HEAD = `e55a0ec`,已跟踪文件无未提交改动;REL = tag `v2.4.2` = GitHub main = `243dee1`。
5
+ > 事实基线(2026-09-13 发版后实测):npm latest = **2.5.0**;pre 线 `D:\dsh-auto-memory` HEAD = `8ad94c3`;REL = tag `v2.5.0` = GitHub main = `7234627`(子代理执行发版,主对话独立复核三处一致)。
6
6
 
7
7
  ---
8
8
 
@@ -11,8 +11,8 @@
11
11
  | 优先级 | 事项 | 归属 | 参考 |
12
12
  | --- | --- | --- | --- |
13
13
  | 🔴 | 大排期三件套(界面 / 文档 / 首页)**等用户拍板 6 点 + 给 3 样输入** | 用户 → 执行方 | `DESIGN-OVERHAUL-PRE-RESEARCH.md` §8 |
14
- | 🟡 | **v2.5.0 待发版**:B 区三项深改已全部落地(2026-09-13),等用户令按 RELEASE-PROCESS 角色分工派子代理执行 | 执行方 | `NEXT-VERSION-TODO.md` 状态行 |
15
- | 🟡 | **procedure 记忆机制整体重构**(沿用 Hermes、社区褒贬不一;等用户统一拍板整体逻辑,期间不动引擎) | 用户 → 执行方 | 本表 §A 末条 |
14
+ | 🟡 | **PR #29 待处置**(社区修 Node 22 宿主崩溃,审阅通过;等拍板:合并 → 移植 pre 线 → 随 2.5.1 发版) | 用户 → 执行方 | 本表 §H |
15
+ | 🟡 | **procedure 记忆机制整体重构**(沿用 Hermes、社区褒贬不一;issue #30 实证同根因;等用户统一拍板整体逻辑,期间不动引擎) | 用户 → 执行方 | 本表 §A 末条 |
16
16
  | 🟡 | 群反馈·日报 CI 的**安全与运维**收口(密钥/签名/成本/告警) | ZCode | `.github/`、`docs/internal/GROUP-*.md` |
17
17
  | 🟡 | 冷启动闭环(公开用户"装上没反应") | 执行方 | 本表 §C |
18
18
  | 🟡 | 分发瘦身 + 对外元数据(npm 包 11 MB 里 86% 是 docs) | 执行方 | 本表 §D |
@@ -31,7 +31,7 @@
31
31
 
32
32
  ## B. 下一版代码改动(3 项,均已定位到行,详见 `docs/internal/NEXT-VERSION-TODO.md`)
33
33
 
34
- > **✅ 2026-09-13 状态:三项已全部落地 v2.5.0(未发版,等用户令)**。全量回归 70/70 绿;细节与验收见 `NEXT-VERSION-TODO.md` 顶部状态行与 §J 存档。以下原文保留备查(文中行号为落地前观测值)。
34
+ > **✅ 2026-09-13 状态:三项已全部落地并随 v2.5.0 发布**(pre `18807ee` / REL+tag+main `7234627` / npm latest 2.5.0,子代理执行、三处复核一致)。全量回归 70/70 绿;细节与验收见 `NEXT-VERSION-TODO.md` 顶部状态行与 §J 存档。以下原文保留备查(文中行号为落地前观测值)。
35
35
 
36
36
  - [ ] 🔴 **水位判据口径**:现触发用 `effectiveWin = win − reserve` 当分母(`lib/index.js:1900`,本机 1,048,576 − 384,000 = 664,576)→ 上下文**刚过半就触发接续**,比官方压缩点(≈80% ≈ 83.9 万)早约 45%。
37
37
  **改法**:正常触发线改用官方声明窗口(或 `min(win, hardWin)`)为分母,阈值 0.75–0.78;`reserve` 只留"距硬墙余量"展示 + 硬判据(`estTokens + reserve > win` 才硬触发)。**加反向锁**:断言"不得把 reserve 计入分母"。
@@ -100,11 +100,16 @@
100
100
  - [ ] 🟡 **运维面(待确认)**:定时班时区与失败告警(现在 11:40/20:40 + 55 分兜底重试);SCF 免费额度/成本;`index.zip` 这类二进制是否应入库(建议改为构建产物,不入 git)。
101
101
  - [ ] ⚪ **文档化**:把三份 `GROUP-*-SETUP.md` 合并成一份"从零部署"清单(含所需 secrets 名、验证命令、回滚方式)。
102
102
  - [ ] ⚪ **与插件的关系**:`.github/**` 不在 npm `files` 里(不会随包发布)—— 保持这样;若日报内容要面向用户,走 `docs/` 或 landing,不要塞进包。
103
+ - [ ] 🟡 **SCF 云函数部署滞后(2026-09-13 实测)**:仓库源码 `9461cea` 已有 `?report=N` 按需报告路由,线上 zip(版本标记 `20260913c`)没有——`?report=12` 只回 `{"v":...}`。需重新打包部署(`index.zip` 重构建 + SCF 控制台上传)。部署前 gist 直读可用替代:用 `--D--dsh_debug--` 记忆里的 fine-grained PAT(只走 shell 变量,不落盘不回显)GET `api.github.com/gists/fb17c49dab6c295346c96ac971727095` 取 `group-raw-debug.txt` 原文。
103
104
 
104
105
  ---
105
106
 
106
107
  ## H. 插件功能侧遗留
107
108
 
109
+ - [ ] 🟡 **PR #29 待处置(2026-09-13 审阅通过,等拍板)**:fei009009 修 Node 22(DSH Desktop 0.5.10/Electron)下巡检全量解压巨型会话文件令宿主必崩——`decodeZstdFramesHead`(前 8 帧/4MB 上限)+ 巡检切换调用点,`lib/subagent-gc.js` +30/-1,贡献者自证 257 会话文件全过、桌面端从必崩到稳定。**处置路径**:GitHub 合并(用户浏览器点,或授权 API 合并)→ 我移植 pre 线(`subagent-gc-pre.js:85/183` 一一对应;建议一并修 `index.js:1842` `waterWindowForSession` 的同类全量解压——PR 作者也指出了)→ 随 **2.5.1** 发版并回复 PR。
110
+ - [ ] 🟡 **issue #30(open)= procedure 管线断裂社区实证**:与 §A 末条(procedure 统一重构)同根因,挂在重构下处置;Aik358 已回复「将在发布新版本时通知」——重构发版后需回来通知该用户。
111
+ - [ ] 🟡 **工作区切换问题(叉叉基,群反馈)**:自包含只读诊断 prompt 已发、用户 15:14 已执行(群内回「已经跑了」),**报告未回传**;回传后按 `--D--dsh-auto-memory--` 记忆 `workspace-switch-user-report.md` 的四归因链判读。
112
+
108
113
  - [ ] ⚪ **子代理通知无法跨会话继承**:durable 侧 `SessionHeader.parentSession` 是 readonly,`coldResume → authorizeLineage` 抛 UNAUTHORIZED,服务契约无 re-parent/transfer/attach → 新会话**收不到旧会话的子代理完成通知**。可选路线见 `docs/internal/SUBAGENT-REPORT-ROUTING-PRE-RESEARCH.md`。
109
114
  - [ ] ⚪ **上下文桥不推子代理会话的 context**:被观测的子代理会话 runtime 从未 `capturePaths`(整段 drop);本机已做 30s 窗口限流 + 首条附 runtime key,**工作区归属改造未做**。
110
115
  - [ ] ⚪ **两个"界面零引用"端点不可删**:`/activation-inbox-pre`(契约测试 + 注入入口)、`/subagent-gc`(CLI `tools/subagent-gc.mjs`)—— 已有白名单锁守着,新增宿主独有端点必须更新白名单并注明消费者。
@@ -63,7 +63,13 @@ node tools\release.mjs <ver> --dry-run
63
63
  node tools\release.mjs <ver>
64
64
  ```
65
65
 
66
- 复核输出含 `开发树版本回写: … → <ver>`。构建会写 REL 树。
66
+ 复核输出含 `开发树版本回写: … → <ver>`。构建会写 REL 树。**构建后 pre 线的 `package.json` 已被回写为新版本 → 立即补一笔提交**(v2.5.0 教训:不补会留下脏文件,污染下一次发版的脏树闸门):
67
+
68
+ ```powershell
69
+ cd D:\dsh-auto-memory
70
+ git add package.json
71
+ git -c user.name="Aik358" -c user.email="aik358@users.noreply.github.com" commit -m "v<ver>: 回写开发树版本号(release.mjs 构建后回写)"
72
+ ```
67
73
 
68
74
  ## 阶段 5 · REL 提交 + tag
69
75
 
package/lib/client.js CHANGED
@@ -7,7 +7,7 @@
7
7
  * 3. settings.section — 自动记忆设置页(存储位置、注入、反思风格)
8
8
  * Data flows over /api/dsh-auto-memory/* (loopback-only host routes).
9
9
  */
10
- console.log('[dsh-auto-memory] client v2.5.0 fingerprint: official-window-water')
10
+ console.log('[dsh-auto-memory] client v2.5.1 fingerprint: head-frame-decode')
11
11
  window.__ModuleLoader__.load({
12
12
  id: '@a9i5k4/dsh-auto-memory',
13
13
  factory: (require) => {
@@ -567,6 +567,13 @@ window.__ModuleLoader__.load({
567
567
 
568
568
  // ───────────────────────── 更新弹窗 / 首次指导 ─────────────────────────
569
569
  var CHANGELOG = {
570
+ '2.5.1': { zh: [
571
+ '修复:DSH Desktop(Node 22/Electron)下装上本插件后 dsh web 启动 1-2 分钟必崩——每日巡检对巨型会话文件全量解压,Node 22 的 zstd 会直接崩掉宿主进程。现改用头帧解码,只解会话开头几帧即可完成判定(社区贡献者 fei009009 的 PR #29,感谢!)。',
572
+ '同类的「切会话时从磁盘推导模型/窗口」路径一并加固(前 32 帧/8MB 上限),不再有全量解压风险点。',
573
+ ], en: [
574
+ 'Fix: on DSH Desktop (Node 22/Electron), dsh web used to crash 1-2 minutes after startup with this plugin installed — the daily patrol fully decompressed giant session files, and Node 22\'s experimental zstd crashes the host process. Scanning now decodes only the first few frames (PR #29 by fei009009, thank you!).',
575
+ 'The same full-decompression path when deriving model/window from disk on session switch is hardened too (first 32 frames / 8MB cap).',
576
+ ] },
570
577
  '2.5.0': { zh: [
571
578
  '★ 水位口径修正:触发分母改用**官方声明窗口**(不再扣预留输出)——阈值 0.75 的触发点从约 46 万 token 后移到约 78.6 万,与官方「约 80% 才压缩」同一条线,不再"刚过半就接续"。',
572
579
  '★ 新增预测性硬墙:上下文实占 + 预留输出 > 窗口(下一次请求必被拒,即 400 事故边界)时立即硬触发;压缩/溢出硬触发不变。本机这类大预留路由会由硬墙率先兜底,属"最后一格"而非浪费。',
package/lib/index.js CHANGED
@@ -44,7 +44,7 @@ import { createMemoryHubPre } from './memory-hub.js'
44
44
  import { pickConsolidationTextPre } from './intent-clean.js'
45
45
  import { createStorageManagerPre } from './storage-manage.js'
46
46
  import { rankWorkspacesByMemoryRecencyPre } from './ws-overview-rank.js'
47
- import { scanPluginSubagentSessions, recycleSessions, PLUGIN_LABEL_PREFIX, decodeZstdFrames } from './subagent-gc.js'
47
+ import { scanPluginSubagentSessions, recycleSessions, PLUGIN_LABEL_PREFIX, decodeZstdFrames, decodeZstdFramesHead } from './subagent-gc.js'
48
48
  import { parseModelWindowsPre, pickWindowPre, findOfficialContextWindowPre, findSessionModelPre, scanPressureSignalsPre } from './water-window.js'
49
49
  import { buildSourceCatalog, CorpusRegistry, canonicalize } from './m4-corpus.js'
50
50
  import * as nodeZlib from 'node:zlib'
@@ -1839,7 +1839,10 @@ class MemoryEngine {
1839
1839
  if (dir) {
1840
1840
  const sessionFile = await this.resolveSessionFile(dir)
1841
1841
  const raw = sessionFile ? await readFile(sessionFile).catch(() => null) : null
1842
- const events = raw ? decodeZstdFrames(raw).split('\n').map((l) => { try { return JSON.parse(l) } catch (e) { return null } }).filter(Boolean) : []
1842
+ // 头帧解码(PR #29,2026-09-13):Node 22(Electron)下全量解压巨型会话文件会令宿主进程直接崩溃,
1843
+ // 而 request/header + request/context 都在会话开头 —— 前 32 帧 / 8MB 内必命中,够推导窗口与模型。
1844
+ // 旧巨会话切到本会话时的「切会话推导」路径因此不再有全量解压,与巡检扫描同防。
1845
+ const events = raw ? decodeZstdFramesHead(raw, 32, 8 * 1024 * 1024).split('\n').map((l) => { try { return JSON.parse(l) } catch (e) { return null } }).filter(Boolean) : []
1843
1846
  const info = findSessionModelPre(events)
1844
1847
  const wi = await this.resolveWaterWindow(info.provider, info.model)
1845
1848
  value = {
@@ -90,6 +90,35 @@ export function decodeZstdFrames(buf) {
90
90
  return Buffer.concat(parts).toString('utf8')
91
91
  }
92
92
 
93
+ /**
94
+ * 头帧解码:仅解压前 maxFrames 帧(或累计超 maxBytes 即停)。
95
+ *
96
+ * 背景(实测 2026-09-11,DSH Desktop 0.5.10 / Electron 内置 Node 22.22.1):
97
+ * Node 22 的实验性 `node:zlib` zstd 在解压巨型会话文件(数 MB 压缩、数万帧)
98
+ * 时会令整个宿主进程直接崩溃(crashpad not connected,无 JS 异常可捕获);
99
+ * 同样的文件在 Node 24 下正常。扫描会话头(header + subagent descriptor)
100
+ * 只需要最前面几帧,因此扫描路径一律改用本函数,避免全量解压巨型旧会话。
101
+ * @param {Buffer} buf - 原始文件内容。
102
+ * @param {number} [maxFrames=8] - 最多解压的帧数。
103
+ * @param {number} [maxBytes=4*1024*1024] - 解压结果累计上限(字节),超出即停。
104
+ * @returns {string} 前若干帧解压文本(坏帧跳过)。
105
+ */
106
+ export function decodeZstdFramesHead(buf, maxFrames = 8, maxBytes = 4 * 1024 * 1024) {
107
+ const parts = []
108
+ let frames = 0
109
+ let bytes = 0
110
+ for (const fr of scanZstdFrames(buf)) {
111
+ if (frames >= maxFrames || bytes >= maxBytes) break
112
+ try {
113
+ const part = zstdDecompressSync(buf.subarray(fr.start, fr.end))
114
+ parts.push(part)
115
+ frames++
116
+ bytes += part.length
117
+ } catch (e) { /* 坏帧跳过 */ }
118
+ }
119
+ return Buffer.concat(parts).toString('utf8')
120
+ }
121
+
93
122
  /**
94
123
  * 从会话日志文本里取首帧 header 与 subagent descriptor。
95
124
  * @param {string} text - 解压后的 JSONL 文本。
@@ -180,7 +209,7 @@ export async function scanPluginSubagentSessions(opts = {}) {
180
209
  }
181
210
  if (!st) { bump('no-file'); continue }
182
211
  let text = ''
183
- try { text = decodeZstdFrames(await readFile(file)) } catch (e) { bump('decode-error'); continue }
212
+ try { text = decodeZstdFramesHead(await readFile(file)) } catch (e) { bump('decode-error'); continue }
184
213
  const head = parseSessionHead(text)
185
214
  if (!head.header) { bump('no-header'); continue }
186
215
  if (head.header.origin === 'subagent') out.subagents++
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@a9i5k4/dsh-auto-memory",
3
3
  "description": "Proactive associative memory for DSH: zero-prompt recall injected before the model speaks, three-layer auto-consolidation, skill crystallization, and Astra-style context management - handoff ledgers, PLAN whiteboard, water-level sensing. Local-first, model-agnostic, zero deps. 主动联想记忆+Astra 式上下文管理:自动唤回/自动沉淀/技能固化/交接账本与白板跨窗口续命/水位感知。",
4
- "version": "2.5.0",
4
+ "version": "2.5.1",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
7
7
  "exports": {