dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
分层 Claude Code 式记忆:用户级+项目级双作用域(项目记忆随 git 团队共享),MEMORY.md 索引会话启动自动注入,上下文护栏,纯文件零依赖。
English | 中文版
Persistent memory for DeepSeek Harness — the Claude Code memory model: your agents remember across sessions, wake up with context, and never mix projects. Pure files, zero dependencies.
Your DSH agent meets you for the "first time" — every single session. With dsh-memory, it remembers.
Session 1 You: "Remember — this project uses pnpm, not npm."
Agent: saved via memory_save
Session 2 You: "Which package manager do we use?"
Agent: "pnpm — you told me yesterday." <- no re-asking, ever
No server, no account, no embedding provider. Just plain markdown files — delete the directory and that scope forgets everything.
Settings → Memory opens a full manager: every memory from both scopes in one searchable list, workspaces as an expandable tree (nested sub-project scopes discovered automatically), sub-folder grouping, and live guard gauges (index lines / KB / file count). Add, rewrite, tag, or delete any memory right in the panel — through the exact same guarded pipeline as the agent's own tool calls, so what you fix in the UI is precisely what the model sees next session.
Project memories carry sub-directory tags. A tag injects when the session's working directory sits inside it — or the moment the session touches it: one read/edit/write/grep/glob/bash/pwsh call into frontend/src activates [frontend] and [frontend/src] for the rest of the session. Activation is monotone and survives session resume — exactly like nested CLAUDE.md files, triggered by what you actually do, not just where you cd'd at launch.
Untouched areas are hinted, never silently hidden: +3 more tagged to areas you haven't touched — memory_search surfaces them.
Each session's prompt carries ITS workspace's memories, and memory_save lands in that same workspace. Multi-session web hosts get zero cross-workspace bleed.
Root-level memories always inject; area memories load on work/touch; a 25-entry injection cap plus hard limits — 200 lines / 25 KB index, 500 memories per scope — keep the prompt flat no matter how much you remember.
Atomic writes (a crash never leaves half a file) · secrets refused on every write path, panel included · cross-origin + method gate on the panel API · traversal-proof ids · $HOME, drive roots and tmp dirs can never become a project scope (Windows-aware guards).
Nothing to provision, nothing to break. Lean hosts degrade gracefully — every optional host service is read defensively, tools keep working without them.
Prerequisite: the DSH CLI — npm install -g @deepseek-ai/dsh. From a source checkout, prefix commands with pnpm.
1 · Install (one command)
dsh plugin --profile web add @fooxe/dsh-memory # DSH CLI installed
pnpm dsh plugin --profile web add @fooxe/dsh-memory # from a source checkout
--profile is required and goes before add — pick the profile you actually boot (web for the Web UI; see ~/.dsh/profiles/). Manual npm i -g @fooxe/dsh-memory + dsh web --patch ./overlay/dsh-memory.cordis.yml also works, but plugin add is the recommended path.
2 · Restart DSH — the step everyone misses
Tools register only at service startup. Stop the service (Ctrl+C), start it again, then open a new chat.
3 · Verify (30 seconds)
Say "Remember that I prefer pnpm over npm." → a memory_save call appears. Open a new session and ask "Which package manager do I prefer?" → answered from the injected index. ~/.dsh/memory/MEMORY.md now exists; inside a project, decisions land in <project-root>/.dsh/memory/ — commit it and the whole team shares it.
| Symptom | Fix |
|---|---|
dsh: command not found | Install the DSH CLI first — see Prerequisite |
required option '--profile <name>' | It goes before the subcommand: dsh plugin --profile web add ... |
pnpm ERR_P..._STORE: Unexpected store location | Your terminal pnpm differs from DSH's bundled one (11.7.0). Delete the profile dir (~/.dsh/profiles/web) and re-run plugin add — it rebuilds cleanly |
| Installed + restarted, still no memory tools | Check startup logs for warning: ... did not activate, and dsh --profile web --dump-config | grep fooxe to confirm the tree entry; file an issue with the log if it persists |
ERR_PNPM_IGNORED_BUILDS after install | Harmless here (zero native deps); pnpm approve-builds in the profile dir clears it |
plugin add installs an old version | Your default registry (a mirror) lags behind npmjs. Pin explicitly: npx pnpm@11.7.0 add @fooxe/dsh-memory@latest --registry=https://registry.npmjs.org, or add @fooxe:registry=https://registry.npmjs.org to ~/.npmrc |
| Tool | Purpose |
|---|---|
memory_save | Save a durable memory; scope defaults to project inside a detected project root, user elsewhere |
memory_search | Case-insensitive keyword search across both scopes (ids, titles, tags, content) |
memory_read | Read one full memory — Claude Code's project_memory_read field contract (content?, local_file?, size_bytes, updated_at, truncated) |
memory_list | Recent memories per scope, newest first |
Tool descriptions embed a save gate modeled on Claude Code / Codex — month-scale facts only, saved at conclusions (never mid-progress state); borderline cases ask the user; secrets never save.
Write rules (ported from Claude Code / Gemini CLI practice):
YYYY-MM-DD, so the model reasons fresh-vs-stale at injection timeSave when: a preference or correction is stated (corrections are the highest-value memories), a decision is made, a key number/ID appears, an error+fix closes. Never: secrets, transient state, anything directly readable from the repo, unconfirmed guesses.
Which scope — the one-line test: is this fact about the person or about this project?
User scope ~/.dsh/memory | Project scope <project-root>/.dsh/memory |
|---|---|
| Personal preferences (pnpm, Chinese comments) | Technical decisions (A over B, because C) |
| Working habits (test before commit) | Conventions (layout, naming, build commands) |
| Cross-project lessons | Key numbers / IDs (ports, servers, app IDs) |
| Communication style | Anything the team should share through the repo |
Still true in a different project? → user scope. Only true here? → project scope.
Two physically isolated stores — user ~/.dsh/memory and project <project-root>/.dsh/memory — that can never mix. The project root is auto-detected by a priority chain, clearest signal first:
DSH_MEMORY_PROJECT_DIR env override.dsh/memory marker above (supports nested sub-project scopes).git / .svn / .hgStorage layout
~/.dsh/memory/ <- user scope (personal, cross-project)
|-- MEMORY.md <- guarded index, newest first
|-- memories/20261004-181500-prefer-pnpm.md
<project-root>/.dsh/memory/ <- project scope (team-shared, commit it)
Injection happens at session start via ctx.systemPrompt: user memories always; project root-level memories always; path-tagged memories when the tag hits the session's working-directory chain or a touched directory's chain (see Touch activation above); untouched tags counted in the hint line; 25-entry cap on top of the scope-level guards.
npm install && npm run build && npm test # 64 tests, zero type errors
Unit + type compile against the shipped official types + runtime smoke (real defineTool, end-to-end save → search → read → list) + a real-cordis activation guard, with CI on Ubuntu and Windows.
dsh-memory happily coexists with DSH's official MCP memory options — pick whichever fits your workflow, or use both.
MIT. Not affiliated with DeepSeek or Anthropic.
给 DeepSeek Harness 装上跨会话持久记忆——Claude Code 的记忆模型:你的 agent 记得住、醒得来、项目之间不串味。纯文件、零依赖。(English)
你的 DSH agent 每次开会话都是"初次见面"。 装上 dsh-memory,它记得你。
会话 1 你:"记住——这个项目用 pnpm,不用 npm。"
Agent:memory_save 已保存
会话 2 你:"我们用什么包管理器?"
Agent:"pnpm——你昨天告诉我的。" <- 从此不用重复解释
无服务端、无账号、无 embedding——只有纯 markdown 文件,删掉目录就是彻底遗忘。
打开 Settings → Memory:双域全部记忆一屏可搜、工作区树形展开(嵌套子项目自动发现)、子文件夹分组、护栏仪表实时可见(行数 / KB / 文件数)。面板内直接新增、改写、打标签、删除任意记忆——和 agent 工具调用走同一条带护栏管线,你在界面改的就是模型下次看到的。
项目记忆带子目录标签。标签命中会话工作目录(含祖先链)时注入——会话触碰它的那一刻也注入:一次 read/edit/write/grep/glob/bash/pwsh 调用进了 frontend/src,[frontend] 和 [frontend/src] 立即激活并保持到会话结束。单调递增、会话恢复后仍在——和嵌套 CLAUDE.md 完全同理,由你实际做了什么触发,而不只是启动时 cd 在哪。
未触碰区域不静默隐藏,始终提示:+3 more tagged to areas you haven't touched — memory_search surfaces them.
每个会话的提示词携带它自己工作区的记忆,保存也落进同一个工作区——多会话 web 宿主零串味。
根级记忆恒注入;区域记忆工作/触碰才加载;注入 25 条上限 + 硬护栏(每域 200 行 / 25KB 索引、500 条)——记得再多也不撑爆上下文。
原子写入(崩溃不留半截文件)· 所有写入路径拒存密钥(面板也算)· 面板 API 跨源 + method 双栅栏 · 防 id 路径穿越 · $HOME、盘符根、tmp 目录永不成为项目作用域(Windows 感知)。
没有要部署的、没有会坏的。精简宿主优雅降级——可选宿主服务全部防御式读取,缺了工具照常工作。
前置:先装 DSH 本体——npm install -g @deepseek-ai/dsh(源码检出则命令加 pnpm 前缀)。
dsh plugin --profile web add @fooxe/dsh-memory # 已装 DSH CLI
pnpm dsh plugin --profile web add @fooxe/dsh-memory # 源码检出方式
--profile 必填且放在 add 前面——填你实际启动的 profile(Web 界面就是 web;已有哪些看 ~/.dsh/profiles/)。
装完必须重启 DSH(工具只在启动时注册),再开新会话说*"记住我喜欢 pnpm"*验证。~/.dsh/memory/MEMORY.md 随之出现;项目内决策落在 <项目根>/.dsh/memory/——提交版本库全组共享。
| 症状 | 解法 |
|---|---|
dsh: command not found | DSH 本体没装,看前置步骤 |
required option '--profile <name>' | 参数放在子命令前面:dsh plugin --profile web add ... |
pnpm ERR_P..._STORE: Unexpected store location | 终端 pnpm 与 DSH 自带(11.7.0)不一致——删掉整个 profile 目录(~/.dsh/profiles/web)重跑 plugin add,全新重建 |
| 装了也重启了还是没有记忆工具 | 看启动日志 warning: ... did not activate;跑 dsh --profile web --dump-config | grep fooxe 确认在插件树里;仍在就把日志发 issue |
ERR_PNPM_IGNORED_BUILDS | 对本插件无害(零原生依赖);profile 目录跑 pnpm approve-builds 清掉 |
plugin add 装到旧版本 | 默认源(镜像)滞后。显式官方源:npx pnpm@11.7.0 add @fooxe/dsh-memory@latest --registry=https://registry.npmjs.org;或 ~/.npmrc 加 @fooxe:registry=https://registry.npmjs.org |
| 工具 | 作用 |
|---|---|
memory_save | 保存持久记忆;项目内默认存项目级,否则存用户级 |
memory_search | 大小写不敏感关键词检索(id/标题/标签/正文,跨双域) |
memory_read | 完整读取——字段与 Claude Code 官方 project_memory_read 一致(content?、local_file?、size_bytes、updated_at、truncated) |
memory_list | 双域最近记忆列表(新→旧) |
工具描述内置保存门槛(参照 Claude Code / Codex)——只存月度级稳定事实、结论时刻保存(过程状态不存)、拿不准先问用户;密钥永不存。
写入规则(移植自 Claude Code / Gemini CLI 实践):
何时记:偏好/纠正出现(纠正是最高价值记忆)、决策诞生、关键数字/ID 出现、踩坑+解法闭环。永不记:密钥、临时状态、代码里直接能读到的、未证实的猜测。
记哪级——一句话判定:关于"这个人"还是"这个工程"?
记用户级 ~/.dsh/memory | 记项目级 <项目根>/.dsh/memory |
|---|---|
| 个人偏好(我用 pnpm、注释用中文) | 技术决策(用 A 方案,因为 C) |
| 工作习惯(先跑测试再提交) | 项目约定(目录结构、命名、构建命令) |
| 跨项目经验("这类库都有 X 坑") | 关键数字/ID(端口、服务器、AppID) |
| 沟通风格 | 一切该随版本库共享给团队的 |
换个项目这条还成立?→ 用户级。只在这里成立?→ 项目级。
两个物理隔离的存储域——用户级 ~/.dsh/memory + 项目级 <项目根>/.dsh/memory——永不混淆。项目根按优先级链自动判定,越明确的信号越优先:
DSH_MEMORY_PROJECT_DIR 环境变量.dsh/memory 标记(支持嵌套子项目).git / .svn / .hg存储布局
~/.dsh/memory/ <- 用户级(个人,跨项目)
|-- MEMORY.md <- 护栏索引,新→旧
|-- memories/20261004-181500-prefer-pnpm.md
<项目根>/.dsh/memory/ <- 项目级(团队共享,随版本库提交)
注入发生在会话启动时(ctx.systemPrompt):user 域记忆恒注入;项目根级恒注入;带路径标签的按"命中工作目录链 或 触碰目录链"注入(见上方触碰激活);未触碰的计数进提示行;注入另有 25 条上限叠在域级护栏之上。
npm install && npm run build && npm test # 64 项测试,0 类型错误
单元 + 对官方类型真实编译 + 运行时冒烟(真实 defineTool,save → search → read → list 端到端)+ 真实 cordis 激活守卫;CI 跑 Ubuntu 和 Windows。
与 DSH 官方 MCP 记忆方案完全共存——按工作流任选,或两者同用。MIT 协议,与 DeepSeek、Anthropic 无关联。