dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
把 DeepSeek Harness(DSH)的真实运行状态投影为四层记忆的只读查看器:
| 层 | 认知隐喻 | 看到的是 DSH 里的什么 |
|---|---|---|
| 🕐 短期记忆 | 眼前的交换 | 会话的最近 N 轮(用户/AI 文本、工具调用与结果、goal/todo 变化),来自会话事件日志(session.jsonl.zstd 解码,node:zlib 内置 zstd,零第三方依赖) |
| ⚙️ 工作记忆 | 正在推进的任务 | goal / plan / todos / sessionStats / subagent / contextPressure / contextBreakdown / tokenUsage / permissions 等会话投影行(优先取内存中 sessionProjections.snapshot,磁盘投影缓存兜底) |
| 🗄 长期记忆 | 跨会话的沉淀 | DSH home、工作区索引(workspace.json → 会话档案)、最近会话清单(标题/体量/时间)、设置、知识库 roots 长期文档统计 |
| 🧩 过程 / 语义记忆 | 会做什么 & 理解的相似性 | 技能清单(SKILL.md / *.skill.md,= 过程记忆)+ knowledge-base 语义索引 dump 统计(文档/词项/向量维度,= 语义记忆容量) |
DSH 没有名为 “memory” 的独立存储——agent 的状态都落在真实会话记录、投影行与磁盘文件中。 本插件的「记忆分层」是展示性认知隐喻(详情见 docs/MODEL.md),每一处都标注了 「来自哪个真实字段 / 文件」。只读,不改写任何 DSH 状态。
当前版本:v0.2.0(变更记录见 CHANGELOG.md)
发现规则与 DSH 自身(@deepseek-ai/dsh-agent-instructions)完全一致,所以看到的就是 agent
实际加载的那些文件:
$DSH_HOME/AGENTS.md(用户全局,无 overlay);projectRootMarkers,默认 .git 的最近祖先目录)逐级到会话 cwd,
每级先基础候选 AGENTS.md / CLAUDE.md,再本地 overlay AGENTS.local.md / CLAUDE.local.md
—— 顺序即“由宽泛到具体”的优先级。界面:左侧按 scope 分组列出候选文件(存在/缺失、大小、local 标记),点选即读;缺失文件以
新建模式打开,保存即创建。右侧编辑器为等宽文本框,带字节数、未保存标记、Cmd/Ctrl+S 保存、
⟲ 重新加载;保存成功显示大小与备份路径。
写入安全约束(重要):
forbidden;$DSH_HOME/memory-view-backups/<name>.<时间戳>.bak;maxSourceBytes / maxWriteBytes;expectedMtimeMs 的乐观并发校验:磁盘上文件被别人改过时返回 conflict,
界面提示先「重新加载」再保存。dsh-memory-view/ # ← git 仓库根
├── package.json # dsh.client 声明(platform: web → 浏览器端 bundle)
├── lib/
│ ├── index.js # Node 半身:/memory-view RPC 通道 + ctx.provide('memoryView')
│ ├── client.js # 浏览器 bundle:标题栏按钮 + 记忆面板(手写、零构建)
│ └── host/
│ ├── collectors.mjs # zstd 会话日志解码 / 磁盘枚举 / KB / 技能收集(纯 Node)
│ ├── instructions.mjs # AGENTS.md 发现 / 读取 / 原子写入(含安全约束)
│ └── service.mjs # 四层快照服务核心(框架无关,可单测)
├── docs/
│ ├── MODEL.md # 记忆模型映射说明
│ └── research/ # DSH 客户端插件框架调研报告
├── test/ # node --test:collectors / service / instructions / client(34 项断言)
├── README.md
└── CHANGELOG.md
以本机 web profile 为例:
# 1. 软链到 profile 的 node_modules(client-modules 与 Node loader 按包名解析)
mkdir -p ~/.dsh/profiles/web/node_modules
ln -sfn /Users/robinddu/Desktop/workspace/robinddu/dsh-memory-view \
~/.dsh/profiles/web/node_modules/dsh-memory-view
# 2. 在 ~/.dsh/profiles/web/cordis.patch.yml 追加:
- insert:
- id: memory-view
name: 'dsh-memory-view'
config:
# ---- Node 半身 ----
kbRoots: # 长期记忆里的“文档”来源(不配 = 不扫)
- '/Users/robinddu/Desktop/workspace/output'
skillRoots: # 过程记忆:技能清单扫描根(*.skill.md / SKILL.md)
- '/Users/robinddu/Desktop/workspace/robinddu/ebook-reader'
- '/Users/robinddu/Desktop/workspace/robinddu/poetry-skill'
# kbIndexJson: '' # knowledge-base 语义索引 dump(index.json,可选项)
# ---- AGENTS.md 指令(第五个页签)----
instructions:
enabled: true
baseCandidates: ['AGENTS.md', 'CLAUDE.md'] # 项目 scope 基础候选
localCandidates: ['AGENTS.local.md', 'CLAUDE.local.md'] # 本地 overlay 候选
projectRootMarkers: ['.git'] # 项目根标记
extraRoots: [] # 额外允许查看/编辑的根目录
maxSourceBytes: 1048576 # 单文件读取上限
maxWriteBytes: 262144 # 单次写入上限
backup: true # 覆盖前备份到 $DSH_HOME/memory-view-backups
# ---- 浏览器面板 ----
defaultTab: 'shortTerm' # shortTerm | working | longTerm | proceduralSemantic | instructions
autoRefreshMs: 10000 # 面板打开时自动刷新间隔;0 = 关闭(会话运行中自动暂停)
drawerWidth: 860 # 抽屉宽度 px
debug: false
dsh web(新插件需重启以重新扫描 client 插件清单),浏览器硬刷新
(Cmd+Shift+R)。此后代码改动只需硬刷新页面即可生效。接线原理与 dsh-chat-fold / dsh-attention 相同:软链一次、
name用包名, client-modules 扫描dsh.client声明并服务/plugins/dsh-memory-view/client.js, Node loader 从 profile 目录解析包入口。
lib/index.js):
web profile 组合了 sessions + sessionProjections,构造实时行提供者
(ctx.get('sessions').list() + sessionProjections.snapshot(session).values);ctx.webServer.register({ kind: 'prefix', path: '/memory-view', handler }) 挂
RPC 通道,协议与 dsh-multi-tenant /mt 一致:
POST {type:'client-request', rpcId, method, payload} →
{type:'server-response', rpcId, result:{ok, value|error}};
方法:health / overview / snapshot / shortTerm / working / longTerm / proceduralSemantic / refresh;ctx.provide('memoryView', …) 供其他插件复用。lib/host/collectors.mjs):会话文件是多个 zstd frame 首尾相连
的 JSONL(每批一帧、带 checksum)。zstdDecompressSync(node:zlib,Node ≥ 24 本机
已验证)只解第一帧,故先按 frame 头/block 头结构扫描边界再逐帧解码——该算法与
@deepseek-ai/dsh-session-persistence-jsonl 内置解码器一致,纯 Node 实现、可单测。lib/client.js):ctx.slots.inject('conversation.session.header.actions')
注册按钮;面板组件挂在 shell.overlay(list 槽,additive)并经 React portal 渲染到
document.body;ctx.connection.rpc.call('/memory-view', 'snapshot', …) 取数;
ctx.sessions.list.subscribe 监听会话切换自动重载;通道不可用时降级为
ctx.sessions 投影摘要。<style>(dataset.plugin 标记,卸载/HMR 自动清理),
变量跟随 DSH 主题(--dsw-alias-*,缺省回退值兜底)。npm test # node --test(20 项断言:解码/摘要/快照/分发/客户端纯函数)
node --check lib/client.js
ctx.connection 通道可用);纯浏览器降级视图只展示会话投影摘要。data 是字符串化 JSON,解码时
已归一;被 compaction 汇总的历史用 sourceEventSeqs 折叠后的消息展示。session_projcache.json)兜底;
未打开过的旧会话以磁盘行为准。ctx.skills.register)不属于文件清单,不在本视图范围。collectors.mjs、
service.mjs 与 client.js 顶部常量,影响面小。~/.dsh/profiles/web/cordis.patch.yml 删除对应 insert 段;~/.dsh/profiles/web/node_modules/dsh-memory-view;dsh web。无 localStorage 残留(面板状态仅内存)。MIT