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-mem

v0.1.1

Published

Cross-session long-term memory for DeepSeek Harness (dsh): durable JSON-file memory store with memory_save / memory_recall / memory_forget / memory_list model tools, installable as a dsh bundle.

Downloads

72

Readme

dsh-mem — 跨会话记忆能力接缝

一个面向 DeepSeek Harness(dsh)的树外 bundle 插件,实现完整的能力接缝(capability seam)三件套:Service Definition + Service Provider + Consumer(模型工具)。它给 Agent 提供跨会话的长期记忆:memory_save / memory_recall / memory_forget / memory_list 四个工具,把事实、偏好、决策存入 $DSH_HOME/memory/memory.json,任何会话都能检索。

接缝三件套

| 角色 | 模块 | 挂载行 | 说明 | |---|---|---|---| | Service Definition | src/memory.ts(dsh-mem/memory) | —(不是插件行) | 抽象类 MemoryService,声明 ctx.memory 契约与类型;直接加载会报错 | | Service Provider | src/provider.ts(dsh-mem/provider) | memory | MemoryFile extends MemoryService,JSON 文件持久化,原子写入 | | Consumer | src/tool.ts(dsh-mem/tool) | tool-memory | 函数插件,在 ctx.tools 上注册四个工具;每次调用经 ctx.get('memory') 解析服务 |

参考 dsh 仓库里的同类结构:ctx.jobs(Definition 在 packages/jobs/jobs,Provider 在 jobs-local,Consumer 在 tool-jobs)。

目录结构

dsh-memory/
├── package.json          # dsh.bundle.patch → ./cordis.patch.yml
├── cordis.patch.yml      # bundle 层:插入 memory + tool-memory 两行
├── tsconfig.json         # 独立构建配置(npm 依赖提供类型)
├── tsconfig.check.json   # 开发用:扩展仓库 tsconfig.base,用仓库源码做类型检查
├── README.md
└── src/
    ├── memory.ts         # Service Definition(默认导出服务类)
    ├── provider.ts       # Provider(默认导出服务类 + static Config)
    └── tool.ts           # Consumer(仅命名导出,name/inject/Config/apply)

构建

npm install      # 拉取依赖(编译与运行时类型都来自 npm)
npm run build    # tsc 产出 lib/ (prepare 脚本同款,git 安装时自动执行)

