中文EN

dsh-claude-memory

memory已测通过npmMIT

只读桥接 Claude Code 已有项目记忆到 DSH:按 git 仓库根解析、注入前脱敏、按需检索工具,零依赖。

下载量 / Downloads
1,023
依赖体积 / node_modules
0.07 MB
测试时间 / Tested
2026-11-06
DSH 版本 / Version
0.2.2-rc.1

安装

dsh plugin --profile web add dsh-claude-memory

沙箱测试结果

阶段结果
1 安装✓
2 列装✓
3 挂载✓
4 启动—

四阶段在隔离沙箱里跑:安装(有网)→ 列装 → 挂载 → 启动(后三步断网)。

README

dsh-claude-memory

一个只读的 DeepSeek Harness 插件,把

Claude Code 已有的项目记忆接进 DSH —— 让 Claude Code 额度耗尽后,任务能在 DSH 里接着做。

English: [README.md](README.md)

~/.claude/CLAUDE.md          ─┐
  @import 已内联              │
~/.claude/projects/<key>/     ├─► 收敛 ─► 脱敏 ─► 字节预算 ─► DSH system prompt
  memory/MEMORY.md  (索引)    │                              + claude_memory 工具
  memory/<topic>.md (正文)   ─┘

它做什么

  • 把解析到的项目 MEMORY.md 索引注入 system prompt,同时注入用户级

~/.claude/CLAUDE.md(其 @path import 会被内联展开)。

  • 注册一个 claude_memory 工具,让模型按需打开某条记忆、列项目、或跨主题搜索 ——

完整正文默认不进 prompt。

  • 在内容到达模型服务商之前就把凭据形状的文本打码。
  • 绝不写入、移动或删除 Claude home 下的任何文件。

安装

dsh plugin --profile web add dsh-claude-memory

需要重启 profile —— dsh.profile.bundles 里的新 bundle 是启动时读取的,不热加载。

包内声明了 engines.dsh 为 >=0.1.2-rc.1 <0.3.0:DSH 0.2 的运行时版本不匹配时会拒绝加载,

除非显式授予版本豁免。已在 0.1.2-rc.1 与 0.2.1-rc.4 上验证。

从本地目录安装:

dsh plugin --profile web add /path/to/dsh-claude-memory

验证配置树:

dsh --profile web --dump-config | grep -A 10 claude-memory

配置

默认值在包内的 cordis.patch.yml;可在 profile 的 patch 层或 --patch 覆盖层里改。

字段 · 默认 · 含义

claudeHome · ~/.claude · Claude Code home,所有读取都收敛在这个根下

cwd · process.cwd() · 仅兜底。会话的 agent.session.header.cwd 永远优先

includeDescendants · true · 是否列出有记忆的兄弟/子项目

descendantLimit · 12 · 最多列出几个其他项目

maxIndexBytes · 24000 · 注入记忆块的字节预算

maxGlobalBytes · 6000 · CLAUDE.md 加内联 import 的字节预算

enableMemory · true · 是否注入记忆块

enableGlobalInstructions · true · 是否注入用户级指令

enableTool · true · 是否注册 claude_memory 工具

redactMode · on · on 打码、report 只统计、off 关闭

refreshMs · 20000 · prompt 组装时若缓存超过此值就重读

实际进入模型的内容

两个 system prompt 段落(order 10 / 11,紧随部署 persona 之后):

1. claude-memory:global —— ~/.claude/CLAUDE.md,@path 已内联。DSH 自带的指令

加载器不解析 import;用户级文件它读的是 $DSH_HOME/AGENTS.md 而不是

~/.claude/CLAUDE.md(0.2 也会读项目级 CLAUDE.md,那是另一个文件),

所以这里是用户级 Claude Code 记忆唯一的通路。

2. claude-memory:memory —— 解析到的项目 MEMORY.md 索引,外加按新鲜度排序的其他

项目列表。

完整正文只通过工具按需返回,一次一个文件,单次 20 KB 上限。

项目解析

决定"该读哪份记忆"的是会话的工作目录,不是 dsh 服务启动的目录 —— 服务从某个

checkout 启动、会话在另一个目录跑的时候,两者必然不同。

解析顺序:

1. exact —— <home>/projects/<cwd 编码>/memory/ 存在;

2. git-root —— 外层 git 仓库根对应的键有记忆;

3. freshest —— 都没有时,在祖先与子项目里选索引更新时间最新的(并明确告知模型这是猜测)。

规则 2 的存在是因为 Claude Code 把记忆归档在 git 仓库根下,而不是原始工作目录 ——

见下方案例研究。规则 2、3 下其他项目按新鲜度倒序列出,最新那个一次工具调用就能取。

agent.session.header.cwd 与第一方 dsh-agent-instructions 读的是同一个来源。段落先以

全局注册作兜底,再在 agent/created 时按 agent 作用域 shadow;工具则按调用方

exec.agent 逐次解析,因此子 agent 或在别处启动的会话看到的是自己的项目。

claude_memory 工具

action · 参数 · 返回

projects · limit? · 所有有记忆的项目、条数、当前标记

index · project? · 某个项目的 MEMORY.md

read · project?、file? · 某个主题文件;不给 file 则列出主题

search · query、project?、limit? · 匹配行,格式 file:line: text

