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-memory-feeder

v0.1.1

Published

DSH plugin that extracts long-term facts from completed turns into an append-only Markdown memory inbox.

Readme

dsh-memory-feeder

DSH 的记忆写回插件。每个完成的主会话轮次结束后,它把用户与助手的文本同步写入本地队列,再用该会话的模型抽取长期事实,追加到 Markdown 记忆库的候选区,等你核实后再合并。

v1 只写 agents/dsh/inbox.md,不会直接修改 shared/、projects/ 或 MEMORY.md。

行为

  • 只处理顶层会话(跳过 origin: subagent),只在 turn/end 且原因为 completed 时入队。
  • 入队是同步追加 .pending.jsonl,所以 dsh headless 一次性运行退出前也不会丢。
  • 抽取在插件启动后约 1.5 秒、新轮次入队后约 5 秒、失败后 15 秒重试。
  • 每个完成轮次向 agents/dsh/inbox.md 追加一块,带来源会话、工作目录、模型、置信度和原始对话摘录;轮次内抽到的事实按 scope 合并成块。
  • 已写过的候选记在 .seen.json,重复运行不会重复写;同一队列条目最多尝试 3 次。
  • 抽取以用户亲口说的事实、计划、目标、偏好为主;助手的建议不会被改写成用户计划,助手长解释只在有可复用结论时提取。
  • 入队前与写盘前清洗 sk-*、GitHub token、Bearer、私钥和 key: value 形式的凭据。
  • 抽取器不读正式记忆,可能提出与已有条目重复的候选;合并时以正式条目为准。

安装

方式 A:从 GitHub 安装(web)

dsh plugin --profile web add github:Ryan-G-Rolling/dsh-memory-feeder

装完重启 DSH web,并硬刷新页面。

默认记忆库是 ~/.dsh/memory(Windows 为 C:\Users\<你>\.dsh\memory),插件会自动创建候选区。要指向已有记忆库,在启动 DSH 的同一个 shell 里设置环境变量:

# Windows PowerShell
$env:DSH_MEMORY_ROOT = 'D:\Projects\memory'
# bash / zsh
export DSH_MEMORY_ROOT="$HOME/memory"

DSH_MEMORY_ROOT 只在 patch 里没有显式 memoryRoot 时生效。headless 用的 profile 不一定是 web;桌面版宿主只读自己的 profile 层,这两种情况按方式 B 手动接。

方式 B:手动 patch(桌面版 / 自定义路径)

DSH 分两层:

  • ~/.dsh/cordis.patch.yml:给 web 和 headless 用。
  • ~/.dsh/profiles/desktop/cordis.patch.yml:给桌面版用。桌面宿主只读 profile 层,不读 home 层,所以桌面版必须单独 insert;桌面 profile 由 Electron 独占,不能用 dsh plugin --profile desktop 安装。

把下面的 insert 块追加到对应 patch 文件。name 用插件 index.js 的绝对路径(见 cordis.patch.example.yml):

- insert:
    - id: dsh-memory-feeder
      name: '<PLUGIN_DIR>/index.js'
      config:
        memoryRoot: '<MEMORY_ROOT>'
        inboxSubdir: agents/dsh
        debounceMs: 5000
        maxItems: 5
        minConfidence: 0.6

两处可以共用同一个队列和 .seen.json,不会重复写同一条记忆。改完桌面 patch 后重启桌面版。

同一个层不要装两次,否则同一轮会入队两次。

配置项

| 键 | 默认值 | 说明 | | --- | --- | --- | | memoryRoot | DSH_MEMORY_ROOT 或 ~/.dsh/memory | 记忆库根目录 | | inboxSubdir | agents/dsh | 候选区相对路径,写入其中的 inbox.md | | debounceMs | 5000 | 新轮次入队后延迟多久抽取 | | startupDelayMs | 1500 | 启动后处理遗留队列的延迟 | | retryDelayMs | 15000 | 失败或队列未清空时的重试间隔 | | maxPerRun | 5 | 每次最多处理几条队列记录 | | maxQueueAttempts | 3 | 单条记录最多尝试次数 | | maxItems | 5 | 每轮最多保留几条候选 | | minConfidence | 0.6 | 低于该置信度的提取结果丢弃 | | minTurnChars | 30 | 用户加助手文本低于该长度不入队 | | maxTranscriptChars | 16000 | 入队文本上限,用户约占 40% | | maxSeenEntries | 2000 | 去重哈希保留条数 | | provider / model | 空 | 留空时用该会话 request/header 的路由 | | queuePath / seenPath / logPath | 插件目录 | 队列、去重表和日志位置 |

路径都建议用绝对路径。Windows 下 YAML 单引号里的反斜杠不需要转义,写成正斜杠也可以。

本地测试

复制 test.patch.example.yml,替换其中的 <PLUGIN_DIR> 与 <MEMORY_ROOT>,然后:

dsh headless --patch "<PLUGIN_DIR>/test.patch.example.yml" "随便完成一轮对话"

测试 patch 把候选区指到 agents/dsh/_feeder_test。headless 通常在入队后立刻退出,异步抽取可能来不及跑;再执行一次同样的命令,启动时就会处理上一条队列记录。

跑完清理:

rm -rf "<MEMORY_ROOT>/agents/dsh/_feeder_test"
rm -f "<PLUGIN_DIR>/.pending.test.jsonl" "<PLUGIN_DIR>/.seen.test.json" "<PLUGIN_DIR>/.feeder.test.log"

日志与排错

  • 日志同时写 stderr 和插件目录的 .feeder.log,前缀 [dsh-memory-feeder];stderr 不污染 headless 的 stdout。
  • 启动日志 ready (memoryRoot=...) 会打印实际使用的路径;路径不对时改 memoryRoot 或 DSH_MEMORY_ROOT。
  • 入队日志是 queued turn ...;抽取成功是 extracted N item(s) 和 appended ...。
  • 卡在 skip turn: no provider/model 时,在配置里显式指定 provider 和 model。

安全边界

  • 队列和日志里会有对话原文,按敏感文件对待,不要提交到公开仓库。仓库自带的 .gitignore 已忽略这些文件。
  • 不写 API key、token、密码、登录态;敏感信息只放环境变量。
  • 写入前会清洗常见凭据格式,但清洗是兜底,不是保证。不要把密钥粘进对话。
  • 记忆库如果同步到远端,inbox.md 里的候选和对话摘录也会一起同步,按需选择私有备份。

限制

  • 只处理顶层会话;子代理的对话不入队。
  • 依赖 DSH 的 llm 服务和会话 request/header 里的 provider/model。
  • 候选不会自动合并、去重到正式条目;需要人或其他 agent 定期清理。
  • 默认只写 ~/.dsh/memory;要接入已有记忆库,必须显式配置路径。
  • 在 Windows 的 DSH 桌面版、web 和 headless 上验证过;其他平台未实测。

License

MIT