dsh-web
zhu1090093659
DeepSeek Harness (DSH) Web 插件聚合生态 · 万物皆插件,通过创意工坊分发||DeepSeek Harness (DSH) Web Plugin Aggregation Ecosystem · Everything is a plugin, distributed via the Creative Workshop
PROJECT TOPICS
INSTALL REFERENCE
dsh plugin --profile web add github:zhangjianyu1006156/dsh-balance-display
该命令指向仓库当前默认分支;尚无绑定当前 commit 的完整验证结果。
PROJECT README
DeepSeek API 余额显示插件 —— 在 DSH Web GUI 的左侧栏底部实时显示 API Key 剩余额度,支持低余额预警、余额消耗趋势、一键充值。
密钥全程只在主机端:主机端通过 dsh 凭据服务读取 key 并查询 api.deepseek.com/user/balance,浏览器端只从本机回环路由拉取脱敏后的余额 JSON,密钥绝不进入浏览器。
余额 ¥92.12,点击刷新,悬浮显示充值/赠送拆分¥0.5842),清楚还剩几分钱platform.deepseek.com/usage# 桌面打包版:profile 名固定为 desktop
dsh plugin --profile desktop add dsh-balance-display
# npm 版 dsh web:profile 名固定为 web
dsh plugin --profile web add dsh-balance-display
本地开发模式(改完源码直接生效,无需重装):
dsh plugin --profile desktop add link:/path/to/dsh-balance-display
装完重启 dsh(宿主端路由改动需重启进程;纯客户端改动硬刷新浏览器即可)。侧边栏底部出现余额胶囊,设置页出现「余额显示」一栏。
注意
dsh web里web是应用名、不是 profile 名;想跑别的 profile 用dsh --profile <name> --port <port>。dsh plugin --profile <name> ...才是 profile 管理入口。
| 风险 | 对策 |
|---|---|
| Key 泄漏到浏览器 | Key 只在主机端 resolve 后用于余额请求的 Authorization 头;客户端只 fetch 本机路由;路由响应 schema 无 key 字段 |
| Key 泄漏到日志/错误 | 不写日志含 key 值;所有外发错误文本经 redact() 脱敏(sk-* / Bearer * → [redacted]),客户端二次脱敏兜底 |
| 客户端 bundle 携带 key | 客户端是纯静态渲染代码,不含任何凭据;安装后 grep 断言零匹配 |
| 路由被滥用 | 仅 GET(余额)与 GET/POST(announce 配置);dsh web 默认仅绑定 127.0.0.1;不加 CORS 头 |
| 上游数据 XSS | React 文本转义渲染,无 innerHTML |
| 上游卡死 | 请求 10s 超时;缓存 TTL 有界;并发请求共享一次上游调用 |
设置页「余额显示」tab:
| 项 | 说明 |
|---|---|
| 侧边栏显示余额角标 | 开关胶囊显示 |
| 自动刷新间隔(分钟) | 默认 10 |
| 低余额预警阈值(¥) | 默认 5 |
| 余额不足时浏览器通知 | 需授权通知权限 |
| Agent 协作 | 在系统提示中声明插件(实时同步到主机端) |
余额历史与偏好存于浏览器 localStorage(dsh.balanceDisplay.*),主机端不感知、不存储。
| DSH 版本 | 状态 |
|---|---|
0.2.0-rc.*(当前桌面版 / dsh web) |
✅ 支持(本版本起) |
0.1.0-rc.*(rc.5 / rc.6 / rc.7 / rc.8) |
需要用 0.1.0 版本,见下方说明 |
宿主协议本身没变(bundle 挂载、/plugins/<id>/client.js 服务、webServer 路由、credentials 服务都与旧版一致)。0.2.0 唯一破坏性变更在"客户端模块图":
@deepseek-ai/dsh-client-runtime 这个包在 0.2.0 线被移除了。槽位/渲染机制迁到 @deepseek-ai/dsh-client-ui-renderer(提供 slots 服务),i18n 迁到 @deepseek-ai/dsh-client-locale(提供 locale 服务)。require() 一个模块图里没有的包是致命错误:加载器直接抛
client-modules: require("...") missed the module table,整个插件激活失败,界面上不会出现胶囊、控制台里是这条报错。package.json 的 dsh.client.inject 必须只列当前模块图里真实存在的包:0.2.0 起为
["@deepseek-ai/dsh-client-ui-renderer", "@deepseek-ai/dsh-client-locale"]。排查同类问题的方法:打开页面源码搜索 __DSH_BOOT__,它后面跟着宿主下发的 boot graph(每个客户端插件一行)。把某行的 inject 逐个比对 entries[].id,缺哪个就是哪个包改名/移除了。
仓库里带了两个免启动浏览器的检查脚本,升级宿主后先跑一遍:
# 1) 客户端 bundle 能否按加载器规则加载并激活(不需要 dsh 在跑)
node tools/client-load-check.mjs lib/client.js
# 反向对照:必须失败,证明这个检查真的能抓到模块图漂移
node tools/client-load-check.mjs tools/fixtures/legacy-runtime-require.js
# 2) 清单里的 inject 与线上 boot graph 是否一致
node tools/boot-graph-check.mjs 'http://127.0.0.1:19387/?token=<启动时打印的 token>'
node tools/boot-graph-check.mjs --graph saved-boot-graph.json
client-load-check 用一个与 dsh-client-modules 同样严格的 require(缺失即抛错)来跑插件工厂,所以
@deepseek-ai/dsh-client-runtime 被移除这类改动会在本地直接暴露,而不是等用户打开界面才发现。
| 插件版本 | 目标宿主 |
|---|---|
0.1.1+ |
dsh 0.2.0-rc.* 及以上 |
0.1.0 |
dsh 0.1.0-rc.* |
dsh-balance-display/
├── package.json # dsh.bundle.patch + dsh.client 清单(inject 列表随宿主模块图演进)
├── cordis.patch.yml # 插件挂载行
├── lib/
│ ├── index.js # 主机端:余额路由 / config 路由 / 脱敏 / 缓存
│ └── client.js # 浏览器端:左下角胶囊 / 设置页 / i18n / 趋势图
└── tools/
├── client-load-check.mjs # 客户端 bundle 加载/激活检查(含反向对照 fixture)
└── boot-graph-check.mjs # 清单 inject 与线上 boot graph 一致性检查
发布新版本:
npm version patch # 或 minor / major
npm publish # 需输 2FA 动态码
MIT
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: billing、web-ui。