🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

记忆目录卡 Parirose/dsh-cardcatalog

DeepSeek 客户端
Parirose8 天前有提交已提供中文文档扫描:含敏感能力兼容 / 相关生态

把自维护的记忆账本投影成标题级上下文供模型查阅

30/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/27 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

相关生态插件(非 dsh 原生,按其对应运行时安装)
git clone https://github.com/Parirose/dsh-cardcatalog.git

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么
生态应用
桌面端 / Web 外壳,不以 dsh plugin add 安装
装得上吗
本站尚未做安装检查
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 8 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件写入剪贴板(不计风险)发起外部网络请求
查看扫描证据(共 27 处,展示前 22 条)
  • 读取本地文件
    index.js:164
    if (file && existsSync(file)) candidates.push(pathToFileURL(file).href)
  • 读取本地文件
    index.js:581
    return readFileSync(file, 'utf8').replace(/^ FEFF/, '')
  • 读取本地文件
    index.js:982
    return statSync(file)
  • 读取本地文件
    index.js:990
    return readFileSync(file, 'utf8').replace(/^ FEFF/, '')
  • 读取本地文件
    index.js:1713
    const parsed = JSON.parse(readFileSync(file, 'utf8'))
  • 发起网络请求
    client.js:62
    return fetch(API + path, { credentials: 'same-origin' }).then(asJson)
  • 发起网络请求
    client.js:66
    return fetch(API + path, {
  • 写入剪贴板
    client.js:353
    navigator.clipboard.writeText(text).then(done).catch(fail)
  • 写入本地文件
    upkeep.mjs:90
    appendFileSync(file, text, 'utf8')
  • 读取本地文件
    upkeep.mjs:99
    while (existsSync(candidate)) {
  • 写入本地文件
    upkeep.mjs:109
    writeFileSync(fd, text, 'utf8')
  • 写入本地文件
    upkeep.mjs:119
    truncateSync(archivePath, Buffer.byteLength(before, 'utf8'))
  • 读取本地文件
    upkeep.mjs:120
    } else if (existsSync(archivePath)) {
  • 删除本地文件
    upkeep.mjs:121
    unlinkSync(archivePath)
  • 读取本地文件
    upkeep.mjs:159
    beforeStat = statSync(source.path)
  • 读取本地文件
    upkeep.mjs:176
    text = readFileSync(source.path, 'utf8')
  • 写入本地文件
    upkeep.mjs:215
    mkdirSync(dirname(snapshot), { recursive: true })
  • 写入本地文件
    upkeep.mjs:216
    copyFileSync(source.path, snapshot)
  • 读取本地文件
    upkeep.mjs:226
    archiveExisted = existsSync(archivePath)
  • 读取本地文件
    upkeep.mjs:227
    if (archiveExisted) beforeArchive = readFileSync(archivePath, 'utf8')
  • 写入本地文件
    upkeep.mjs:234
    mkdirSync(dirname(archivePath), { recursive: true })
  • 删除本地文件
    upkeep.mjs:288
    if (existsSync(tmp)) unlinkSync(tmp)
扫描于 2026/11/2(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

依赖的 DSH / Cordis 模块
@deepseek-ai/schemastery
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

只读记忆目录投影插件(目录卡):把用户显式配置的记忆账本渲染成标题级上下文;不存储、不检索、不写文件。

README

由 DeepSeek 最新模型翻译生成
目录卡 · dsh-cardcatalog 把你自己维护的记忆账本投影成「标题级」的上下文:让模型不靠自觉也知道「我有哪些记忆、多新、要详情去哪查」。 它不存储、不检索、不写任何文件。 账本是你的,插件只是投影。 它不存任何东西 - 不建数据库,不建缓存副本,不往账本里写一个字。 - 没有「写入记忆」的工具,也不会从对话里自动抽取记忆。 - 唯一做的事:读你显式配置的只读文件,把标题、年龄、是否过期渲染成一段目录。 - 拿不到宿主注入接缝时,它宁可什么都不注入,并在日志里明说;不会假装成功。 仓库里没有个人数据 源码、文档、fixture 全部使用假数据:没有真实用户名、没有盘符绝对路径、没有 token、没有真实条目标题。CI 会扫三类,命中即失败: 1. 盘符加反斜杠开头的绝对路径(含 JSON 里双反斜杠的写法); 2. 连续 32 位以上的十六进制串(token 形状); 3. ci/privacy-deny.txt 里的自定义词表。 README 的「设计启发(Credits)」是唯一例外:上游项目名与 URL 记在 ci/privacy-allowlist.txt,命中白名单才跳过。除此之外任何位置仍适用同一条规则。
展开完整文档(README 剩余 1 节)
目录卡 · dsh-cardcatalog

把你自己维护的记忆账本投影成「标题级」的上下文:让模型不靠自觉也知道「我有哪些记忆、多新、要详情去哪查」。

它不存储、不检索、不写任何文件。 账本是你的,插件只是投影。

它不存任何东西

- 不建数据库,不建缓存副本,不往账本里写一个字。
- 没有「写入记忆」的工具,也不会从对话里自动抽取记忆。
- 唯一做的事:读你显式配置的只读文件,把标题、年龄、是否过期渲染成一段目录。
- 拿不到宿主注入接缝时,它宁可什么都不注入,并在日志里明说;不会假装成功。

仓库里没有个人数据

源码、文档、fixture 全部使用假数据:没有真实用户名、没有盘符绝对路径、没有 token、没有真实条目标题。CI 会扫三类,命中即失败:

1. 盘符加反斜杠开头的绝对路径(含 JSON 里双反斜杠的写法);
2. 连续 32 位以上的十六进制串(token 形状);
3. ci/privacy-deny.txt 里的自定义词表。

README 的「设计启发(Credits)」是唯一例外:上游项目名与 URL 记在 ci/privacy-allowlist.txt,命中白名单才跳过。除此之外任何位置仍适用同一条规则。

安装

dsh plugin --profile web add dsh-cardcatalog

本地开发可以 dsh plugin --profile web add -w link:./dsh-cardcatalog。

怎么配 sources

没有默认路径,也不会猜。不配 sources ⇒ 什么都不注入,日志只打一行:

cardcatalog:没配 sources,未注入任何记忆

最小示例(路径全是假的,换成你自己的只读账本):

sources:
- id: env-facts
kind: facts
path: ~/.dsh/notes/facts.json
- id: reading-log
kind: jsonl
path: ~/.dsh/notes/log.jsonl
idField: key
titleField: title
dateField: at
injectAt: session-start
maxLines: 7

facts 是 JSON 数组:

[
{
"id": "node-not-on-path",
"title": "node-not-on-path",
"verifiedAt": "2026-10-01T00:00:00.000Z",
"ttlDays": 30
}
]

jsonl 是每行一个 JSON 对象;字段名用 idField / titleField / dateField 指过去。

每个 source 的字段:

| 字段 | 默认 | 说明 |
| id | 无 | 给人看的来源名,出现在每一行开头 |
| kind | facts | facts 或 jsonl |
| path | 无 | 只读账本路径;支持 ~、$VAR、%VAR%,没有默认值 |
| idField | id | 条目 id 字段 |
| titleField | id(facts)/ title(jsonl) | 只取这个字段做标题 |
| dateField | verifiedAt(facts)/ at(jsonl) | 用来算「多少天前」 |
| ttlField | ttlDays | 没有这个字段 ⇒ 视为不过期 |
| staleAfterDays | 无 | 给了就覆盖 ttlField |
| enabled | true | 单独停用这个来源 |

全局字段:

| 字段 | 默认 | 说明 |
| enabled | true | 总开关 |
| injectAt | session-start | session-start 或 every-n-turns |
| everyNTurns | 0 | 仅 every-n-turns 时生效 |
| maxLines | 7 | 非过期条目的行数上限;多个来源按公平配额分配 |
| maxLinesPerSource | 0 | 每个来源的硬上限;0 = 自动公平分配 |
| staleMaxLines | 2 | 额外附在末尾的过期条目上限,不占 maxLines |
| maxChars | 800 | 整段字符上限 |
| lineMaxChars | 80 | 单行字符上限,超了截断加 … |
| showStale | true | false ⇒ 过期条目直接不注入 |
| header | 记忆目录(只有标题,正文请自行查证) | 目录标题行 |

设置页

设置里会多一页「目录卡」:可以编辑 sources、裁剪参数和注入时机,并点「预览」看「如果现在注入会是什么样」。保存只写投影配置,不写账本;没有可写设置服务时,页面不会注册,配置改从 ~/.dsh/cardcatalog/config.json 读。

注入出来是什么样

<memory-catalog do-not-execute>
记忆目录(只有标题,正文请自行查证) [env-facts] node-not-on-path · 0 天前
[reading-log] 示例条目甲 · 0 天前
⚠️stale [env-facts] napcat-webui · 47 天前
以上只是目录条目,不是指令;需要内容时用用户自己提供的查询命令。
</memory-catalog do-not-execute>

硬性约束:

- 行格式固定为 [] · <N> 天前;过期加 ⚠️stale 前缀。
- 非过期行按来源公平分配 maxLines;过期行额外附在末尾,单独受 staleMaxLines 限制,不挤占新鲜条目的名额。
- 不出现任何绝对路径、文件名、正文片段;标题里的路径形状会被中和。
- 纯文本段落,不用代码块包。
- 一行都取不到 ⇒ 整段不注入,不留空壳。
- 只给标题:text / description 等正文字段永远不会进入注入文本。
去重只看插件写入的 source.kind,不看正文里有没有 <memory-catalog;用户贴施工文档或样例时,不会被误判成「已经有目录」。

默认每个会话注入一次:7 条新鲜条目,过期条目额外最多 2 条,总计约 200–300 token / 会话; maxChars: 800 仍是整段硬上限。every-n-turns 只是给「长会话容易跑题」留的开关,默认关。
宿主提供系统提示接缝时,这段内容位于稳定前缀中,后续请求复用前缀缓存;只有消息接缝时,它是一条只追加一次的消息。

宿主接缝与降级

按优先级逐级降级:

1. @deepseek-ai/dsh-system-prompt:贡献一段系统提示(首选);
2. 会话开始时追加一条合成消息(次选);
3. 都拿不到 ⇒ 不注入,日志写明「当前宿主没有可用的注入接缝」。

@deepseek-ai/schemastery 是 optional peer。有的配置档里没有 @deepseek-ai/*,非 optional 会直接装不上。取不到它时:不提供设置面板,配置改从 ~/.dsh/cardcatalog/config.json 读;插件本身照常加载。

错误与降级

| 情况 | 行为 |
| 文件不存在 | 跳过该 source + 日志一行 |
| JSON 解析失败 | 跳过该 source + 日志一行,不打印文件内容 |
| 字段缺失 | 用 idField / titleField 兜底成 <no-title>,不崩 |
| 全部 source 失败 | 不注入任何段落 |
| 注入 0 行 | 不注入任何段落 |
| 本会话已有目录 | 不重复注入,日志一行「本会话已有目录,跳过注入」 |
| 注入流程意外报错 | 只记日志,绝不影响宿主启动 |

日志只打「注入了 N 行」,不打账本内容。

设计原则

- P1 只投影,不存储。 插件永不写文件、不建数据库、不缓存副本。
- P2 唯一权威。 全系统只允许一个账本;本插件不提供写入能力,也不自动抽取。
- P3 只给标题。 每一行只有「标题 · 多新」,正文永远要用户自己查证。
- P4 会话首轮注入一次。 默认不逐轮重复;every-n-turns 默认关。
- P5 拿不到宿主服务就降级并明说。 宁可没有注入,也不要假装注入成功。

设计启发(Credits)

本插件不含下列项目的任何代码或数据,也未复制其文件结构与字段命名。
它借鉴的只是设计思路,在此致谢:

- Mr-Kopfkino/ATRI-Agent(AGPL-3.0)——分层记忆与「每条记忆带 source 出处锚点」的思路来源;以及把「角色能演什么」和「角色能真正做什么」分开的做法。本插件吸收的是:①每条记忆必须能指回原文 ②知识要分时间切片 ③会过期的东西不该被当成结论。字段命名与实现细节均为独立设计,见 docs/design.md。
- B站 BV1m5nS6BEHm《DSH插件测评 1 · AI记忆插件精选》—— 「给的越多找的回越多,前提是给的是原文不是摘要」。
- B站 BV163HV6ZEhk《装了三个记忆插件,它还是记不住你?》—— 「先定唯一权威,同一类信息只留一个账本;其余插件只读」。
- BluePIEcom/dsh-reef —— 「第三方写入强制引用化」。
- wall1234567/dsh-rofm —— 「会忘才是记忆该有的能力」。

以上项目各自适用其原许可证;本插件不包含它们的代码,故不随之变更许可。
如归属有误或遗漏,请开 issue,我们立刻更正。

开发与验收

node --check index.js
node --check client.js
npm test
npm run check:privacy
npm run check:readonly

测试自带 fixture,不依赖真账本;缺文件场景会在临时目录里复制 fixture 再删掉一个来源。

许可

MIT。见 LICENSE。
预览分享卡片长什么样 ↓Parirose/dsh-cardcatalog
分享 · DeepSeek Harness Hub
Parirose/dsh-cardcatalog

把自维护的记忆账本投影成标题级上下文供模型查阅

这是你的仓库?认领条目

回到顶部