🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

工作区记忆 TheSethRose/dsh-workspace-memory

DeepSeek Harness
TheSethRose26 天前有提交已提供中文文档扫描:含敏感能力

按工作区持久保存并自动注入可审阅的记忆

30/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/6 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add TheSethRose/dsh-workspace-memory
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:待复验
是什么
dsh 原生插件 · chat
装得上吗
曾在 dsh 0.2.0-rc.2 下真实安装成功,但当前 dsh 已更新至 0.2.1-rc.5,本站尚未在新版下复验
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 26 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 46 处,展示前 34 条)
  • 发起网络请求
    client.js:139
    async function api(operation,args={}){const response=await fetch('/workspace-memory/api',{method:'POST',headers:{'Content-Type':'application/json','X-
  • 发起网络请求
    embeddings.js:60
    this.fetch = options.fetch ?? ((...args) => globalThis.fetch(...args));
  • 发起网络请求
    embeddings.js:85
    response = await this.fetch(this.url.toString().replace(/ $/, '') + '/api/embed', {
  • 执行外部命令固定命令
    apple-embedding-evaluation.cjs:10
    const output = JSON.parse(execFileSync('swift', [path.join(__dirname,'apple-embedding-probe.swift')], {input:JSON.stringify(texts),encoding:'utf8',tim
  • 读取本地文件
    build.cjs:14
    const sources = new Map(files.map(file => [file, fs.readFileSync(path.join(root, file), 'utf8')]));
  • 写入本地文件
    build.cjs:37
    fs.writeFileSync(path.join(root, helpers[index]), sources.get(`${module}.js`));
  • 写入本地文件
    build.cjs:39
    fs.writeFileSync(path.join(root, entry), `// Generated by build.cjs. Edit host.mjs and helpers, not this artifact.\n${host}`);
  • 写入本地文件
    build.cjs:40
    fs.writeFileSync(path.join(root, 'cordis.patch.yml'), `- insert:\n - id: workspace-memory\n name: ./${entry}\n`);
  • 读取本地文件
    build.cjs:42
    for (const file of fs.readdirSync(root)) {
  • 删除本地文件
    build.cjs:43
    if (GENERATED.test(file) && !keep.has(file)) fs.rmSync(path.join(root, file));
  • 写入本地文件
    build.test.cjs:12
    fs.copyFileSync(path.join(__dirname, 'build.cjs'), path.join(root, 'build.cjs'));
  • 写入本地文件
    build.test.cjs:13
    fs.writeFileSync(path.join(root, 'host.mjs'), "import core from './core.js';\nimport embeddings from './embeddings.js';\nexport const value = () => [c
  • 写入本地文件
    build.test.cjs:14
    fs.writeFileSync(path.join(root, 'core.js'), "module.exports = { value: 'old-core' };\n");
  • 写入本地文件
    build.test.cjs:15
    fs.writeFileSync(path.join(root, 'embeddings.js'), "module.exports = { value: 'old-embeddings' };\n");
  • 写入本地文件
    build.test.cjs:16
    fs.writeFileSync(path.join(root, 'client.js'), '// Client revision one\n');
  • 写入本地文件
    build.test.cjs:30
    fs.writeFileSync(path.join(root, 'core.js'), "module.exports = { value: 'fixed-core' };\n");
  • 读取本地文件
    build.test.cjs:42
    assert.ok(fs.readFileSync(path.join(root, 'cordis.patch.yml'), 'utf8').includes(third.entry));
  • 读取本地文件
    build.test.cjs:43
    for (const helper of third.helpers) assert.ok(fs.existsSync(path.join(root, helper)));
  • 读取本地文件
    build.test.cjs:59
    assert.equal(fs.existsSync(path.join(root, 'cordis.patch.yml')), false);
  • 读取本地文件
    build.test.cjs:68
    for (const stale of ['runtime-deadbeefdeadbeef.mjs', 'core-runtime-deadbeefdeadbeef.cjs', 'embeddings-runtime-deadbeefdeadbeef.cjs']) assert.equal(fs.
  • 读取本地文件
    build.test.cjs:69
    for (const kept of ['keep-me.txt', 'runtime-notahash.mjs']) assert.ok(fs.existsSync(path.join(root, kept)), `${kept} must survive`);
  • 读取本地文件
    build.test.cjs:70
    assert.ok(fs.existsSync(path.join(root, result.entry)));
  • 读取本地文件
    client.test.cjs:12
    vm.runInNewContext(fs.readFileSync(require('node:path').join(__dirname,'client.js'),'utf8'),{window,document:{createElement:()=>({})}});
  • 读取本地文件
    client.test.cjs:58
    vm.runInNewContext(fs.readFileSync(require('node:path').join(__dirname,'client.js'),'utf8'),{window,document:{createElement:()=>({})},fetch,console});
  • 读取本地文件
    client.test.cjs:105
    vm.runInNewContext(fs.readFileSync(require('node:path').join(__dirname,'client.js'),'utf8'),{window,document:{createElement:()=>({})},fetch,console});
  • 发起网络请求
    embeddings-runtime-e4b9ae6108439894.cjs:60
    this.fetch = options.fetch ?? ((...args) => globalThis.fetch(...args));
  • 发起网络请求
    embeddings-runtime-e4b9ae6108439894.cjs:85
    response = await this.fetch(this.url.toString().replace(/ $/, '') + '/api/embed', {
  • 发起网络请求
    integration.test.cjs:293
    const response = await h.request('create', { workspaceId: 'workspace-a', input: { title: 'Unauthorized', content: 'Must not save.' } });
  • 发起网络请求
    integration.test.cjs:302
    assert.equal((await refused.request()).statusCode, 403);
  • 发起网络请求
    integration.test.cjs:308
    ]) assert.equal((await h.request('workspaces', {}, overrides)).statusCode, 403);
  • 发起网络请求
    integration.test.cjs:309
    const valid = await h.request();
  • 发起网络请求
    integration.test.cjs:317
    await h.request('workspaces', {}, { rawBody: '{broken' }),
  • 发起网络请求
    integration.test.cjs:318
    await h.request('workspaces', {}, { rawBody: 'x'.repeat(100001) }),
  • 发起网络请求
    nomic-embedding-evaluation.cjs:15
    const response = await fetch(endpoint + '/api/embed', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ model,
扫描于 2026/11/1(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

依赖的 DSH / Cordis 模块
@deepseek-ai/dsh-system-prompt@deepseek-ai/dsh@deepseek-ai/dsh-storage-domain@deepseek-ai/dsh-tools
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 工作区级持久记忆
  • 可审查的增删改查
  • 自动注入上下文

为 DeepSeek Harness 提供工作区级持久记忆:可审查的 CRUD、跨项目全局偏好、自动注入上下文,以及每轮请求披露。

README

由 DeepSeek 最新模型翻译生成
工作区记忆 为 DeepSeek Harness 提供持久化、按工作区隔离的记忆,带显式批准与请求透明。本地包面向 DSH 0.2.0-rc.2,注册 Host 与 Web Client 插件。 使用记忆 在侧边栏打开 Workspace memory,或在会话标题栏打开 Memory,即可打开该会话的工作区与控制项。 - 新建记忆,选择类型,然后 Save & approve 以便日后复用。Save as suggestion 会先把它排除在请求之外,等你批准后再加入。 - 按标题/内容、状态或类型浏览、搜索。选中一条记录,可以编辑、置顶、启用/停用,或把它排除出当前会话。 - 可选过期时间使用 UTC 的 ISO 时间戳。替换项只有在批准之后、且仍在有效期内,才会压制原记录。 - 展开 Source & revision history,查看来源、早前内容,以及「恢复为建议」。恢复绝不会悄悄批准旧版本。 - Delete 始终显示在选中记忆的操作行里,列表每一行也各自带删除控件。两条路径打开同一张确认卡——你不确认就不会删除任何东西,确认卡会明确说明删除同时会移除修订历史。Replacement 区块会把一条记忆标记为已被取代,而不是删除它。 - 展开 Memory settings,配置自动注入、助手建议和上下文预算。改动要显式保存。
展开完整文档(README 剩余 1 节)
工作区记忆

为 DeepSeek Harness 提供持久化、按工作区隔离的记忆,带显式批准与请求透明。本地包面向 DSH 0.2.0-rc.2,注册 Host 与 Web Client 插件。

使用记忆

在侧边栏打开 Workspace memory,或在会话标题栏打开 Memory,即可打开该会话的工作区与控制项。

- 新建记忆,选择类型,然后 Save & approve 以便日后复用。Save as suggestion 会先把它排除在请求之外,等你批准后再加入。
- 按标题/内容、状态或类型浏览、搜索。选中一条记录,可以编辑、置顶、启用/停用,或把它排除出当前会话。
- 可选过期时间使用 UTC 的 ISO 时间戳。替换项只有在批准之后、且仍在有效期内,才会压制原记录。
- 展开 Source & revision history,查看来源、早前内容,以及「恢复为建议」。恢复绝不会悄悄批准旧版本。
- Delete 始终显示在选中记忆的操作行里,列表每一行也各自带删除控件。两条路径打开同一张确认卡——你不确认就不会删除任何东西,确认卡会明确说明删除同时会移除修订历史。Replacement 区块会把一条记忆标记为已被取代,而不是删除它。
- 展开 Memory settings,配置自动注入、助手建议和上下文预算。改动要显式保存。会话设置可以覆盖工作区默认值,也可以重置回默认值。
- Context preview & activity 会展示选中原因、修订、因预算被省略的项,以及最近的请求记录。
- 助手回复上的 Remember… 会打开同一个编辑器,并带上指向该回复的链接。它不会自动复制或批准助手内容。
- 把 Workspace 切到 Global · all workspaces,就能保留适用于所有项目的内容:写作风格、语气,或关于你的稳定事实。全局条目只接受 Preference 和 Fact 两种类型——项目决策和工作上下文留在各自的工作区——它们会加入每个项目的请求。置顶某条,它就会进入每个请求,而不只是匹配到的请求。两者冲突时,项目条目覆盖全局条目。

「Remember: use pnpm for this project」这类对话请求,授权一次对话式写入。更正和删除需要用户明确意图,并做乐观修订检查。检索到或引用的文本不能授予该授权。未经请求的助手建议在批准前始终是建议状态。

请求披露

聊天每轮显示一个紧凑的 Memory 披露项。空选择只汇总一次,而不是重复成零字符的行。展开后可查看有界、可滚动的逐步日志、选中的 ID/修订/原因,以及被省略的项。「Started」表示一次模型调用已开始,它不是送达回执。
只有已批准、已启用、未过期、未被排除的记录才有资格。全局记录在每个工作区都有资格;按 id 排除某条记录,仍会在该会话或工作区中将其移除。置顶记录优先,但仍要遵守序列化上下文的精确预算。每条渲染出来的条目都会标明自己的作用域,当项目条目与全局条目冲突时,项目条目覆盖全局条目。禁用或删除某条条目,无法撤回更早的请求或源对话。

隐私与边界

DSH 存储域 workspace_memory 在当前配置档中保存记录、修订历史、设置和使用元数据。每条记录都以注册的工作区身份为键。对话归属跟随执行会话,而不是侧边栏当前选中的工作区。全局记录使用保留的全局键,任何工作区都无法占用,因此两种作用域永远读不到对方的记录,全局 API 路径也完全不接受工作区或会话输入。为某个工作区关闭记忆后,该处的全局注入也会停止,因为上下文是按工作区组装的。

浏览器 API 要求通过 Harness 认证边界,并且只接受本地同源的 POST 请求,且需带自定义请求头。本插件不对记忆加密。已批准、已选中的文本会成为上下文,发送给会话配置的模型服务商;插件本身不会增加向嵌入服务商的传输。

检索状态

排序是混合式且本地的。确定性关键词匹配始终运行;当 Find memories by meaning 开启时,有资格的记录还会通过仅限回环的端点,由本地嵌入模型按余弦相似度排序。全局记录与工作区记录共用一份排序列表和一份预算;置顶记录排在最前,然后按得分排序,得分相同时项目条目排在全局条目之前。任何非回环端点都会被拒绝,因此记忆文本和查询永远不会离开这台机器。如果模型或服务不可用,检索会回退到关键词,进入短暂冷却,请求披露也会逐步说明这一点。

默认后端是 Ollama,使用 nomic-embed-text:v1.5,地址为 http://127.0.0.1:11434,可用 WORKSPACE_MEMORY_EMBED_ENDPOINT 和 WORKSPACE_MEMORY_EMBED_MODEL 覆盖。向量缓存在内存中,以工作区、记录 ID 和修订为键,因此编辑过的记忆永远不会复用过期向量;向量可重新计算,并非权威数据,也不存储在持久域中。
这里的实测限制很关键:在自建的诊断语料上,混合路径达到了 8/8 精确召回、8/8 简洁改写召回、4/4 自然改写召回。默认 Relevance threshold 为 0.55,校准于 2026-10-05 —— 在真实项目语料上,无关查询的余弦相似度最高为 0.5409,而最弱的相关匹配得分为 0.5754,0.55 是唯一一个既没有无关选中、又保持完整 top-1 召回的扫描值(0.50 放进了 10 条中的 2 条)。想提高精度就调高它,想提高召回就调低它,或者干脆关掉语义搜索。两次扫描和遗留缺口见评估 —— 长记忆是从有界前缀嵌入的,而不是分块嵌入,并且没有跨会话的持久索引。

安装

需要 DeepSeek Harness 0.2.0-rc.2。

通过插件管理器把 bundle 加进你的配置档,使用 spec:

github:TheSethRose/dsh-workspace-memory

如果 dsh 命令行在 PATH 上,同样的安装是:

dsh plugin --profile desktop add github:TheSethRose/dsh-workspace-memory

然后启用 dsh-workspace-memory,刷新 Harness 页面加载面板。

生成的运行时产物(runtime-<hash>.mjs、core-runtime-<hash>.cjs、embeddings-runtime-<hash>.cjs、cordis.patch.yml)已提交,所以 git 安装不需要构建步骤,也不需要 pnpm 的 allowBuilds 条目。记忆存储在配置档的 workspace_memory 存储域中,按注册的工作区作键,全局条目使用保留键 global。

语义搜索是可选的,并且始终在本地运行。它需要 Ollama 在 http://127.0.0.1:11434 上提供 nomic-embed-text:v1.5;没有它,检索会回退到关键词匹配,请求披露也会说明这一点。用 WORKSPACE_MEMORY_EMBED_ENDPOINT 和 WORKSPACE_MEMORY_EMBED_MODEL 覆盖。非回环端点会被拒绝。

开发与激活

在本目录下:

node build.cjs
node --test core.test.js integration.test.cjs client.test.cjs embeddings.test.cjs build.test.cjs
node retrieval-evaluation.cjs
node nomic-embedding-evaluation.cjs

build.cjs 会对生成器和每个实现文件(build.cjs、host.mjs、core.js、embeddings.js、client.js)做哈希,写出一个内容寻址的 Host 入口 runtime-<hash>.mjs,写出 CommonJS 辅助模块的物理逐版本副本(core-runtime-<hash>.cjs、embeddings-runtime-<hash>.cjs),并让 bundle 补丁指向那个入口。Node 按解析后的路径缓存 CommonJS,所以真正防止重新构建后跑到旧代码的是辅助模块副本,而不是 Host 的查询字符串。每次构建都会清理上一个版本,因此目录里始终只保留一个。任何源码改动后都要运行 node build.cjs;当提交的产物落后于源码时,build.test.cjs 会失败。Client 是预构建的 ModuleLoader 模块;这个 bundle 不依赖应用外壳的 watcher。激活后刷新现有的 Harness URL 以加载 Client 改动。不要启动替代的 Vite 服务器。
构建完成后,通过插件管理器切换已安装的 bundle 即可;这次重载对 Host、core、embeddings 和 Client 的改动都够用,不需要重启 Harness。HTTP 路由和 Inspect 服务商注册为 Cordis 效果,因此禁用再启用就能干净地释放它们。

测试覆盖持久化 CRUD 与乐观修订、工作区归属、审批/来源/历史规则、注入与预算门禁、抑制、请求披露、HTTP 认证/CSRF、会话设置、预览、路由释放、紧凑披露渲染、混合排序门禁,以及 embedding 传输(前缀、批处理、缓存失效、截断、畸形响应、回环拒绝)。测试用打桩的 fetch,因此不会联系任何服务。组件契约测试是轻量 mock;实时浏览器检查另外验证了桌面/移动端渲染、两种主题对比度、键盘焦点,以及一个禁用的合成审批/恢复/删除 fixture,没有残留测试记录。

License

MIT — see LICENSE。
预览分享卡片长什么样 ↓TheSethRose/dsh-workspace-memory
分享 · DeepSeek Harness Hub
TheSethRose/dsh-workspace-memory

按工作区持久保存并自动注入可审阅的记忆

回到顶部