memory-eternal 0.10.54 → 0.11.0

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://anthropic.com/claude-code/plugin.schema.json",
3
3
  "name": "memory-eternal",
4
- "version": "0.10.54",
4
+ "version": "0.11.0",
5
5
  "description": "记忆核心(Memory Eternal):对话结束后自动沉淀知识卡到本地记忆库(~/.dsh/memory-vault),支持检索 / 召回 / 审核中心。",
6
6
  "author": {
7
7
  "name": "EternalNight996",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memory-eternal",
3
- "version": "0.10.54",
3
+ "version": "0.11.0",
4
4
  "description": "记忆核心(Memory Eternal):对话结束后自动沉淀知识卡到本地记忆库(~/.dsh/memory-vault),支持检索 / 召回 / 审核中心。",
5
5
  "author": {
6
6
  "name": "EternalNight996",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memory-eternal",
3
- "version": "0.10.54",
3
+ "version": "0.11.0",
4
4
  "description": "记忆核心(Memory Eternal):对话结束后自动沉淀知识卡到本地记忆库(~/.dsh/memory-vault),支持检索 / 召回 / 审核中心。",
5
5
  "author": {
6
6
  "name": "EternalNight996",
package/README.en.md CHANGED
@@ -6,32 +6,45 @@
6
6
  The two are **separate files** with 1:1 heading levels — when you change one, change the other
7
7
  (a new section must be added on both sides). npm / the DSH marketplace show README.md (Chinese) by default. -->
8
8
 
9
+ <p align="center">
10
+ <img src="https://raw.githubusercontent.com/EternalNight996/memory-eternal/main/assets/icon.png" width="84" alt="memory-eternal" />
11
+ </p>
12
+
13
+ <p align="center">
14
+ <b style="font-size:20px">Memory Atlas · a local-first memory library for your AI</b><br/>
15
+ <sub>Auto-capture · review first · knowledge graph · shared by every Agent</sub>
16
+ </p>
17
+
9
18
  <p align="center"><a href="README.md">简体中文(默认)</a> · <b>English</b></p>
10
19
 
11
20
  <p align="center">
12
21
  <img src="https://img.shields.io/badge/DeepSeek%20Harness-plugin-3B82F6" alt="DSH plugin" />
13
22
  <img src="https://img.shields.io/npm/v/memory-eternal" alt="npm version" />
23
+ <img src="https://img.shields.io/badge/release-v0.11.0-FF7A45" alt="v0.11.0" />
24
+ <a href="https://eternalnight996.github.io/memory-eternal/"><img src="https://img.shields.io/badge/Live%20Demo-online-FF7A45" alt="Live demo" /></a>
14
25
  <img src="https://img.shields.io/github/stars/EternalNight996/memory-eternal?style=flat" alt="GitHub stars" />
15
26
  <img src="https://img.shields.io/github/license/EternalNight996/memory-eternal" alt="license" />
16
- <a href="https://dsh.market/"><img src="https://raw.githubusercontent.com/2BingLing/dsh-market/master/assets/readme/badge-listed.svg" alt="DSH Market listed" /></a>
17
27
  </p>
18
28
 
19
29
  <p align="center">
20
- <img src="https://raw.githubusercontent.com/EternalNight996/memory-eternal/main/assets/screen/cards.png" width="900" alt="Knowledge card list: every conversation is distilled into a card you can search, audit and trace back" />
30
+ <a href="https://eternalnight996.github.io/memory-eternal/demo/"><img src="https://raw.githubusercontent.com/EternalNight996/memory-eternal/main/assets/screen/library.png" width="920" alt="Memory Atlas: library, daily resurface, cards and connection graph" /></a>
21
31
  </p>
32
+ <p align="center"><sub>▲ Memory Atlas · live demo (sample data) · <a href="https://eternalnight996.github.io/memory-eternal/demo/">open it</a></sub></p>
22
33
 
23
34
  > **Every conversation is distilled into knowledge cards; nothing is forgotten across sessions, and recall fetches only the relevant chunks — fewer tokens, less noise.**
24
35
  > Fully self-built, zero third-party memory framework, no DSH source changes; one vault shared by every Agent, SQLite persistent storage, zero external dependencies.
25
36
 
26
- <p align="center"><strong>⭐ If it saved you from explaining the same context again, a star means a lot</strong><br/><sub>DSH one-liner: <code>dsh plugin --profile web add memory-eternal</code></sub></p>
37
+ <p align="center"><strong>⭐ If it saved you from explaining the same context again, a star means a lot</strong><br/><sub>DSH one-liner: <code>dsh plugin --profile desktop add memory-eternal</code></sub></p>
38
+
39
+ <p align="center"><a href="https://eternalnight996.github.io/memory-eternal/"><b>🌐 Live site</b></a> · <a href="https://eternalnight996.github.io/memory-eternal/demo/"><b>Open the memory library demo</b></a> <sub>(sample data, no install)</sub></p>
27
40
 
28
41
  <p align="center">
29
- <img src="https://raw.githubusercontent.com/EternalNight996/memory-eternal/main/assets/screen/graph.png" width="32%" alt="Knowledge graph: 897 nodes / 4257 edges, coloured by kind, cross-vault aggregation and export" />
30
- <img src="https://raw.githubusercontent.com/EternalNight996/memory-eternal/main/assets/screen/health.png" width="32%" alt="Health overview: database / backups / auto-capture / versions — spot anything broken silently" />
31
- <img src="https://raw.githubusercontent.com/EternalNight996/memory-eternal/main/assets/screen/audit.png" width="32%" alt="Audit centre: AI-written cards are reviewed before they land; batch approve / reject / recycle" />
42
+ <img src="https://raw.githubusercontent.com/EternalNight996/memory-eternal/main/assets/screen/audit.png" width="32%" alt="Review: type bar, queue and verdict sidebar" />
43
+ <img src="https://raw.githubusercontent.com/EternalNight996/memory-eternal/main/assets/screen/graph.png" width="32%" alt="Knowledge graph: kind colours, cluster legend, cross-vault aggregation" />
44
+ <img src="https://raw.githubusercontent.com/EternalNight996/memory-eternal/main/assets/screen/reader.png" width="32%" alt="Reader: content plus TOC, tags and related memories" />
32
45
  </p>
33
46
 
34
- <p align="center"><sub>▲ Card list · knowledge graph · health · audit centre — real screenshots from a running instance (1280×860)</sub></p>
47
+ <p align="center"><sub>▲ Real screenshots: review verdict · knowledge graph · reader</sub></p>
35
48
 
36
49
  ---
37
50
 
@@ -69,7 +82,7 @@ cd ~/.dsh/profiles/web && pnpm add memory-eternal@latest
69
82
  # right after a release, @latest can be held back by pnpm's minimum-release-age gate or a cached
70
83
  # packument (it silently stays on the old version): pin the version instead — pnpm adds it to the
71
84
  # workspace's minimumReleaseAgeExclude automatically
72
- cd ~/.dsh/profiles/web && pnpm add memory-eternal@0.9.6
85
+ cd ~/.dsh/profiles/web && pnpm add memory-eternal@0.11.0
73
86
 
74
87
  # verify the version, then restart the host
75
88
  node -e "console.log(require('memory-eternal/package.json').version)"
@@ -377,14 +390,16 @@ curl http://127.0.0.1:7999/memory-eternal/api/web-info # is the standalone we
377
390
 
378
391
  | Version | Date | Highlights |
379
392
  |---|---|---|
380
- | **v0.10.54** | 2026-10-20 | **More reliable distillation with local models (#48), plus a refreshed README with new screenshots**. ① **#48**: a local 30B model takes 40-60s to cold start while the distill timeout was **hardcoded to 45s**, so every cold start aborted; the timeout is now configurable via **captureTimeoutMs** (still 45s by default, 120000+ recommended for local inference) and **a timeout retries the same candidate once with a longer budget** instead of switching models. ② **The second shape of #48**: when the provider does not report max-tokens, a truncated answer only shows up as unterminated JSON, so a dedicated **TRUNCATED_OUTPUT** code now joins MAX_TOKENS on the "double the output budget and retry the same candidate" ladder. ③ The settings page gains a distill timeout (ms) field. ④ **README refresh**: all real screenshots (cards, a graph with 897 nodes / 4257 edges, health overview, audit centre, settings) plus a "what problem does it solve" comparison table and a clearer value proposition and star call-to-action (both languages). npm test now runs **440 checks** |
381
- | **v0.10.53** | 2026-10-20 | **Health panel (reliability line): all previously invisible state in one place**. A new "Health" card at the top of the usage page shows: ① **database** (journal mode, writability, last health check, with doctor guidance when bad); ② **backups** (count and age of the newest, amber past 7 days, red at zero); ③ **auto capture** (last success/failure with reason); ④ **versions** (disk / resident / host, plus a Start check button because align needs the npm registry and cannot run automatically). Data comes from existing endpoints: /overview now includes a **backups summary** (count/newestAt/last five filenames) alongside /capture-log and /align. Also **fixes a white-screen bug**: the card initially used tf(), which only exists in the ConfigPanel scope, so opening the usage page blanked the whole app; the panel checker gained two gates — **page alive (textLen<20 counts as blank)** and **Runtime.exceptionThrown capture** — because a blank page previously passed the overflow assertions. Adds tests/health-panel.test.mjs (4 checks). npm test now runs **437 checks** |
393
+ | **v0.11.0** | 2026-10-22 | **Memory Atlas stable release**: the full V5 UI lands — 4-column library cards with daily resurface and mini connection graphs; review top type bar + queue + right verdict sidebar (no bottom bar, no popups); knowledge graph page head/cluster legend + DPR, grid and edge rendering optimizations; four runtime status cards; reader TOC and related memories; Jinwu brand icon; click-to-zoom QR codes; onboarding starts with Star/Fork; GitHub/Gitee/npm shipped together. |
394
+ | **v0.11.0-rc.1** | 2026-10-21 | **V5 preview RC**: Memory Atlas dark ember theme, 228px rail and topbar; V5 card grid and page head; audit top type bar + queue + verdict preview + select-all batch approve/reject; smaller graph default; first-run guide (👍 emphasised), reader TOC/related memory, and support rail (community/sponsor/legacy/bug report); public demo updated to V5. |
382
395
 
383
396
  <details>
384
397
  <summary>Older release notes (v0.10.52 and earlier · 79 releases, click to expand)</summary>
385
398
 
386
399
  | Version | Date | Highlights |
387
400
  |---|---|---|
401
+ | **v0.10.54** | 2026-10-20 | **More reliable distillation with local models (#48), plus a refreshed README with new screenshots**. ① **#48**: a local 30B model takes 40-60s to cold start while the distill timeout was **hardcoded to 45s**, so every cold start aborted; the timeout is now configurable via **captureTimeoutMs** (still 45s by default, 120000+ recommended for local inference) and **a timeout retries the same candidate once with a longer budget** instead of switching models. ② **The second shape of #48**: when the provider does not report max-tokens, a truncated answer only shows up as unterminated JSON, so a dedicated **TRUNCATED_OUTPUT** code now joins MAX_TOKENS on the "double the output budget and retry the same candidate" ladder. ③ The settings page gains a distill timeout (ms) field. ④ **README refresh**: all real screenshots (cards, a graph with 897 nodes / 4257 edges, health overview, audit centre, settings) plus a "what problem does it solve" comparison table and a clearer value proposition and star call-to-action (both languages). npm test now runs **440 checks** |
402
+ | **v0.10.53** | 2026-10-20 | **Health panel (reliability line): all previously invisible state in one place**. A new "Health" card at the top of the usage page shows: ① **database** (journal mode, writability, last health check, with doctor guidance when bad); ② **backups** (count and age of the newest, amber past 7 days, red at zero); ③ **auto capture** (last success/failure with reason); ④ **versions** (disk / resident / host, plus a Start check button because align needs the npm registry and cannot run automatically). Data comes from existing endpoints: /overview now includes a **backups summary** (count/newestAt/last five filenames) alongside /capture-log and /align. Also **fixes a white-screen bug**: the card initially used tf(), which only exists in the ConfigPanel scope, so opening the usage page blanked the whole app; the panel checker gained two gates — **page alive (textLen<20 counts as blank)** and **Runtime.exceptionThrown capture** — because a blank page previously passed the overflow assertions. Adds tests/health-panel.test.mjs (4 checks). npm test now runs **437 checks** |
388
403
  | **v0.10.52** | 2026-10-19 | **Redaction hole in the diagnostic bundle (privacy fix; upgrade recommended)**. The 0.10.51 one-command bundle had a gap: the home directory appears in **JSON-escaped form** (C:\\Users\\x) inside doctor/align --json output and meta.json, while only the plain and forward-slash variants were replaced, so the bundle could still be grepped for the home path. All three variants (plain, forward slash, JSON escaped) now become <home>, with a test assert added for the escaped form; a freshly generated bundle on this machine verifies as **no home path and no sk- keys**. If you already generated and shared a bundle with 0.10.51, please regenerate it before sharing. npm test now runs **433 checks** |
389
404
  | **v0.10.51** | 2026-10-19 | **One-command diagnostic bundle: dsh-memory support** (reliability line; in #47 the user-pasted context was truncated by GitHub so I could not see the full picture — this exists for exactly that kind of exchange). A single command produces a **zip** with meta (version matrix / platform / node / vault), doctor, align, status, the watchdog lock, the host heartbeat, the shared config, the tail of the capture log (200 lines by default) and a README; everything is **redacted before writing** (home directory to <home>, sk-/ghp_/github_pat/Bearer and key-like config fields to ***). Implemented with **no dependencies**: a hand-written store/deflate ZIP writer (lib/zip.js) whose output opens in Windows Explorer (verified by extracting with Expand-Archive). In restricted environments --no-spawn skips the sub-processes, while --out and --tail N control destination and log length. Adds tests/support-bundle.test.mjs (redaction, zip structure, no plaintext secrets inside the bundle, CLI wiring). npm test now runs **433 checks** |
390
405
  | **v0.10.50** | 2026-10-19 | **Models that ignore JSON no longer burn a call every turn (a follow-up to #47)**. ① "The model replied with prose and produced no JSON object at all" is now separated from the generic UNPARSEABLE_OUTPUT failure and gets its own code **MODEL_NOT_JSON**, with wording that says the model likely does not follow structured output. ② New `lib/model-strikes.js` records which provider/model recently ignored the format (24h window, at most 50 entries) and the host moves those to the end of the candidate list when routing (never removing them; if every candidate was struck the original order is kept, so we never run out), logging a "candidates reordered" line. ③ Effect: models such as stepfun/step-api, which answer distillation prompts conversationally, stop being tried first from the second turn on, saving a pointless call each time. Adds `tests/model-strikes.test.mjs` (prose detection, stable ranking, record window and trimming, wiring guards). npm test now runs **429 checks** |
package/README.md CHANGED
@@ -6,32 +6,45 @@
6
6
  两份是**独立文件**、标题层级一一对应;改一处请同步另一处(新增一节要两边都加)。
7
7
  npm / DSH 插件市场默认展示本文件(中文)。 -->
8
8
 
9
+ <p align="center">
10
+ <img src="https://raw.githubusercontent.com/EternalNight996/memory-eternal/main/assets/icon.png" width="84" alt="memory-eternal" />
11
+ </p>
12
+
13
+ <p align="center">
14
+ <b style="font-size:20px">Memory Atlas · 本地优先的 AI 记忆库</b><br/>
15
+ <sub>自动沉淀 · 先审后入 · 知识星图 · 全 Agent 共享</sub>
16
+ </p>
17
+
9
18
  <p align="center"><b>简体中文(默认)</b> · <a href="README.en.md">English</a></p>
10
19
 
11
20
  <p align="center">
12
21
  <img src="https://img.shields.io/badge/DeepSeek%20Harness-plugin-3B82F6" alt="DSH plugin" />
13
22
  <img src="https://img.shields.io/npm/v/memory-eternal" alt="npm version" />
23
+ <img src="https://img.shields.io/badge/release-v0.11.0-FF7A45" alt="v0.11.0" />
24
+ <a href="https://eternalnight996.github.io/memory-eternal/"><img src="https://img.shields.io/badge/Live%20Demo-online-FF7A45" alt="Live demo" /></a>
14
25
  <img src="https://img.shields.io/github/stars/EternalNight996/memory-eternal?style=flat" alt="GitHub stars" />
15
26
  <img src="https://img.shields.io/github/license/EternalNight996/memory-eternal" alt="license" />
16
- <a href="https://dsh.market/"><img src="https://raw.githubusercontent.com/2BingLing/dsh-market/master/assets/readme/badge-listed-zh.svg" alt="DSH Market 收录" /></a>
17
27
  </p>
18
28
 
19
29
  <p align="center">
20
- <img src="https://raw.githubusercontent.com/EternalNight996/memory-eternal/main/assets/screen/cards.png" width="900" alt="知识卡列表:对话结束自动沉淀成卡,可检索 / 可审核 / 可追溯来源" />
30
+ <a href="https://eternalnight996.github.io/memory-eternal/demo/"><img src="https://raw.githubusercontent.com/EternalNight996/memory-eternal/main/assets/screen/library.png" width="920" alt="Memory Atlas:记忆库、今日回看、知识卡与连接星图" /></a>
21
31
  </p>
32
+ <p align="center"><sub>▲ Memory Atlas · 在线 Demo(示例数据)· <a href="https://eternalnight996.github.io/memory-eternal/demo/">点此打开</a></sub></p>
22
33
 
23
34
  > **对话结束自动沉淀成知识卡,跨会话不失忆;召回只取相关小块,省 token 少噪音。**
24
35
  > 全自研、零第三方记忆框架、不改 DSH 源码;一个记忆库所有 Agent 共享,SQLite 持久存储,零外部依赖。
25
36
 
26
- <p align="center"><strong>⭐ 如果它帮你少解释了一遍上下文,点个 Star 就是最大的支持</strong><br/><sub>DSH 一条命令:<code>dsh plugin --profile web add memory-eternal</code></sub></p>
37
+ <p align="center"><strong>⭐ 如果它帮你少解释了一遍上下文,点个 Star 就是最大的支持</strong><br/><sub>DSH 一条命令:<code>dsh plugin --profile desktop add memory-eternal</code></sub></p>
38
+
39
+ <p align="center"><a href="https://eternalnight996.github.io/memory-eternal/"><b>🌐 在线体验</b></a> · <a href="https://eternalnight996.github.io/memory-eternal/demo/"><b>打开记忆库 Demo</b></a> <sub>(示例数据,不用安装)</sub></p>
27
40
 
28
41
  <p align="center">
29
- <img src="https://raw.githubusercontent.com/EternalNight996/memory-eternal/main/assets/screen/graph.png" width="32%" alt="知识图谱:897 节点 / 4257 连线,按类型着色、支持跨库聚合与导出" />
30
- <img src="https://raw.githubusercontent.com/EternalNight996/memory-eternal/main/assets/screen/health.png" width="32%" alt="健康概览:知识库 / 备份 / 自动沉淀 / 版本,一眼看清有没有静默坏掉的东西" />
31
- <img src="https://raw.githubusercontent.com/EternalNight996/memory-eternal/main/assets/screen/audit.png" width="32%" alt="审核中心:AI 写的卡先审后入,可批量批准 / 驳回 / 回收" />
42
+ <img src="https://raw.githubusercontent.com/EternalNight996/memory-eternal/main/assets/screen/audit.png" width="32%" alt="待审:顶部类型条 + 队列 + 右侧判词栏" />
43
+ <img src="https://raw.githubusercontent.com/EternalNight996/memory-eternal/main/assets/screen/graph.png" width="32%" alt="知识星图:按类型着色、连接簇图例、跨库聚合" />
44
+ <img src="https://raw.githubusercontent.com/EternalNight996/memory-eternal/main/assets/screen/reader.png" width="32%" alt="读卡器:正文 + 右侧目录、标签与相关记忆" />
32
45
  </p>
33
46
 
34
- <p align="center"><sub>▲ 知识卡列表 · 知识图谱 · 健康概览 · 审核中心 —— 全部是真实运行截图(1280×860)</sub></p>
47
+ <p align="center"><sub>▲ 真实运行截图:待审判词 · 知识星图 · 读卡器</sub></p>
35
48
 
36
49
  ---
37
50
 
@@ -68,7 +81,7 @@ cd ~/.dsh/profiles/web && pnpm add memory-eternal@latest
68
81
 
69
82
  # 刚发新版时 @latest 可能被 pnpm 的最小发布年龄门槛/元数据缓存挡住(静默停在旧版):
70
83
  # 直接指定版本号最快,pnpm 会自动把它加进 workspace 的 minimumReleaseAgeExclude
71
- cd ~/.dsh/profiles/web && pnpm add memory-eternal@0.9.6
84
+ cd ~/.dsh/profiles/web && pnpm add memory-eternal@0.11.0
72
85
 
73
86
  # 验版本(应等于上面装的号),然后重启对应宿主生效
74
87
  node -e "console.log(require('memory-eternal/package.json').version)"
@@ -409,14 +422,16 @@ curl http://127.0.0.1:7999/memory-eternal/api/web-info # 独立 web 是否活
409
422
 
410
423
  | 版本 | 日期 | 关键改动 |
411
424
  |---|---|---|
412
- | **v0.10.54** | 2026-10-20 | **本地大模型蒸馏更稳(#48)+ README 焕新与最新截图**。① **#48**:本地 30B 模型冷启动要 40–60 秒,而蒸馏超时**硬编码 45 秒** → 每次冷启动必报 ABORTED;现在超时可配 **captureTimeoutMs**(默认仍 45s,本地推理建议 120000+),且**超时后自动用更长超时重试同一候选一次**(不直接换模型)。② **#48 的第二种形态**:模型不给 max-tokens finish 时,截断只表现为「JSON 未闭合」→ 新增独立错误码 **TRUNCATED_OUTPUT**,与 MAX_TOKENS 一起走「加倍输出预算重试同一候选」的阶梯。③ 配置页新增「蒸馏超时(毫秒)」输入项。④ **README 焕新**:全部换成真实运行截图(知识卡 / 知识图谱 897 节点 4257 连线 / 健康概览 / 审核中心 / 配置页)+ 新增「它到底解决什么问题」对照表 + 更清晰的卖点与 Star 引导(中英同步)。npm test 共 **440 项** |
413
- | **v0.10.53** | 2026-10-20 | **健康面板(可靠性线):把看不见的状态集中一处**。在「用量/今日」顶部新增「🩺 健康概览」:① **知识库**(journal 模式 / 可写 / 最后一次体检时间,异常时给 doctor 指引);② **备份**(数量 + 最近一次多久前,>7 天标黄、0 备份标红);③ **自动沉淀**(最近一次成功/失败与原因);④ **版本**(磁盘 / 常驻 / 宿主;未检查时给「开始检查」按钮,因为 align 要联网比 npm 不能自动跑)。数据来自既有接口:/overview 新增 **backups 摘要**(count/newestAt/最近 5 个文件名),加上 /capture-log 与 /align。**顺带修一个白屏 bug**:健康卡最初误用了 ConfigPanel 作用域的 tf() → 点开「用量/今日」整页白屏;同时给 panel-check 补了两道闸 —— **页面存活(textLen<20 判空白页)** 与 **Runtime.exceptionThrown 捕获**,因为「白屏没有横向溢出」原本会让检查通过。新增 tests/health-panel.test.mjs(4 项)。npm test 共 **437 项** |
425
+ | **v0.11.0** | 2026-10-22 | **Memory Atlas 正式版**:V5 UI 全量落地 —— 记忆库 4 列知识卡 + 今日回看 + 固定/连接微缩图;待审顶部类型条 + 队列 + 右侧判词栏(无底部栏、无弹窗);知识星图 V5 页头/连接簇图例 + DPR/网格/边渲染优化;运行状态四张状态卡;读卡器右侧目录/相关记忆;金乌品牌图标;二维码点击放大;首次引导先 Star/Fork;GitHub/Gitee/npm 三端同步。 |
426
+ | **v0.11.0-rc.1** | 2026-10-21 | **V5 预览 RC**:Memory Atlas 深色余烬视觉、228px 侧栏与顶栏;记忆库 V5 卡片网格 + 页头;审核顶部类型条 + 队列 + 判词预览 + 全选批量批准/驳回;星图默认缩小;首次引导(重点 👍)、读卡器目录/相关记忆与左栏交流群/赞助/旧程序/异常反馈;公开 Demo 同步 V5。 |
414
427
 
415
428
  <details>
416
429
  <summary>更早的更新日志(v0.10.52 及以前 · 共 79 版,点开查看)</summary>
417
430
 
418
431
  | 版本 | 日期 | 关键改动 |
419
432
  |---|---|---|
433
+ | **v0.10.54** | 2026-10-20 | **本地大模型蒸馏更稳(#48)+ README 焕新与最新截图**。① **#48**:本地 30B 模型冷启动要 40–60 秒,而蒸馏超时**硬编码 45 秒** → 每次冷启动必报 ABORTED;现在超时可配 **captureTimeoutMs**(默认仍 45s,本地推理建议 120000+),且**超时后自动用更长超时重试同一候选一次**(不直接换模型)。② **#48 的第二种形态**:模型不给 max-tokens finish 时,截断只表现为「JSON 未闭合」→ 新增独立错误码 **TRUNCATED_OUTPUT**,与 MAX_TOKENS 一起走「加倍输出预算重试同一候选」的阶梯。③ 配置页新增「蒸馏超时(毫秒)」输入项。④ **README 焕新**:全部换成真实运行截图(知识卡 / 知识图谱 897 节点 4257 连线 / 健康概览 / 审核中心 / 配置页)+ 新增「它到底解决什么问题」对照表 + 更清晰的卖点与 Star 引导(中英同步)。npm test 共 **440 项** |
434
+ | **v0.10.53** | 2026-10-20 | **健康面板(可靠性线):把看不见的状态集中一处**。在「用量/今日」顶部新增「🩺 健康概览」:① **知识库**(journal 模式 / 可写 / 最后一次体检时间,异常时给 doctor 指引);② **备份**(数量 + 最近一次多久前,>7 天标黄、0 备份标红);③ **自动沉淀**(最近一次成功/失败与原因);④ **版本**(磁盘 / 常驻 / 宿主;未检查时给「开始检查」按钮,因为 align 要联网比 npm 不能自动跑)。数据来自既有接口:/overview 新增 **backups 摘要**(count/newestAt/最近 5 个文件名),加上 /capture-log 与 /align。**顺带修一个白屏 bug**:健康卡最初误用了 ConfigPanel 作用域的 tf() → 点开「用量/今日」整页白屏;同时给 panel-check 补了两道闸 —— **页面存活(textLen<20 判空白页)** 与 **Runtime.exceptionThrown 捕获**,因为「白屏没有横向溢出」原本会让检查通过。新增 tests/health-panel.test.mjs(4 项)。npm test 共 **437 项** |
420
435
  | **v0.10.52** | 2026-10-19 | **诊断包脱敏补漏(隐私修复,建议尽快升级)**。0.10.51 的「一键诊断包」有个漏点:doctor/align --json 与 meta.json 里的家目录是 **JSON 转义形态**(C:\\Users\\x),而我只替换了原样/正斜杠两种写法 → 包里仍能 grep 到家目录明文。现在三种写法(原样、正斜杠、JSON 转义)都替换成 <home>,并在测试里加了一条「JSON 转义形态不能漏」的断言;本机重新生成诊断包实测:**无家目录明文、无 sk- 密钥**。**如果你已经用 0.10.51 生成过诊断包并分享出去,建议重新生成一次再分享。** npm test 共 **433 项** |
421
436
  | **v0.10.51** | 2026-10-19 | **一键诊断包 dsh-memory support**(可靠性线;#47 里用户贴的现场被 GitHub 截断,我拿不到完整信息,这功能就是为这类沟通做的)。一条命令生成 **zip**:meta(版本矩阵/平台/node/vault)/ doctor / align / status / 看门狗锁 / 宿主心跳 / 共享配置 / 沉淀日志尾巴(默认 200 行)+ README;写入前**统一脱敏**(家目录→<home>,sk-/ghp_/github_pat/Bearer/配置里 key 类字段→***)。实现为**零依赖**:自写 store/deflate ZIP 写入器(lib/zip.js,Windows 资源管理器可直接打开,实测 Expand-Archive 解压正常)。受限环境可加 --no-spawn 跳过子进程;--out 指定输出、--tail N 控制日志条数。新增 tests/support-bundle.test.mjs(4 项:脱敏、zip 结构、包内不含明文密钥、CLI 接线)。npm test 共 **433 项** |
422
437
  | **v0.10.50** | 2026-10-19 | **「模型不守 JSON」不再每轮白烧调用(#47 衍生改进)**。① 把「模型回了散文、输出里根本没有 JSON 对象」从笼统的 UNPARSEABLE_OUTPUT 里拆出来,给独立错误码 **MODEL_NOT_JSON**,文案直接说清「该模型可能不遵守结构化输出」。② 新增 `lib/model-strikes.js`:记下「哪个 provider/model 最近不守格式」(24h 窗口、最多 50 条),宿主选路时把它们**排到候选末尾**(不删除;全部命中过则按原顺序兜底,绝不没候选),并留一条「蒸馏候选已调整」日志。③ 效果:像 stepfun/step-api 这种会把蒸馏当聊天回的模型,第二轮起就不再优先尝试,省掉每次的无效调用。新增 `tests/model-strikes.test.mjs`(4 项:散文识别 / 排序稳定性 / 记录窗口与裁剪 / 接线守卫)。npm test 共 **429 项** |
Binary file
package/index.js CHANGED
@@ -1287,6 +1287,21 @@ export function apply(ctx, config) {
1287
1287
  // 是相对路径,所以在这三个路由下都会解析到 /memory-eternal/ui/app.js —— 天然同源。
1288
1288
  // 为什么记忆库页也要同源(issue #29):iframe 过去指向「常驻实例监听的那个端口」,
1289
1289
  // 而自愈/漂移会让那个端口变成死地址 → 记忆页「拒绝连接」。同源后地址与端口彻底解耦。
1290
+ if (pathname.startsWith(API_PREFIX + '/ui/support/')) {
1291
+ const name = pathname.slice((API_PREFIX + '/ui/support/').length)
1292
+ if (!/^[a-z0-9-]+\.(jpg|jpeg|png)$/i.test(name)) {
1293
+ res.writeHead(404, { 'Content-Type': 'text/plain; charset=utf-8' })
1294
+ return res.end('not found')
1295
+ }
1296
+ try {
1297
+ const buf = await fs.readFile(path.join(PACKAGE_ROOT, 'web', 'support', name))
1298
+ res.writeHead(200, { 'Content-Type': /\.png$/i.test(name) ? 'image/png' : 'image/jpeg', 'Cache-Control': 'public, max-age=3600' })
1299
+ return res.end(buf)
1300
+ } catch (error) {
1301
+ res.writeHead(404, { 'Content-Type': 'text/plain; charset=utf-8' })
1302
+ return res.end('not found')
1303
+ }
1304
+ }
1290
1305
  if (pathname === API_PREFIX + '/ui/app' || pathname === API_PREFIX + '/ui/config' || pathname === API_PREFIX + '/ui/app.js') {
1291
1306
  const { readFile } = fs
1292
1307
  const webRoot = path.join(PACKAGE_ROOT, 'web')
package/lib/api.js CHANGED
@@ -15,6 +15,7 @@ import { gzipSync, brotliCompressSync, constants as zlibConstants } from 'node:z
15
15
  import os from 'node:os'
16
16
  import fs, { readFileSync } from 'node:fs'
17
17
  import path from 'node:path'
18
+ import { spawn } from 'node:child_process'
18
19
  import { listCards, countCards, readCard, search, searchAll, graph, graphAll, overview, exportCards, deleteCard, writeCard, parseCard, stats, optimizeCandidates, optimizeApply, addFeedback, dailyCounts, mergeCards, ensureVault, auditQueue, recycleList, purgeExpired, setCardStatus, restoreCard, mainStoreBodies } from './vault.js'
19
20
  import { compressExcerpt, DEFAULT_CAPTURE_MAX_TOKENS } from './capture.js'
20
21
  import { buildDiagnostics } from './feedback.js'
@@ -30,6 +31,26 @@ export function broadcast(event, data) { return hub.broadcast(event, data) }
30
31
 
31
32
  export const API_PREFIX = '/memory-eternal/api'
32
33
 
34
+ // 浏览器/Electron 里 target=_blank 可能被宿主拦截;由本机 Node 进程调用系统默认浏览器。
35
+ // 只允许项目自己的 GitHub 地址,避免变成任意 URL 打开器。
36
+ function openExternalUrl(raw) {
37
+ let u
38
+ try { u = new URL(String(raw || '')) } catch { return { ok: false, error: 'bad url' } }
39
+ const allowed = u.protocol === 'https:' && u.hostname === 'github.com' && u.pathname.startsWith('/EternalNight996/memory-eternal')
40
+ if (!allowed) return { ok: false, error: 'url not allowed' }
41
+ try {
42
+ let child
43
+ if (process.platform === 'win32') child = spawn('rundll32', ['url.dll,FileProtocolHandler', u.href], { detached: true, stdio: 'ignore', windowsHide: true })
44
+ else if (process.platform === 'darwin') child = spawn('open', [u.href], { detached: true, stdio: 'ignore' })
45
+ else child = spawn('xdg-open', [u.href], { detached: true, stdio: 'ignore' })
46
+ child.on('error', () => {})
47
+ child.unref()
48
+ return { ok: true, url: u.href }
49
+ } catch (e) {
50
+ return { ok: false, error: String((e && e.message) || e) }
51
+ }
52
+ }
53
+
33
54
  // npm 最新版本缓存(避免每次点「检查更新」都打 registry)
34
55
  const versionCache = { at: 0, latest: '' }
35
56
 
@@ -477,6 +498,10 @@ export function createApi(deps = {}) {
477
498
  }, 300)
478
499
  return
479
500
  }
501
+ case '/open-external': {
502
+ if (req.method && req.method !== 'POST') return json(res, 405, { ok: false, error: 'method not allowed' })
503
+ return json(res, 200, openExternalUrl(query.get('url')))
504
+ }
480
505
  case '/diagnostics': {
481
506
  // 「反馈异常」用:返回一段可直接贴进 issue 的**已脱敏**诊断文本。
482
507
  // 宿主与独立 web 共用这个实现;home 目录、各类 key/token 全都会被替换掉。