wangyihao0001-oss/dsh-task-memory
Task-isolated long-term memory for DeepSeek Harness — remember / recall / search stay inside one task boundary.
编辑导读Editor's Brief
## 核心特性
- 将长期记忆条目存储在 ~/.dsh/storages/task-memory/ 下按任务划分的 vault 中,每个 vault 由一个以任务 ID 命名的纯 JSON 文件表示。
- 通过 memory_bind_task 将会话绑定到指定名称的任务 vault,默认任务则根据会话工作目录推导。
- 提供 memory_remember、memory_recall、memory_search、memory_forget、memory_current_task、memory_list_tasks 和 memory_clear_task 工具,用于管理任务范围内的记忆事实。
- 当启用 injectPrompt 时,按照配置的条目数量和字符预算,将置顶和最近的事实注入当前 agent 会话的系统提示词。
- 强制执行 vault 容量限制:优先淘汰最旧的非置顶条目,永不淘汰置顶条目;当 vault 已满且没有可移除条目时,拒绝新增 key。
## 使用场景
- 将项目特定事实、技术栈决策或任务上下文与其他 DeepSeek Harness 会话隔离保存。
- 在将会话绑定到指定任务后,支持在同一任务 vault 中召回已存储的 key。
- 将置顶任务事实提供给 agent 系统提示词,使活跃会话无需手动重复即可访问持久上下文。
## 技术细节
- 写入操作使用临时文件和原子重命名,按任务进行的变更会通过进程内锁串行化,以保持 vault 快照的一致性。
- 搜索为词法搜索,使用英文 token 和中文二元分词;空查询会列出最近或置顶条目。
- cordis.patch.yml 中的配置可控制注入限制、字符预算、提示词注入开关、最大条目数以及可选存储根目录。
- 该插件通过 dsh.bundle.patch 以 Git bundle 形式安装到 web 等 DSH profile 中,并要求 Node.js 20 或更高版本。
## 注意事项
- 卸载后 vault 文件仍会保留,用户如需备份或删除,必须手动处理 ~/.dsh/storages/task-memory/。
- 关键词搜索不使用 embeddings 或向量搜索,该插件也不会为 DeepSeek Harness 的其他部分提供沙箱。
- 记忆条目中不应包含凭据、token 或个人密钥。
## Core Features
- Stores long-term memory entries in per-task vaults under ~/.dsh/storages/task-memory/, with each vault represented by a plain JSON file named after the task ID.
- Binds a session to a named task vault through memory_bind_task, while the default task is derived from the session working directory.
- Provides memory_remember, memory_recall, memory_search, memory_forget, memory_current_task, memory_list_tasks, and memory_clear_task tools for managing task-scoped facts.
- Injects pinned and recent facts into the current agent session system prompt when injectPrompt is enabled, using configured entry limits and character budgets.
- Enforces a vault capacity limit by evicting oldest non-pinned entries first, never evicting pinned entries, and rejecting new keys when a full vault has no removable entries.
## Use Cases
- Keeps project-specific facts, stack decisions, or task context separated from other DeepSeek Harness sessions.
- Supports recalling stored keys within the same task vault after binding a session to a named task.
- Supplies pinned task facts to the agent system prompt so active sessions can access persistent context without manual repetition.
## Technical Details
- Writes use a temporary file and atomic rename, and per-task mutations are serialized with an in-process lock to maintain consistent vault snapshots.
- Search is lexical, using English tokens and Chinese bigrams, and an empty query lists recent or pinned entries.
- Configuration in cordis.patch.yml controls injection limits, character budgets, prompt injection toggle, maximum entries, and optional storage root.
- The plugin installs as a Git bundle through dsh.bundle.patch into a DSH profile such as web, and requires Node.js 20 or newer.
## Notes
- Vault files remain after uninstall, so users must back up or delete ~/.dsh/storages/task-memory/ manually if needed.
- Keyword search does not use embeddings or vector search, and the plugin does not sandbox other parts of DeepSeek Harness.
- Memory entries should not contain credentials, tokens, or personal secrets.
安装Install
dsh plugin --profile web add "github:wangyihao0001-oss/dsh-task-memory"
把 wangyihao0001-oss/dsh-task-memory 加入你的 DSH 配置(web profile)即可启用。
READMEREADME
dsh-task-memory
English | 中文
Task-isolated long-term memory for DeepSeek Harness.
Memories live in per-task vaults under ~/.dsh/storages/task-memory/. Facts stored for one task are invisible to another unless you deliberately switch.
Catalog: dsh.pub/en/plugins/dsh-task-memory
Why this exists
Most DSH memory plugins are global or workspace-wide. This one treats task as the isolation boundary:
- Default task = derived from session
cwd memory_bind_taskrebinds the current session to a named vault- Search / recall / prompt injection never cross that boundary — prompt injection is registered at agent scope, so each session's system prompt only ever shows its own task's memories
Quick start
# Install into the web profile (pin a full commit SHA for production)
dsh plugin --profile web add "github:wangyihao0001-oss/dsh-task-memory"
# Or via the catalog CLI
npx dshpub add wangyihao0001-oss/dsh-task-memory --profile web
Restart the web UI (or reboot the profile), then in a session:
memory_bind_task— e.g.taskId: "my-app"(optionaltitle)memory_remember—key: "stack",content: "Node 22 + Postgres", optionallypinned: truememory_recall/memory_search— read back within the same taskmemory_current_task— confirm which vault this session is on
Tools
| Tool | Purpose |
|---|---|
memory_bind_task |
Bind this session to a task vault |
memory_current_task |
Show the session's current vault (binding or default) |
memory_remember |
Upsert a fact by key (optional tags / pin / task override) |
memory_recall |
Exact-key read |
memory_search |
Keyword search (EN + 中文 bigrams); empty query lists recent/pinned |
memory_forget |
Delete one key |
memory_list_tasks |
List vaults |
memory_clear_task |
Wipe one vault (confirm: true required) |
Never store secrets in memory entries.
Install / verify / disable
# Install
dsh plugin --profile web add "github:wangyihao0001-oss/dsh-task-memory#<40-char-sha>"
# Confirm the bundle layer is present
dsh --profile web --dump-config
# Remove from the profile when done
dsh plugin --profile web remove dsh-task-memory
After install or remove, restart dsh web (or reboot the profile) so the Cordis layer reloads.
Vault files under ~/.dsh/storages/task-memory/ are not deleted on uninstall — back up or delete them yourself if needed.
Local develop (without installing)
npm install
npm run build
npm test # node:test unit tests
npm run smoke # build + smoke
Link a checkout while developing:
dsh plugin --profile web add "$(pwd)"
If you run DSH from a source checkout:
pnpm dsh web --patch /absolute/path/to/dsh-task-memory/cordis.dev.yml
Update the absolute path in cordis.dev.yml so it points at this checkout’s built lib/index.js.
Config
cordis.patch.yml defaults:
injectLimit: 8 # max memories in prompt context
injectMaxChars: 2400 # soft char budget for the injected block
injectMaxEntryChars: 400 # per-entry char cap in the injected block (truncated)
injectPrompt: true # inject pinned/recent facts for the active task
maxEntries: 500 # vault cap (>= 1); oldest non-pinned entries are evicted first
# (pinned are never evicted; new keys over the cap are rejected;
# upserts of existing keys are not blocked by capacity)
Optional storageRoot overrides ~/.dsh/storages/task-memory.
Storage & reliability
~/.dsh/storages/task-memory/
<task-id>.json
Each file:
{
"taskId": "<task-id>",
"title": "<title>",
"updatedAt": 0,
"entries": [
{
"id": "m_…",
"key": "<key>",
"content": "…",
"tags": [],
"pinned": true,
"createdAt": 0,
"updatedAt": 0
}
]
}
- Files are plain JSON — safe to hand-edit or back up
- Writes go through tmp file + atomic rename, so readers always see a consistent snapshot
- Mutations for the same task (including
memory_bind_tasktitle updates,save, andupdate) are serialized in-process (per-task lock); concurrent agents cannot lose updates. Preferupdateoverload→ mutate →savefor read-modify-write - Pinned entries are never evicted; when a full vault has nothing removable but pinned entries, new keys are rejected with a clear error instead of silently dropping the just-written fact, while upserts of existing keys are never blocked by capacity (they still shrink best-effort)
- On startup, stale
*.tmpfiles from crashed writes are cleaned up (only those older than 1h, so another process's live write is never touched)
Model experience
When injectPrompt is true, the plugin injects a short memory block into the current agent session's system prompt:
- Only the vault bound to that session (or the cwd-derived default)
- Prefer pinned entries, then recent ones, up to
injectLimit/ char budgets - Other sessions and other tasks never appear in this block
Tools remain available for explicit recall/search beyond what fits in the prompt.
Known limitations
- Host-only bundle: no Web UI for browsing vaults yet (see roadmap)
- Keyword search is lexical (EN tokens + 中文 bigrams), not embeddings / vector search
- Isolation is per task id within this plugin — it does not sandbox the rest of DSH
- Catalog listing on dsh.pub is an automated contract check, not a security audit
- Do not store credentials, tokens, or personal secrets in memories
Compatibility
- Node.js
>= 20 - DeepSeek Harness peers as declared in
package.json(@deepseek-ai/dsh-*/cordis/schemastery) - Installs as a Git bundle via
dsh.bundle.patch→cordis.patch.yml - Intended profile:
web(or any profile that loads Host tools)
Roadmap
- ✅ Per-session prompt injection via agent-scoped context (replaces process-level binding guess)
- Optional vector search behind the same tools
- Tiny Web UI page to browse / pin / delete vaults
License
MIT — see LICENSE.
amruthpillai/reactive-resume
tt-a1i/archify
strukto-ai/mirage
liustack/modlens
omdsh-dev/DSH-better-sidebar
dsh-market/dsh-market
GanyuanRan/Aegis