project 可传完整键、键后缀或唯一子串。所有返回都过同一个脱敏器并受 20 KB 上限约束。

安全模型

威胁模型很具体:为 A 厂商模型写的笔记,即将发给 B 厂商。

  • 只读:没有任何代码路径写入、移动或删除 claudeHome 下的文件。
  • 收敛:每个路径都经 realpath 解析且必须落在 claudeHome 内;指向外部的符号链接

会被拒绝;含路径分隔符的主题名会被拒绝。

  • 注入前脱敏:13 条规则覆盖厂商 key 形状、Bearer token、PEM 块、JWT、带熵阈值的

password/token/secret 赋值、内联凭据的连接串、长 hex 串。误报代价是一行被打码,

漏报代价是把凭据发出去 —— 所以策略偏保守。

  • 不可信框定:注入块明确告诉模型这些是背景笔记而非指令,记忆文本不能操纵 agent。
  • 零依赖:只 import node:*,信任链里没有第三方代码,且在 node_modules 为空

(不含 harness 包)的 profile 里也能解析。

  • prompt 文本是字符串:provider 读同步刷新的缓存,永不返回 Promise。

脱敏是基于模式的,不是分类器,抓不住"不像凭据的凭据"。用 redactMode: report 审计

"哪些会被打码",用 enableMemory: false 作为总开关。

测试

npm test              # smoke + plugin + schema + live
npm run test:unit     # 仅 fixture,不需要真实 ~/.claude

文件 · 覆盖范围

test/smoke.mjs · 路径、脱敏、存储、预算、工具 —— 全部跑在系统临时目录里的合成 fixture 上

test/plugin.mjs · 假 Cordis ctx 下的 loader 契约,含 agent 作用域 shadow

test/schema.mjs · 手写工具 schema 过真实 @deepseek-ai/dsh-tools 校验器;无 DSH 时跳过

test/live.mjs · 可选:对真实 ~/.claude 检查"没有凭据形状文本进入 prompt";无 store 时跳过

共 82 项断言,无网络、无模型调用。CI 会固定 @deepseek-ai/dsh-tools 版本并真实执行

test/schema.mjs,运行时不变量一变就直接失败,而不是跳过。

案例研究:两件容易做错的事

两个发现都来自阅读生态里已有的插件与一份真实记忆库。对任何"桥接另一个 agent 文件"的

DSH 插件都适用。

1. prompt provider 是同步的 —— async provider 会渲染成 Promise

dsh-system-prompt 解析段落与上下文文本时不做 await(lib/index.js:330,337),随后

插值器调用 text.indexOf(lib/index.js:152)。所以声明成 async () => string 的 provider

返回的是 Promise 而不是字符串。

生态里最知名的 Claude Code 桥接插件

(YYTbit/dsh-plugin-claude-bridge,

src/index.ts:75,92,107)注册的正是 async provider。能加载不等于能渲染 —— 插件挂载

正常,组装时才失败。本插件用同步刷新的缓存,返回普通字符串。

2. Claude Code 把记忆归档在 git 仓库根下

记忆位于 ~/.claude/projects/<项目路径编码>/memory/,路径编码是项目目录把 ASCII 字母和数字以外的每个字符换成 -(/home/me/.config 编码为

-home-me--config);超过 200 字符的编码会截到 200 并追加 -<完整路径哈希>,保证深路径仍可区分。同一仓库的所有 linked worktree 共用主 worktree 的键。

问题在于哪个目录算项目。在作者机器上,对一个位于更大仓库内、自身没有 .git 的文档

hub 实测:

观察项 · 值

该 hub 会话记录的 cwd · hub 目录

它写入 memory/ 的 Write/Edit 调用 · 12 次,全部落在外层仓库的键下

该会话引用外层仓库 memory/MEMORY.md 的次数 · 235

引用它自己目录 memory/ 路径的次数 · 0

hub / 父目录 / 祖父目录是否有 .git · 无 / 无 / 有

会话记录按 cwd 编码存放,记忆按 git 仓库根存放。按 process.cwd() 解析、或只认

精确 cwd 的桥接插件,在任何 hub 目录下都会静默读错项目的笔记。另外记忆目录是按需创建

的:那台机器 50 个项目目录里只有 20 个有非空索引,21 个是空 memory/ —— 所以"没有记忆

目录"很正常,不代表那个目录没被用过。

已知边界

  • 不读会话流水。它读记忆文件,不读 transcript。"我一小时前在做什么"需要 *.jsonl,

不在本插件范围内。

  • 不强制 Claude Code 自己的索引上限。Claude Code 只加载 MEMORY.md 的前 200 行或

25 KB,超限的条目在那边会被静默丢弃;本插件按 maxIndexBytes 注入,不对该上限告警。

  • 项目键有损。- 既是分隔符也是目录名的合法字符,所以展示路径靠遍历文件系统反查,

失败时退回键尾。

  • 没有文件监听。新鲜度靠 prompt 组装时检查 refreshMs,所以一轮对话中途的改动会在

下一次组装生效。

  • 只注入解析到的那一个项目的索引。其他项目需要工具调用。

许可证

MIT

以上内容来自 npm 上的 README,我们只做格式化,不改内容。

版本

npm 上共发布:2,最后更新 2026-10-29

链接

GitHub · Homepage · npm

同类插件