memory-eternal 0.20.0 → 0.21.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.20.0",
4
+ "version": "0.21.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.20.0",
3
+ "version": "0.21.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.20.0",
3
+ "version": "0.21.0",
4
4
  "description": "记忆核心(Memory Eternal):对话结束后自动沉淀知识卡到本地记忆库(~/.dsh/memory-vault),支持检索 / 召回 / 审核中心。",
5
5
  "author": {
6
6
  "name": "EternalNight996",
@@ -2,7 +2,7 @@
2
2
  "name": "memory-eternal",
3
3
  "displayName": "Memory Atlas",
4
4
  "description": "Memory-eternal: open the local Memory Atlas library, review queue and knowledge graph in a Cursor/VS Code webview.",
5
- "version": "0.20.0",
5
+ "version": "0.21.0",
6
6
  "publisher": "EternalNight996",
7
7
  "license": "MIT",
8
8
  "repository": {
@@ -2,7 +2,7 @@
2
2
  "$schema": "urn:dsh-std:community-draft:dsh-plugin:0.15",
3
3
  "id": "memory-eternal-tui",
4
4
  "name": "memory-eternal-tui",
5
- "version": "0.20.0",
5
+ "version": "0.21.0",
6
6
  "manifestVersion": "0.15",
7
7
  "description": "Open Memory Atlas from dsh-TUI: native /audit scene plus browser launcher.",
8
8
  "facets": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memory-eternal-tui",
3
- "version": "0.20.0",
3
+ "version": "0.21.0",
4
4
  "description": "Memory Atlas for dsh-TUI: /audit scene with reason/severity, batch confirmation and reject reasons.",
5
5
  "type": "module",
6
6
  "main": "main.js",
package/lib/api.js CHANGED
@@ -17,7 +17,7 @@ import fs, { readFileSync } from 'node:fs'
17
17
  import path from 'node:path'
18
18
  import { fileURLToPath } from 'node:url'
19
19
  import { spawn } from 'node:child_process'
20
- import { listCards, countCards, readCard, search, searchAll, graph, graphAll, overview, exportCards, deleteCard, writeCard, parseCard, stats, optimizeCandidates, optimizeApply, addFeedback, dailyCounts, mergeCards, ensureVault, auditQueue, recycleList, purgeExpired, setCardStatus, setCardKind, restoreCard, mainStoreBodies } from './vault.js'
20
+ import { listCards, countCards, readCard, search, searchAll, graph, graphAll, graphLevel, LEVEL_ERR_PATH, LEVEL_ERR_STALE, overview, exportCards, deleteCard, writeCard, parseCard, stats, optimizeCandidates, optimizeApply, addFeedback, dailyCounts, mergeCards, ensureVault, auditQueue, recycleList, purgeExpired, setCardStatus, setCardKind, restoreCard, mainStoreBodies } from './vault.js'
21
21
  import { compressExcerpt, guessRawKind, DEFAULT_CAPTURE_MAX_TOKENS } from './capture.js'
22
22
  import { buildDiagnostics } from './feedback.js'
23
23
  import { getSetupStatus, runSetup, mcpAgentAction } from './setup.js'
@@ -606,6 +606,25 @@ export function createApi(deps = {}) {
606
606
  json(res, 200, { ok: true, diagnostics: text, repo: 'EternalNight996/memory-eternal', version: (dshD && dshD.version) || envD.MEMORY_ETERNAL_VERSION || '' })
607
607
  return
608
608
  }
609
+ case '/graph/level': {
610
+ // 星球分层视图:一次只返回「一层」(根层 kind 折叠 / 卡片层 / 语义簇层)。
611
+ // 10k 规模下客户端绝不再拉全量图 —— 每层图元 ≤1000、payload ≤1MB(见 lib/vault.js 守卫)。
612
+ await ensureVault(vaultRoot)
613
+ const pathStr = query.get('path') || ''
614
+ const allRoots = query.get('all') === '1'
615
+ try {
616
+ const out = await graphLevel(vaultRoot, {
617
+ path: pathStr,
618
+ roots: allRoots ? vaultRoots() : null,
619
+ })
620
+ return json(res, 200, out)
621
+ } catch (e) {
622
+ // 分类失败:路径写错/语义簇过期是「客户端可纠正」的 400;其他未知异常一律 500,
623
+ // 内部细节只进服务端日志(不把 SQL/堆栈原文抛给浏览器)。
624
+ const { status, body } = levelErrorResponse(e, 'path=' + pathStr)
625
+ return json(res, status, body)
626
+ }
627
+ }
609
628
  case '/graph': {
610
629
  await ensureVault(vaultRoot)
611
630
  const all = query.get('all') === '1'
@@ -1315,6 +1334,29 @@ export function createApi(deps = {}) {
1315
1334
  }
1316
1335
  }
1317
1336
 
1337
+ /**
1338
+ * 分层接口的错误 → HTTP 响应(纯函数,便于单测)。
1339
+ * LEVEL_PATH / LEVEL_STALE:客户端可以自己纠正(路径写错 / 卡片增删让簇 id 过期)→ 400 + 原文案;
1340
+ * 其他未知异常:500 + 通用文案,**内部细节只写服务端日志**,不回给浏览器。
1341
+ * 无论哪种,客户端都会显示「显式报错 + 保留当前层 + 重试」。
1342
+ */
1343
+ export function levelErrorResponse(err, context = '') {
1344
+ const code = err && err.code
1345
+ if (code === LEVEL_ERR_PATH || code === LEVEL_ERR_STALE) {
1346
+ return {
1347
+ status: 400,
1348
+ body: { ok: false, code, error: String((err && err.message) || err) },
1349
+ }
1350
+ }
1351
+ try {
1352
+ console.error('[memory-eternal] /graph/level 内部错误' + (context ? '(' + context + ')' : '') + ':', err)
1353
+ } catch { /* console 不可用时彻底静默(日志失败不能反过来影响响应) */ }
1354
+ return {
1355
+ status: 500,
1356
+ body: { ok: false, code: 'LEVEL_FAILED', error: '知识图谱层级暂时不可用,请稍后重试' },
1357
+ }
1358
+ }
1359
+
1318
1360
  export function json(res, status, body) {
1319
1361
  const payload = JSON.stringify(body)
1320
1362
  const headers = {