一个Deepseek Harness插件,可以为每一个工作区配置独立的Api Key
32.1/100
综合分
3
GitHub 星标
1,004
npm 周下载
—/5
用户评分
数据截至 2026/10/14 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add dsh-workspace-api-keynpm 源 · dsh-workspace-api-key 的发布者账号已校验与本仓库一致
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · model
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 19 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查✓ 自动检查通过展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✓npm 包dsh-workspace-api-key @ 0.2.6
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/15 20:02:06
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
读写/删除本地文件发起外部网络请求
查看扫描证据(共 10 处,展示前 10 条)
- 读取本地文件lib/index.js:97
const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')) - 读取本地文件lib/index.js:635
if (!existsSync(path)) return emptyState() - 读取本地文件lib/index.js:636
return normalizeState(JSON.parse(readFileSync(path, 'utf8'))) - 写入本地文件lib/index.js:646
mkdirSync(dirname(path), { recursive: true }) - 写入本地文件lib/index.js:647
writeFileSync(path, JSON.stringify(state, null, 2), 'utf8') - 发起网络请求lib/index.js:1134
res = await fetch(`${root}/messages`, { - 发起网络请求lib/index.js:1196
res = await fetch(endpoint, { - 读取本地文件lib/index.js:1626
exists: typeof dir === 'string' ? existsSync(dir) : false, - 读取本地文件lib/index.js:1700
exists: typeof entry.path === 'string' ? existsSync(entry.path) : false, - 发起网络请求lib/client.js:145
res = await window.fetch(`${API_BASE}${path}`, init)
扫描于 2026/10/31(1 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 为工作区配置独立密钥
README
由 DeepSeek 最新模型翻译生成dsh-workspace-api-key
一个 DeepSeek Harness 插件:为每个工作区——必要时也可以为单个会话——单独绑定一把 DeepSeek API key。
DSH 只从一个全局凭据 ref(默认 DEEPSEEK_API_KEY)解析 DeepSeek key,于是所有工作区的所有会话花的都是同一把 key。这个插件加了一个面板,让单个工作区、甚至单个会话可以用自己的 key,这样一把 key 的花费就只落在你指定的会话上。没有单独配置的层级继续用上层设置:
会话 key → 工作区 key → 系统默认
你会得到
- 一行侧栏入口,叫「API Key 分配」,紧跟在宿主自己的「插件」行下方,点开是全宽页面。
- 按工作区配置的 key —— 列出 workspaceRegistry 服务里注册的全部工作区,各自一个 key 输入框。
- 按会话配置的 key —— 每个工作区行可以展开(默认折叠),列出该目录下的会话,每个会话有自己的 key;从上层继承的会话会如实标注层级,而不是假装自己配了 key。
- 系统默认卡片 —— 当前生效的 ref、值的来源(file、env 等)以及打码后的值。
展开完整文档(README 剩余 1 节)
dsh-workspace-api-key
一个 DeepSeek Harness 插件:为每个工作区——必要时也可以为单个会话——单独绑定一把 DeepSeek API key。
DSH 只从一个全局凭据 ref(默认 DEEPSEEK_API_KEY)解析 DeepSeek key,于是所有工作区的所有会话花的都是同一把 key。这个插件加了一个面板,让单个工作区、甚至单个会话可以用自己的 key,这样一把 key 的花费就只落在你指定的会话上。没有单独配置的层级继续用上层设置:
会话 key → 工作区 key → 系统默认
你会得到
- 一行侧栏入口,叫「API Key 分配」,紧跟在宿主自己的「插件」行下方,点开是全宽页面。
- 按工作区配置的 key —— 列出 workspaceRegistry 服务里注册的全部工作区,各自一个 key 输入框。
- 按会话配置的 key —— 每个工作区行可以展开(默认折叠),列出该目录下的会话,每个会话有自己的 key;从上层继承的会话会如实标注层级,而不是假装自己配了 key。
- 系统默认卡片 —— 当前生效的 ref、值的来源(file、env 等)以及打码后的值。
- 测试连接 —— 用该 key 真发一次 POST <baseURL>/messages(max_tokens: 1),返回 ok、invalid、quota、rate-limit 或 unreachable;测试成功会顺手清掉失效标记。
- key 失效提醒 —— 401/403 把绑定的 key 标为 invalid,402 标为 quota,429 标为 rate-limit。当你点进一个生效 key 已失效的会话时,覆盖层会说明情况,并给出去配置、改用上层设置或稍后。
- 不匹配提醒 —— 如果绑 key 时记下的是某个服务商(比如 deepseek-official),而该会话现在跑在另一个服务商上,点进这个会话时会提醒你,因为那次请求会拿着对方不认的 key 发出去。
- 绝不悄悄换 key —— 两种提醒都不会改动实际使用的 key,决定权始终在你手上;自动替换会直接破坏「按会话分离计费」这个初衷。
- 一键回退 —— 清空会话条目回到工作区 key,清空工作区条目回到系统默认。
实现方式
宿主半边(lib/index.js):
- 每个进程包装一次 credentials.resolve(通过 ctx.effect 在卸载时还原),而不是去注册第二个同名服务或第二条 provider 路由——对一个已被占用的名字,cordis 不允许这两者;
- 从 agents.currentInitiator()?.session 取当前会话的目录与 id:agent loop 把整个回合跑在那个异步作用域里,所以解析凭据时这两个值都拿得到,解析器据此选中「有 key 的最具体层级」;
- 把该目录与 workspaceRegistry.list() 做规范化后比对(绝对化、去掉尾部分隔符、Windows 折大小写);
- 由每一层派生出稳定的 ref —— 工作区是 DEEPSEEK_API_KEY_WS_<sha1(规范化路径) 前 16 位十六进制大写>,会话是 DEEPSEEK_API_KEY_SS_<sha1(会话 id) 前 16 位十六进制大写>(会话 id 含 -,不能直接当 ref 名)——通过凭据服务写入 key,并返回这个 ref 的值;
- 只改写 provider 真正会读的 ref:默认 ref、每个适配器配置的 apiKeyEnv,以及插件自己生成的 ref;其它 ref 原样透传;
- 会话列表来自 sessionController 服务(list(),会拆开它 {items: […]} 的信封),控件缺失 / 抛错 / 列表为空时再退到宿主 live 会话服务(ctx.get('sessions').list()),所以那种情况下面板仍能列出会话;侧栏藏起来的两种会话这里也藏:子代理会话(origin: 'subagent' 或带 parentSession)和空会话(建了但一句话都没发过,侧栏只显示当前开着的那个)。两种都不过滤的话,一个只有 1 个真实会话的工作区会列出 13 个;
- 不是注册工作区的目录,只有侧栏真的会显示它才会被列出来。这件事宿主判不了:「空会话里只有当前开着的那个算数」是浏览器端才知道的事(retainedBy.mainView),所以宿主把这种目录连同每个会话的 blank 标记一起发出去,并用 hiddenBlankDirs 点名「里面全是空会话」的目录,由浏览器半边套用与侧栏一致的判据;
- /wsk-api/state 会带上插件自身版本与会话探针(available、shape、source、count、withoutCwd、subagents、samples、error,以及工作区路径样本),面板据此说明为什么没有列出会话:宿主半边是旧版本(只刷新了页面而没重启应用)、没有 sessionController、list() 抛错、信封形状不认识,还是会话的 cwd 与任何工作区路径都对不上;
- 自己的账本(哪一层对应哪个 ref、失效标记、key 是给哪个服务商记的)落在 $DSH_HOME/storages/dsh-workspace-api-key.json;
- 通过 agent/request-error waterfall 观察失败,但从不返回 {kind: 'retry'}——只记录判定结果并 next() 放行。
浏览器半边(lib/client.js)注册到 sidebar.panellist 槽(order: 1)、main 槽(key 为 workspace-api-key)与 shell.overlay 槽(点进会话时的提醒),和 dsh-skill-mcp-panel、dsh-429-guard 用的是同一套槽。全部是朴素的 React.createElement,没有构建步骤,也不打包任何依赖。它会把宿主行与浏览器端 sessions 存储(ctx.get('sessions').list.getSnapshot(),也就是侧栏自己渲染的数据)合并起来,因此标题取自 displayTitle,浏览器端只认识一部分会话时也不会把宿主行挤掉,宿主列不出会话时面板也照样有会话可列。这个存储由 dsh-api-session-controller 在插件 apply() 之后才提供,所以面板与覆盖层都会为它重试(每 500ms 一次,最多 40 次),而不是首次渲染拿不到就放弃。覆盖层向 /wsk-api/check?sessionId=…&path=… 查询当前占据主视图的会话,每个会话最多问一次,它的按钮只负责把你带到面板——改 key 只能由面板里的操作完成。
HTTP 接口(仅限回环)
| 方法 | 路径 | 用途 |
| GET | /wsk-api/state | 默认 ref 状态、工作区及其会话、覆盖项、失效标记 |
| GET | /wsk-api/resolve | 当前会话此刻解析到哪一层、哪个 ref |
| GET | /wsk-api/check | ?sessionId=…&path=… 只读判定:生效层级、key、失效标记、服务商不匹配、needsAttention |
| POST | /wsk-api/set | {scope: 'workspace' \| 'session', path \| sessionId, title, key, provider?} 绑定 key;{useDefault: true} 或空 key 为清除 |
| POST | /wsk-api/test | {scope, path \| sessionId \| ref}(或 {key})真发一次请求并返回判定;invalid 打标记,ok 清标记 |
| POST | /wsk-api/clear-flag | {ref} 或一个目标,清掉失效/配额标记 |
只接受本机回环调用(127.0.0.1、::1、::ffff:127.0.0.1),且 Origin 必须同源或缺失。任何响应都不会包含明文 key,只有掩码。
工作区目标也接受不是注册工作区的目录;这类条目会作为「未分组目录」列在面板里,且只列侧栏真的会显示的目录——一个目录里若只有「刚建好、一句话都没发过」的空会话,侧栏不会显示它(空会话里只有当前打开的那个算数),面板也不会列。
安装
插件被市场收录后,可以直接在「设置 → 插件市场」里一键安装;也可以手动装:
在 profile 目录里,例如 ~/.dsh/profiles/desktop
pnpm add "dsh-workspace-api-key@github:COH2357/dsh-workspace-api-key"
然后把 "dsh-workspace-api-key" 加进该 profile package.json 的 dsh.profile.bundles,重启 DSH。本地开发用 link 代替:
"dependencies": { "dsh-workspace-api-key": "link:/path/to/dsh-workspace-api-key" }
测试
node test/host.test.mjs # 136 条断言
node test/client.test.mjs # 145 条断言
两个套件都不需要启动 DSH。宿主套件用一个假 ctx(假的 credentials、workspaceRegistry、agents、sessionController、sessions、webServer,以及打桩的 fetch)驱动 apply(),覆盖 ref 派生、会话→工作区→默认的级联、工作区匹配、把第二个适配器的 apiKeyEnv 一起重定向、清回默认、401/402/429/5xx 的判定、回环与来源校验、状态落盘,以及会话探针(含 {items} 信封与 live 兜底)。浏览器套件通过一个极小的 window.__ModuleLoader__ 与自制 React 运行时加载 lib/client.js,渲染出面板与覆盖层,断言槽注册、首屏渲染、会话折叠/展开、会话级保存与测试、宿主列不出会话时从浏览器端存储恢复会话(标题取 displayTitle、隐藏子代理会话与空会话、浏览器端只认识一部分会话时不挤掉宿主行)、会话列表服务晚于插件提供时的重试、未分组目录卡片、失效与不匹配提醒、「去配置」的交接、没有会话列表时的降级,以及 ctx.get('layout') 在插件 apply 之后才可用时返回键仍然有效。
要求与限制
- 已在 DSH Desktop 2.0.17(@deepseek-ai/dsh 0.2.0-rc.2、@deepseek-ai/cordis 4.0.4)上验证。插件没有运行时依赖,也不 import 任何 @deepseek-ai/ 包,只用宿主服务(credentials、workspaceRegistry、agents、sessionController、webServer、llm、settings)与 Node 内置模块。
- 每一层只有一把 key:一个会话无论被哪个 provider 路由读取,用的都是同一把 key;key 记下的服务商与会话当前服务商不一致时会被报为「不匹配」,但同一服务商内换模型不算不匹配,因为 DeepSeek key 是账号级的。
- 会话按目录(cwd)归入工作区。宿主自己的 list() 会跳过从未存过 cwd 的历史会话,而 live 兜底只认识当前装载中的会话,所以面板列出的会话可能比侧栏少;只在浏览器端存储里可见的会话,除了侧栏知道的那个 cwd 之外没有别的路径信息。
- 「测试连接」说的是 Anthropic Messages 协议(POST <baseURL>/messages 带 x-api-key 与 anthropic-version: 2023-06-01),也就是 DeepSeek 路由用的协议;换了别的协议的 provider 一样可以按层绑 key,只是测试可能把有效的 key 报成失败。
- key 通过凭据服务存放在 $DSH_HOME/.credentials.yaml 的 refs: 里,明文,和默认 key 完全一样。它不会被写进会话日志、插件状态文件或插件目录。
- 匹配是规范化之后的文本比较。如果某个会话的 cwd 是指向已注册工作区路径的符号链接或 junction,则匹配不上,会走上层层级。
- 卸载插件不会删除已生成的 _WS_ / _SS_ ref,可在「设置 → 模型」里清掉。
- 如果面板列出了工作区却没有可展开的会话,请看面板底部的诊断行。出现红色「宿主端插件还是旧版本」横幅,说明 DSH 进程没有重启过:宿主半边只在启动时加载,关窗口和刷新页面都不算——请完全退出 DSH Desktop 再打开。其余情况诊断行会写明宿主看到多少个会话、会话列表来自哪个来源(sessionController、live 兜底,还是浏览器端存储);一个都对不上时,还会并排给出会话 cwd 样本与工作区路径样本,便于比对。
许可
MIT预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
COH2357/dsh-workspace-api-key
一个Deepseek Harness插件,可以为每一个工作区配置独立的Api Key
相关插件 · 模型接入
API 中继安全审计toby-bridges/api-relay-audit
面向 AI API 中转与 LLM 代理的本地安全审计。
★ 897已汉化DSH
69.4
免费搜索插件DDDMUC/dsh-free-search
DeepSeek Harness 免费搜索插件 —— 无需 API key,零成本,多引擎可切换。 一个给…
★ 761已汉化DSH
68.7
免费联网搜索liustack/modsearch
在官方 App 里模型能联网,切到 API 就不能了。ModSearch 把联网补回来:网页搜索、X…
★ 863已汉化DSH
68.5
OpenCode 免费模型FishBottle7/opencode2dsh
在 DSHDeepSeek Harness里原生使用 OpenCode Zen 的免费匿名模型。
★ 379已汉化DSH
67.8
AI 模型网关tingly-dev/tingly-box
Tingly Box Web UI 演示
★ 373已汉化DSH
67.4
WorkBuddy 账号池XDTrees/dsh-xdpool
把你能白嫖的模型额度接进 DSH 同一个池:WorkBuddy 多账号自动容错、十三家扫码登录、76…
★ 359已汉化DSH
67.1