npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

dsh-claude-memory

v0.1.0

Published

Read-only DeepSeek Harness plugin that surfaces Claude Code's project memory, redacted and byte-budgeted

Readme

dsh-claude-memory

一个只读的 DeepSeek Harness 插件,把 Claude Code 已有的项目记忆接进 DSH —— 让 Claude Code 额度耗尽后,任务能在 DSH 里接着做。

English: 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 是启动时读取的,不热加载。

从本地目录安装:

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, 所以这里是用户级 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 时跳过 |

共 76 项断言,无网络、无模型调用。

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

两个发现都来自阅读生态里已有的插件与一份真实记忆库。对任何"桥接另一个 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/,路径编码是项目目录把 / 换成 -。 问题在于哪个目录算项目。在作者机器上,对一个位于更大仓库内、自身没有 .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