在 dsh 仓库 checkout 旁开发时,本目录的 node_modules/@deepseek-ai/* 已用 junction 链接到仓库包(cordisschemasterydsh-toolsdsh-branddsh-atomic-writecordis-plugin-include,node_modules/js-yaml 同理),因此可以不 npm install 直接做本地类型检查:

pnpm exec tsc -p dsh-memory/tsconfig.check.json   # 类型检查(不产出)
pnpm exec tsc -p dsh-memory/tsconfig.json         # 产出 lib/

测试脚本(需先构建 lib):

node dsh-memory/tests/patch-smoke.mjs     # patch 组合烟雾(空 base + web 风格 base)
node dsh-memory/tests/provider-smoke.mjs  # Provider 全流程烟雾(持久化/搜索/边界/损坏文件)

安装进 profile

dsh plugin --profile demo add ./dsh-memory   # 本地目录安装
dsh plugin --profile demo add dsh-mem        # 从 npm 安装(发布后)

首次使用会初始化 demo profile,dsh 把这个包追加进 dsh.profile.bundles(位于 @deepseek-ai/dsh-base 之后),pnpm 链接本目录并安装它声明的 @deepseek-ai/dsh-* 依赖。验证层与启动:

dsh --profile demo --dump-config   # 应看到 "# == dsh-mem" 层与 memory/tool-memory 行
dsh --profile demo                 # 启动;新会话即可使用 memory_* 工具

卸载:dsh plugin --profile demo remove dsh-mem。从 git 或 npm 安装、tarball 分发等打包细节见 dsh 官方教程打包与安装插件

记忆条目与存储

一条记忆是 5~6 个字段的不可变记录:

| 字段 | 来源 | 说明 | |---|---|---| | id | provider 自动 | m-<n>,重启续号不重复 | | content | 模型提供 | 记忆正文(自由文本,模型按描述写成完整句子/短段落) | | tags | 模型提供 | 关键词,检索用;空串丢弃 | | project | 模型提供 | 所属项目/工作区(如仓库名);缺失 = 全局记忆,适用于所有项目 | | createdAt / updatedAt | provider 自动打戳 | epoch 毫秒;时间由系统记录,模型不用传;工具输出里附带人类可读的 createdAtText(ISO 8601) |

存到 $DSH_HOME/memory/memory.json(默认 ~/.dsh/memory/),文件形如:

{
  "version": 1,
  "nextId": 3,
  "entries": [
    {
      "id": "m-1",
      "content": "Project X uses pnpm workspaces and rejects yarn.",
      "tags": ["project", "tooling"],
      "project": "project-x",
      "createdAt": 1753000000000,
      "updatedAt": 1753000000000
    }
  ]
}

设计说明

  • 为什么 Provider 自管 JSON 文件,而不是用 ctx.storage 接缝:dsh 的存储行(storage / storage-json / storage-domain)由 dsh-web-app bundle 挂载,dsh-base 不含它们;一个树外 bundle 若再插入同名行,在同时挂载 web-app 的 profile 里会产生重复行。自管一个 JSON 文档让本插件在任何 profile(web / headless / 自定义)上零依赖可用。想换成 ctx.storage.domain 后端时,只需另写一个继承 MemoryService 的 Provider,工具与契约完全不用动——这正是接缝的意义。
  • 耐久性:每次变更先写内存再 writeFileAtomic(临时文件 + 原子 rename,0o600/0o700),落盘成功才对外可见;所有操作(含读)走同一进程内队列,读永远不会看到未落盘的写。并发多个 dsh 进程共享同一个 root 不受支持。
  • 文档格式:{ version, nextId, entries },nextId 持久化保证跨重启 id 不重复;版本不符或文件损坏在加载时大声失败,绝不静默清空。
  • 模型工具契约:搜索是内容的大小写不敏感子串匹配 + 精确 tag 匹配,空查询返回最新;recall/list 可传 project 精确过滤(大小写不敏感,全局记忆不含 project 因此永远不匹配项目过滤);recall/list 的 limit 由部署配置 maxRecallLimit 钳制;内容超长、limit 非法、id 格式非法都在工具边界拒绝。保存时机与内容取舍由工具描述文案引导模型判断:项目相关事实必须带 project,全局事实(如用户偏好)不带;createdAt 由 provider 自动打戳,模型无法伪造。
  • 依赖声明:@deepseek-ai/cordis@^4.0.1@deepseek-ai/dsh-*@^0.1.0-rc.6 均已发布到 npm,dsh plugin add 会为 profile 安装它们。

扩展点

  • 换 Provider:新建 class MyMemory extends MemoryService,在 cordis.patch.yml 里把 memory 行的 name 指向它。
  • 加人类命令:在工具插件里注入 ctx.commands(base 已提供),注册 /memory 之类的斜杠命令。
  • 会话内注入:在 agent/pre-steptools/post-execute 监听器里调用 agent.inject(),把与当前任务相关的记忆主动塞进下一次请求。
  • 换存储位置:在 profile 的 cordis.patch.yml 里整行覆盖 memory 行的 config.root(注意 patch 是整行替换,要重述保留的键)。

已知限制

  • 单进程写模型:两个 dsh 进程共享一个 root 时没有跨进程锁。
  • 无编辑 API:updatedAt 目前恒等于 createdAt;覆盖旧事实请 forget 后重新 save
  • 无结构化 schema:内容就是文本;需要字段化记忆(如"用户: 姓名=张三")时,约定模型用固定文本格式存入。