dsh web通用工具箱插件,纯AI制作包括仓库,零人工含量,可能不会维护,请谨慎使用。
30.1/100
综合分
1
GitHub 星标
426
npm 周下载
—/5
用户评分
数据截至 2026/10/7 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add dsh-toolsnpm 源 · dsh-tools 的发布者账号已校验与本仓库一致
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · tool
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 34 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查✓ 自动检查通过展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✓npm 包dsh-tools @ 1.1.5
✓Node 引擎要求 >=20 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/7 14:40:47
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 65 处,展示前 62 条)
- 读取本地文件lib/index.js:56
if (existsSync(configPath())) stored = JSON.parse(readFileSync(configPath(), "utf8")); - 读取本地文件lib/index.js:56
if (existsSync(configPath())) stored = JSON.parse(readFileSync(configPath(), "utf8")); - 写入本地文件lib/index.js:88
mkdirSync(dirname(path), { recursive: true }); - 写入本地文件lib/index.js:91
copyFileSync(path, `${path}.bak`); - 写入本地文件lib/index.js:93
writeFileSync(path, JSON.stringify(config, null, 2) + "\n"); - 写入本地文件lib/features/restart-web.js:148
mkdirSync(dataDir, { recursive: true }); - 写入本地文件lib/features/restart-web.js:166
writeFileSync(files.capture, JSON.stringify({ at: new Date().toISOString(), node, args, cwd, port: checkPort }, null, 2) + "\n"); - 删除本地文件lib/features/restart-web.js:173
rmSync(files[key], { force: true }); - 写入本地文件lib/features/restart-web.js:177
writeFileSync(files.ps1, ps1Content); - 写入本地文件lib/features/restart-web.js:178
writeFileSync(files.cmd, cmdContent); - 执行外部命令固定命令lib/features/restart-web.js:190
const child = spawn("explorer.exe", [files.cmd], { stdio: "ignore", windowsHide: true }); - 写入本地文件lib/features/restart-web.js:195
writeFileSync(files.error, "explorer dispatch failed: " + String((error && error.message) || error)); - 读取本地文件lib/features/delete-chat.js:47
const text = await readFile(SIZE_CACHE_FILE(), "utf8"); - 写入本地文件lib/features/delete-chat.js:62
mkdirSync(pluginsDataDir(), { recursive: true }); - 写入本地文件lib/features/delete-chat.js:63
await writeFile(SIZE_CACHE_FILE(), JSON.stringify({ sessions: sizeCache }, null, 2), "utf8"); - 读取本地文件lib/features/delete-chat.js:185
entries = await readdir(current, { withFileTypes: true }); - 读取本地文件lib/features/delete-chat.js:199
const info = await stat(full); - 读取本地文件lib/features/delete-chat.js:295
const [dirStat, fileStat] = await Promise.all([stat(dir), stat(path)]); - 读取本地文件lib/features/delete-chat.js:306
const [dirStat, fileStat] = await Promise.all([stat(dir), stat(path)]); - 写入本地文件lib/features/delete-chat.js:417
mkdirSync(dirname(scriptPath), { recursive: true }); - 写入本地文件lib/features/delete-chat.js:418
writeFileSync(scriptPath, OPEN_FOLDER_PS1, "utf8"); - 读取本地文件lib/features/plugin-toggle.js:50
return JSON.parse(readFileSync(path, "utf8")); - 写入本地文件lib/features/plugin-toggle.js:56
copyFileSync(path, `${path}.bak`); - 读取本地文件lib/features/plugin-toggle.js:70
return existsSync(patchPath()) ? readFileSync(patchPath(), "utf8") : ""; - 读取本地文件lib/features/plugin-toggle.js:70
return existsSync(patchPath()) ? readFileSync(patchPath(), "utf8") : ""; - 写入本地文件lib/features/plugin-toggle.js:177
writeFileSync(path, text.trimEnd() + "\n"); - 读取本地文件lib/features/plugin-toggle.js:209
if (!existsSync(path)) throw new Error("profile package.json 不存在"); - 写入本地文件lib/features/plugin-toggle.js:218
writeFileSync(path, JSON.stringify(manifest, null, 2) + "\n"); - 读取本地文件lib/features/plugin-toggle.js:226
const manifest = existsSync(manifestPath()) ? readJson(manifestPath()) : {}; - 读取本地文件lib/features/update-plugin.js:61
if (existsSync(bundled)) return { file: process.execPath, prefix: [bundled], shell: false }; - 执行外部命令来自配置/变量lib/features/update-plugin.js:83
const child = spawn(cmd.file, [...cmd.prefix, ...args], { - 读取本地文件lib/features/update-plugin.js:131
return JSON.parse(readFileSync(path, "utf8")); - 读取本地文件lib/features/update-plugin.js:166
const manifest = existsSync(manifestPath()) ? readJson(manifestPath()) : {}; - 读取本地文件lib/features/update-plugin.js:372
if (!existsSync(path)) return; - 写入本地文件lib/features/update-plugin.js:382
writeFileSync(path, JSON.stringify(manifest, null, 2) + "\n"); - 读取本地文件lib/features/plugin-catalog.js:71
if (!existsSync(join(profileRoot, "package.json"))) return {}; - 读取本地文件lib/features/plugin-catalog.js:72
const manifest = JSON.parse(readFileSync(join(profileRoot, "package.json"), "utf8")); - 读取本地文件lib/features/harness-check.js:28
if (!existsSync(packageJsonPath)) return null; - 读取本地文件lib/features/harness-check.js:29
const pkg = JSON.parse(readFileSync(packageJsonPath, "utf8")); - 执行外部命令来自配置/变量lib/features/harness-check.js:54
? spawnSync(process.env.ComSpec || "cmd.exe", ["/d", "/s", "/c", "npm root -g"], { encoding: "utf8", windowsHide: true }) - 执行外部命令固定命令lib/features/harness-check.js:55
: spawnSync("npm", ["root", "-g"], { encoding: "utf8" }); - 执行外部命令来自配置/变量lib/features/harness-check.js:65
? spawnSync(process.env.ComSpec || "cmd.exe", ["/d", "/s", "/c", "dsh --version"], { encoding: "utf8", windowsHide: true }) - 执行外部命令固定命令lib/features/harness-check.js:66
: spawnSync("dsh", ["--version"], { encoding: "utf8" }); - 读取本地文件lib/features/wechat-openclaw.js:115
entries = readdirSync(d, { withFileTypes: true }); - 读取本地文件lib/features/wechat-openclaw.js:124
total += statSync(full).size; - 读取本地文件lib/features/wechat-openclaw.js:136
if (!existsSync(root)) return []; - 读取本地文件lib/features/wechat-openclaw.js:148
if (existsSync(root)) { - 读取本地文件lib/features/wechat-openclaw.js:149
for (const entry of readdirSync(root, { withFileTypes: true })) { - 删除本地文件递归lib/features/wechat-openclaw.js:151
rmSync(join(root, entry.name), { recursive: true, force: true }); - 读取本地文件lib/features/wechat-openclaw.js:166
if (!existsSync(target)) return { ok: false, error: "not-found", message: "文件不存在" }; - 发起网络请求lib/features/github-ref.js:97
return await fetch(GITHUB_API_BASE + path, { headers, signal: controller.signal }); - 发起网络请求lib/features/github-ref.js:168
const response = await fetch( - 发起网络请求lib/features/github-ref.js:194
const response = await fetch( - 读取本地文件lib/features/usage-daily.js:189
entries = await readdir(dir, { withFileTypes: true }); - 读取本地文件lib/features/usage-daily.js:207
const text = await readFile(cacheFilePath(), "utf8"); - 写入本地文件lib/features/usage-daily.js:218
await mkdir(dirname(cacheFilePath()), { recursive: true }); - 写入本地文件lib/features/usage-daily.js:219
await writeFile(cacheFilePath(), JSON.stringify(cache), "utf8"); - 读取本地文件lib/features/usage-daily.js:266
st = await stat(file); - 读取本地文件lib/features/usage-daily.js:281
const buffer = await readFile(file); - 执行外部命令固定命令lib/wechat/vendor/weixin/run-lock.js:34
const res = spawnSync('ps', ['-p', pid, '-o', 'command='], { encoding: 'utf8' }); - 发起网络请求lib/wechat/vendor/weixin/api/api.js:251
const res = await fetch(url.toString(), { - 发起网络请求lib/wechat/vendor/weixin/api/api.js:320
const res = await fetch(url.toString(), {
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/dsh-agent@deepseek-ai/dsh-cmdline@deepseek-ai/dsh-llm@deepseek-ai/dsh-session@deepseek-ai/dsh-tools@deepseek-ai/cordis给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
最近更新
在 GitHub 查看全部 →v1.1.22026-09-08
dsh-tools v1.1.2
6533fbb dsh-tools v1.1.2: 兼容 DSH 0.1.3-alpha.2(微信流式回复修复 + devDependencies 对齐)
原文(未汉化)
v1.1.12026-09-04
dsh-tools v1.1.1
d0bf905 dsh-tools v1.1.1: 兼容 DSH 0.1.2-rc.1(会话读取 API 迁移 + devDependencies 对齐)
原文(未汉化)
v1.1.02026-08-31
dsh-tools v1.1.0
b3d8bd1 v1.1.0: 兼容 DSH 0.1.2-alpha.2,移除界面增强功能
数据来自仓库的 GitHub Release,可能与插件实际版本不一致。
README
由 DeepSeek 最新模型翻译生成dsh-tools
DSH web 插件:个人通用工具箱。一个插件收纳多个功能/工具想法,设置页(设置 → dsh 工具箱)采用页签式导航:「功能开关」页签顶部为 DeepSeek Harness 版本检查、一键重启(常驻,强制开启无开关)与「任务完成提示」卡片(授权与开关合一:未授权时显示授权按钮,授权完成后在卡片内展示启用/停用开关),下方为可选功能的开关列表;每个已启用的可选功能一个页签入口(页签超出宽度时可按住左右拖动查看);开关即时生效并持久化(重启后保留)。
⚠️ 使用提示:本插件纯 AI 制作,无人工含量,可能后续不会对其进行维护,请谨慎使用。
当前功能
| key | 功能 | 说明 | 默认 |
| notify.task-done | 任务完成提示 | 当前对话任务完成且网页未聚焦时,在 Windows 桌面右下角弹出系统提示框(置顶),点击跳回会话;开关关闭时不监听、不弹提示 | 开 |
| harness.check | DeepSeek Harness 版本检查 | 「功能开关」页签顶部卡片:检查 DeepSeek Harness 当前版本与 GitHub 最新 Release/tag,仅检查不升级;每次 dsh web 启动后仅首次打开时自动检查,之后手动点「重新检查」 | 强制开启(无开关) |
展开完整文档(README 剩余 1 节)
dsh-tools
DSH web 插件:个人通用工具箱。一个插件收纳多个功能/工具想法,设置页(设置 → dsh 工具箱)采用页签式导航:「功能开关」页签顶部为 DeepSeek Harness 版本检查、一键重启(常驻,强制开启无开关)与「任务完成提示」卡片(授权与开关合一:未授权时显示授权按钮,授权完成后在卡片内展示启用/停用开关),下方为可选功能的开关列表;每个已启用的可选功能一个页签入口(页签超出宽度时可按住左右拖动查看);开关即时生效并持久化(重启后保留)。
⚠️ 使用提示:本插件纯 AI 制作,无人工含量,可能后续不会对其进行维护,请谨慎使用。
当前功能
| key | 功能 | 说明 | 默认 |
| notify.task-done | 任务完成提示 | 当前对话任务完成且网页未聚焦时,在 Windows 桌面右下角弹出系统提示框(置顶),点击跳回会话;开关关闭时不监听、不弹提示 | 开 |
| harness.check | DeepSeek Harness 版本检查 | 「功能开关」页签顶部卡片:检查 DeepSeek Harness 当前版本与 GitHub 最新 Release/tag,仅检查不升级;每次 dsh web 启动后仅首次打开时自动检查,之后手动点「重新检查」 | 强制开启(无开关) |
| restart.web | 一键重启 dsh web | 「功能开关」页签顶部按钮:重启服务并自动打开新窗口,旧页面自动关闭(开发测试快循环) | 强制开启(无开关) |
| delete-chat | 会话管理 | 归档会话查看、单条/批量删除会话;列表显示每个会话与工作区占用的磁盘空间;v1.0.0 起先快速返回列表再后台补齐大小,并对目录大小做磁盘缓存,打开更快;删除会话页点击工作区路径可打开对应文件夹 | 开 |
| plugin-toggle | 插件开关 | profile 已安装插件的启用/停用开关;点击插件名可跳转其 GitHub 页(有则显示),行内展示插件功能描述 | 开 |
| update-plugin | 更新检查 | 检查/更新/卸载 profile 已安装插件;支持 npm 注册表与 GitHub(github: / git+https://github.com/... / URL spec,Releases/tags API 探测)安装来源;点击插件名可跳转其 GitHub 页(有则显示);每次 dsh web 启动后仅首次打开该页签时自动检查,之后需手动点「重新检查」 | 开 |
| plugin-catalog | 插件分类视图 | 「设置 → 插件」新增「插件分类」页签:官方(安装 Harness 自带)/ 已安装(插件市场 / GitHub / npm)/ 本地(link:/file: 开发)三个分类筛选浏览;开关关闭时页签自动消失 | 开 |
| ui.usage | 应用用量 | 「应用用量」页签:按时间跨度(今年 / 本月 / 近 7 天 / 近 3 天 / 自定义日期)与模型过滤聚合各会话用量(Token、缓存命中、时长、会话 / 步数);趋势柱图优先读取会话日志按自然日统计真实 usage(磁盘缓存 + 增量扫描),悬停显示具体数据,会话用量列表展示 Token / 命中率 / 估算费用;支持价格配置,v1.0.0 起费用卡片可直接切换峰 / 谷价格(默认谷价) | 关 |
| wechat.openclaw | 微信接入(OpenClaw) | 扫码绑定个人微信,通过腾讯 openclaw-weixin / iLink 协议与 DSH Agent 文字聊天;支持白名单、room / per-user 会话模式、网关启停;v1.0.0 起页签内“使用说明”可展开 / 折叠 | 关 |
融合功能与参考来源
融合了开源插件的功能(均 MIT 许可,源码文件头与下方条目标注来源;融合版默认关闭,开启后行为与上游一致,但配置存 dsh-tools 自身的 featureConfig,设置入口统一在「dsh 工具箱」内):
| 功能 | 来源 | 许可 |
| ui.usage | yoli-mi/dsh-client-ui-custom | MIT(Copyright (c) 2026 Yoli-mi) |
说明:ui-custom 的 appearance(外观)、shortcuts(快捷键)、 marketplace(插件市场)模块未融合;ui.enhance(Markdown 渲染 + 浮动历史条)自 v1.1.0 起移除,与 Harness 自带功能定位重复。
v1.1.0 更新
- 更新兼容 DeepSeek Harness 0.1.2-alpha.2(devDependencies 对齐到 0.1.2-alpha.2)。
- 删除「界面增强」(ui.enhance)功能:用户消息 Markdown 渲染 + 浮动历史条,与 Harness 自带功能定位重复。
v1.1.1 更新
- 更新兼容 DeepSeek Harness 0.1.2-rc.1(devDependencies 对齐到 0.1.2-rc.1)。
- 微信接入的 AgentBridge 适配宿主会话读取 API:宿主已移除 Session.events,改为 session.snapshotEvents() 读取事件流(lib/wechat/vendor/bridge.js)。微信 AI 回复要求宿主提供该 API(DSH 0.1.2-alpha.4 及以上);更老宿主上该功能不可用。
- 应用用量口径实证(rc.1 会话日志多代采样):inputTokens + outputTokens + cacheReadTokens ≡ totalTokens,宿主不单列 cache-write 用量,现有聚合数值精确,无需改动。
v1.1.2 更新
- 更新兼容 DeepSeek Harness 0.1.3-alpha.2(devDependencies 对齐到 0.1.3-alpha.2)。
- 修复微信接入在 0.1.3-alpha.1 及以上宿主上回复为空:宿主取消了顶层 assistant/chunk 会话事件(Session format v2,流改嵌入 assistant/message.data.stream),实时增量改由 agent 作用域事件 agent/assistant-stream 的 start / chunk / end 帧发布。AgentBridge 改为订阅该帧通道,并保留旧宿主(≤ 0.1.2)的 assistant/chunk 兼容订阅(两通道互斥,双订阅不重叠)。
- 新增增量兜底:宿主一个文本增量都没发布时,把 assistant/message 聚合出的回复整体交给发送器 —— 调用方只从 onDelta 取文本,缺这条兜底会「静默空回复」。
- test/wechat-openclaw-smoke.mjs 新增 bridge 流式通道回归(v2 帧 / 旧信封 / 无增量兜底 / 订阅注销);该套件此前对流式路径零覆盖,正是破坏能通过自检的原因。
v1.1.5 更新
- 更新兼容 DeepSeek Harness 0.2.0-rc.2(devDependencies 对齐到 0.2.0-rc.2;宿主 0.1.7-rc.2 → 0.2.0-rc.2 为跨 minor 升级,逐触点核对后确认无破坏性变更命中本插件)。
- 修复文生图工具 generate_image 静默注册失败:宿主 tools.register() 强制要求 output{schema,render},且 parameters 必须是「紧凑参数表」而非已编译的 JSON Schema;旧写法两项都不符,register() 抛 TypeError 后被本插件自己的 try/catch 吞掉,表现为「配置了文生图但 Agent 永远调不到工具、界面无任何提示」。现改用宿主导出的 defineTool() 统一生成定义(与 lib/wechat/vendor/weixin/gateway.js 写法一致),并把该 catch 的日志从 api.log 提升为 console.error 且写明后果,不再静默。
- test/wechat-openclaw-smoke.mjs 新增 generate_image 定义形状回归:走真实 register() 路径截获定义,断言 output{schema,render} 存在、parameters 为编译后的 JSON Schema、render 输出内容块,并用宿主导出的 validateArgs / validateJsonSchemaValue 做正反双向校验(旧形状必须被宿主拒绝,否则用例失去意义)。
- 依赖声明补全:运行时消费的宿主包(dsh-agent / dsh-llm / dsh-session / dsh-tools)加入 peerDependencies( + peerDependenciesMeta.optional,可选以免在非宿主环境安装时报错);@deepseek-ai/dsh-cmdline 补入 devDependencies,消除 lib/wechat/vendor/weixin/ 下两个不可达文件对未声明依赖的裸引用。
- 修复应用用量数据停止更新(2026-09-10 实测):宿主把会话日志升级为「格式世代」命名 session[.vN].jsonl[.zstd],旧口径只认字面量 session.jsonl.zstd,导致带版本号的日志(实测 37 个)全部扫不到,磁盘缓存与实际用量冻结在升级当天。判定口径收敛到 lib/features/session-log.js,usage-daily 扫描与 delete-chat 删除共用同一条规则。
- 0.2.0-rc.2 实测 SESSION_FORMAT_VERSION 仍为 4(与 0.1.7-rc.2 相同,未产生新世代),该正则继续覆盖,无需再改。
- 修复会话管理无法删除新格式会话:sessionDirOf() 同款字面量口径会让带版本号的日志直接返回 bad-location。
- test/smoke.mjs 补回归:世代命名日志的目录大小、删除路径,以及文件名判定表的正反用例(含迁移临时文件 session.migration..tmp 必须被拒)。
- client-smoke 的 React 解析新增本包 devDependencies 兜底(profile 里没有 React 时不再整份失败);React / react-dom 因此进入 devDependencies。
依赖解析提示:@deepseek-ai/dsh-agent 等包把 dsh-llm / dsh-session / dsh-scope 等声明为精确版本 peer,因此升级 devDependencies 后必须删除 package-lock.json 与 node_modules 重装;沿用旧锁文件会因旧树的 peer 范围(^0.1.5-rc.1)无法接受新版本而报 ERESOLVE。
已知边界:lib/wechat/vendor/weixin/ 下 15 个文件(含 entry.js、gateway.js、driver.js、login-qr.js 等)不在任何运行路径上(对 lib/index.js 做完整 ESM 可达性遍历确认),属迁移遗留的参考代码。本版只保证 gateway.js 可正常 import;entry.js 仍需额外安装其传递依赖 commander 才能加载,因不可达故未处理。
v1.0.0 更新
- 一键重启 dsh web 后不再刷新旧页面,改为自动打开新窗口并关闭旧页面。
- 会话管理加载优化:先快速返回列表再后台补齐磁盘占用,并对目录大小做磁盘缓存。
- 界面增强中 Markdown 渲染新增独立开关;修复 @文件引用 后紧跟中文时后续文字被一起高亮的问题。
- 应用用量底部提示文案更新;费用卡片新增峰 / 谷价格一键切换,默认按谷价计算。
- 微信接入页签的“使用说明”改为可展开 / 折叠。
- 修复 client-smoke 因 React 与 react-dom/server 版本不一致导致的 server-render 失败。
安装
dsh-tools 是 DSH web profile 的常驻插件(bundle 插件)。傻瓜式安装,一条命令:
dsh plugin --profile web add dsh-tools
该命令自动完成:依赖安装(走 npm 官方源分发)+ 激活层写入(dsh.profile.bundles)。
执行后重启 dsh web,从 设置 →「dsh 工具箱」管理各功能开关。
提示:裸 pnpm add / npm i 只安装依赖、不会激活插件(依赖 ≠ 激活);激活靠 dsh.profile.bundles 列表,dsh plugin add 会自动写入。
已装有 dsh-tools 且依赖 spec 为 github: 形式的环境,更新检查页签会通过 GitHub Releases/tags API 自动检测本仓库新版本并一键更新(更新会固定到 #tag)。
配置
私有 JSON:<DSH_HOME>/profiles/web/plugins-data/dsh-tools.json(首次修改时自动生成,写入前自动备份 .bak)。结构为 { "features": { "<key>": true|false }, "featureConfig": { "<key>": {...} } }:缺失的 key 一律回落到功能默认值(带默认配置的功能,其 featureConfig 在读取时自动与模块 defaultConfig 合并)。
微信接入(OpenClaw)
wechat.openclaw 是可选功能(默认关),启用后会在「dsh 工具箱」出现「微信接入」页签:
- 扫码登录个人微信(复用腾讯 openclaw-weixin / iLink 协议层)。
- 微信文字消息会进入 DSH Agent 会话,Agent 的回复会发回微信。
- 白名单为空时也可以启动网关(仅记录模式),所有消息会被拦截并在「最近发送者 ID」中记录;配置白名单(每行一个微信 ID)后重启网关即可放行。
- 会话模式:room(所有微信用户共享一个 DSH 会话)或 per-user (每个微信用户独立会话)。
- 微信凭据保存在用户主目录的 ~/.openclaw/openclaw-weixin/accounts/,聊天记录仍由 DSH 会话持久化保存,不写入 dsh-tools 配置。
注意:同一微信账号同时只能有一个轮询网关;如果该账号已被 OpenClaw / hermes-agent 等其他程序占用,启动会因实例互斥失败。
微信媒体能力
- 图片 / 视频 / 文件收发:不需要外接模型。微信图片/文件会下载到
~/.openclaw/weixin-dsh/media/inbound/{images,videos,files,voice}/,
Agent 回复中写 [image:路径] / [video:路径] / [file:路径] 即可发送。
- 语音转文字(ASR):需要 OpenAI 兼容 ASR 接口,配置 AI_ASR_BASE_URL / AI_ASR_KEY / AI_ASR_MODEL(默认 SenseVoiceSmall),或全局 AI_GATEWAY_BASE_URL / AI_GATEWAY_KEY。
- 图像理解(Vision):需要 OpenAI 兼容视觉接口,配置 AI_VISION_BASE_URL / AI_VISION_KEY / AI_VISION_MODEL(默认 deepseek-v4-flash-vision-exp,即 DeepSeek 官方多模态视觉模型;使用第三方网关时可改为自己的模型名)。
未配置时,如果已安装 @liustack/modlens,微信图片会自动提示 Agent 使用 modlens_read_image 读取。
- 文生图(Image):需要 OpenAI 兼容图像生成接口,配置 AI_IMAGE_BASE_URL / AI_IMAGE_KEY / AI_IMAGE_MODEL(默认 gpt-image-2)。
配置后 dsh-tools 会注册 generate_image 工具,Agent 可以主动画图并发给微信。
- 以上 AI 凭据统一从环境变量或 ~/.openclaw/weixin-dsh/.env 读取(权限 0600)。
- 「微信接入」页签的 AI 能力 下拉框内:
- 显示当前 AI 能力配置状态;
- 提供 Base URL / API Key / Model 表单,可直接保存到 ~/.openclaw/weixin-dsh/.env;
- 内置示例配置说明。
- 页签还提供媒体缓存路径列表与「清理聊天文件缓存」按钮。
示例 ~/.openclaw/weixin-dsh/.env:
AI_ASR_BASE_URL=https://your-gateway/v1
AI_ASR_KEY=sk-xxx
AI_ASR_MODEL=SenseVoiceSmall
AI_VISION_BASE_URL=https://api.deepseek.com/v1
AI_VISION_KEY=sk-xxx
AI_VISION_MODEL=deepseek-v4-flash-vision-exp
AI_IMAGE_BASE_URL=https://your-gateway/v1
AI_IMAGE_KEY=sk-xxx
AI_IMAGE_MODEL=gpt-image-2
也可以只配一组全局:
AI_GATEWAY_BASE_URL=https://your-gateway/v1
AI_GATEWAY_KEY=sk-xxx
参考来源
微信接入的协议层与部分媒体逻辑参考/改写自以下开源项目(MIT 许可):
- shaodushu/dsh-weixin-gateway —— 微信消息网关 dsh 插件:复用腾讯 openclaw-weixin 协议层,dsh 作为执行层
- Tencent/openclaw-weixin —— 腾讯微信渠道插件(协议/接口参考)
dsh-tools 已将所需代码迁入 lib/wechat/vendor/,不再把 dsh-weixin-gateway 作为运行时依赖。
传输协议安全
- 与微信 iLink 服务通信统一使用 HTTPS(https://ilinkai.weixin.qq.com 等)。
- 微信 bot token 只保存在本机 ~/.openclaw/openclaw-weixin/accounts/,不写入 dsh-tools 配置、不进入 git。
- 日志与 API 返回中对 token 做脱敏,不输出完整凭据。
- 媒体下载/上传走微信 CDN,涉及加密媒体时使用 AES 解密/加密;媒体文件只保存在本机 ~/.openclaw/weixin-dsh/media/。
- 所有 dsh-tools 本地 API 继续沿用同源 + 信任围栏(api.fence),非回环/未授权来源会被拒绝。
- AI 能力凭据(AI_)只写入权限 0600 的 ~/.openclaw/weixin-dsh/.env,不进入插件配置或 git。
宿主 API(同源 + 信任围栏,POST 除注明外)
框架路由:
- POST /dsh-tools/api/config — 配置快照(全部功能的元数据 + 开关 + featureConfig)
- POST /dsh-tools/api/config/set {key, enabled} — 改开关,写盘并热应用
- POST /dsh-tools/api/config/feature {key, config} — 写某功能的配置项(与模块默认值合并后写盘;客户端据此实时渲染)
- POST /dsh-tools/api/ping — 健康检查(客户端重启探测用)
- POST /dsh-tools/api/restart — 重启 dsh web(restart.web 启用时)
- POST /dsh-tools/api/harness-check — DeepSeek Harness 版本检查(harness.check 启用时;仅检查,不升级)
- POST /dsh-tools/api/plugin-catalog — 插件分类投影:loader 条目 + 来源分类(plugin-catalog 启用时;分类规则见 lib/features/plugin-catalog.js)
- POST /dsh-tools/api/usage/daily — 按自然日聚合真实 usage(ui.usage 启用时;读取会话日志,带磁盘缓存 + 增量扫描)
- GET /dsh-tools/api/events — SSE 推送(notify.task-done 启用时)
合并功能路由(对应功能启用时注册):
- POST /dsh-tools/delete-chat/api/{list,delete}
- POST /dsh-tools/plugin-toggle/api/{list,set}
- POST /dsh-tools/update-plugin/api/{check,update,uninstall}
- POST /dsh-tools/wechat.openclaw/api/{status,login/start,login/poll,login/verify,login/cancel,gateway/start,gateway/stop,account/logout,media/list,media/clean,media/open,ai/config}
SSE 消息格式:data: {"type":"turn-done","data":{"sessionId":"..."}}。
应用用量按天统计说明
- 趋势柱状图优先读取会话日志(<DSH_HOME>/sessions/*/session[.vN].jsonl.zstd)中的真实 assistant/message usage,按请求实际发生日期聚合,而不是把整个会话累计值记到最后活跃日期。
- 日志文件名带「格式世代」版本段(宿主 0.1.5 起写入 session.v3.jsonl.zstd,旧的无版本 session.jsonl.zstd 停在原地不再更新),判定口径收敛在 lib/features/session-log.js,供本功能与会话管理共用;只扫 .zstd(明文日志没有 zstd 帧,走不了这条解压管线)。
- 首次请求会全量扫描并写入磁盘缓存;后续只对 size/mtime 变化的日志增量重扫。
- 缓存文件:<DSH_HOME>/profiles/web/plugins-data/dsh-tools-usage-daily.json。
- 费用按模型分别计价后求和;悬停柱状图可查看该日期的 Token、会话数、命中率与估算费用。
- 费用卡片支持峰 / 谷价格一键切换,默认按谷(空闲)价计算;价格配置面板仍可手工调整价格表。
新增一个「工具想法」
1. 在 lib/features/ 下新建 <key>.js:
export const key = "my.idea"; // 唯一 key,同时是开关存储键
export const label = "我的新功能"; // 设置页显示名
export const description = "一句话说明这个功能做什么";
export const defaultEnabled = true; // 首次启用的默认开关
export const kind = "tool"; // "tool"=模型工具 | "feature"=UI/服务类
// 注册逻辑;宿主在开关开启时调用,关闭时调用返回的 disposer。
// ctx 为宿主 Cordis 上下文;api 提供 config()/featureEnabled()/broadcast()/ // fence/writeOk/writeError/readJsonBody/log。
import { defineTool } from "@deepseek-ai/dsh-tools";
export function register(ctx, api) {
// 例:注册一个模型工具 const tools = ctx.get("tools");
if (tools === undefined) return () => {};
// ⚠️ 必须用宿主 defineTool() 包装,且三件套齐全,否则 register() 会抛错: // - parameters 用「紧凑参数表」({name:{type,required,description}}), // 不是已编译的 JSON Schema; // - output{schema,render} 是宿主强制字段; // - 记得包 try/catch 时别把错误吞掉 —— 静默失败会让工具凭空消失。js const dispose = tools.register(defineTool({ name: "my_tool", description: "…",
parameters: {
query: { type: "string", required: true, description: "查询内容" },
},
output: {
schema: { type: "string" },
render: (_args, value) => [{ type: "text", text: 结果:${value} }],
},
execute: async () => "ok",
}));
return () => dispose();
}
// 可选:贡献 POST 方法到 /dsh-tools/api/<方法名>
export const methods = {
"my/action"(req, res, api, payload) {
api.writeOk(res, { ok: true });
},
};
2. 在 lib/features/index.js 里 import 一行并加入 FEATURES 数组。
3. 重启 dsh web(用设置页「功能开关」页签顶部的一键重启按钮最快),新功能即出现在
dsh 工具箱设置页并带开关。
一键重启的实现说明
restart.web 捕获当前进程的 process.argv / env / cwd,落盘一个 PowerShell 延迟启动器(dsh-tools-restart-launcher.ps1 + 同名 .cmd),由 explorer.exe 分发执行——启动器链完全脱离服务器进程树,因此不受服务器所在 kill-on-close job 的连坐清除(直接由服务器派生子进程的方案实测会在 Start-Process 之前被连坐杀死)。启动器等待 2s 规避端口占用竞态后 Start-Process 拉起原命令,先回包、600ms 后退出当前进程;新窗口由重启流程自动打开;客户端轮询 ping,服务恢复后关闭旧页面,不再刷新旧页面。
关键实现细节(均由 test/restart-launcher-smoke.mjs 用真实生成器文本验证):
- 启动器以单字符串 -ArgumentList 传参并手工按 CommandLineToArgvW 规则加引号(Windows PowerShell 5.1 的数组形式不会给含空格元素加引号,会导致参数截断);try/catch 保持在单行(}; catch 是解析错误);
- 全流程取证落盘在 <DSH_HOME>/profiles/web/plugins-data/: dsh-tools-restart-capture.json(argv/env 快照)、-ran.log、 -ok.log、-failed.log、-restart.log(错误)、-port-up/down.log (端口存活探测)。新进程日志直接输出到它自己的控制台窗口。
仅支持 Windows;桌面端环境优先走 window.dshDesktop.restartService() 桥。
新进程会在一个独立的控制台窗口中运行(日志直接可见、可随时关闭)。依赖 explorer.exe 常驻(交互式桌面的常态)。若重启仍失败,把上述日志文件发来即可定位。
客户端构建
lib/client.js 是由 lib/client/ 下的源码片段构建生成的单文件客户端 bundle。修改 lib/client/ 后运行: sh
npm run build:client
发布到 npm / GitHub Release 时 prepack 会自动执行构建,确保 lib/client.js 与源码一致;github: / git+https 直装方式需要仓库中已提交构建后的 lib/client.js。
测试 sh
node test/smoke.mjs # 宿主框架:启动/配置热应用/SSE 管线/围栏/方法门控/featureConfig 路由/插件分类路由
node test/plugin-catalog-smoke.mjs # 插件分类:分类判定纯函数(scope/spec/余量桶/投影)
node test/client-smoke.mjs # 客户端 bundle:执行/槽位注册/初始渲染/提示判定/标签页模型/用量与外观纯函数
node test/mutations-smoke.mjs # profile 文件改写(plugin-toggle / update-plugin,假 profile)
node test/update-github-smoke.mjs # GitHub 安装来源:spec 分类/解析/版本探测/检查流程(假 profile)
node test/harness-check-smoke.mjs # DeepSeek Harness 版本检查:版本发现/比较/状态机(假 profile)
node test/restart-launcher-smoke.mjs # 一键重启启动器(真实生成器文本,无害载荷)
node test/explorer-dispatch-smoke.mjs # explorer 分发链(cmd→隐藏 powershell)
node test/restart-sequence-smoke.mjs # 真实 restart 方法:响应+自退出(一次性牺牲进程)
node test/wechat-openclaw-smoke.mjs # 微信接入:白名单/登录状态机/feature 元数据(不连真实微信)
十一个测试都不需要真实服务器,全部在临时目录下运行(通过临时 DSH_HOME 隔离;仅 client-smoke.mjs 以只读方式解析真实 profile 中的 react 与 react-dom/server 用于可选的服务端渲染,其余测试绝不触碰真实 profile)。
注意:restart-sequence-smoke.mjs 的"复活进程"阶段在 DSH agent 沙箱内无法完成 explorer 分发链而跳过——在普通终端运行该测试会完整断言整条重生链。
任务完成提示(桌面通知)说明
页面未聚焦时,任务完成提示优先使用浏览器的 Notification API —— Windows 会把它渲染成屏幕右下角置顶的系统提示框,点击回到会话。
首次使用需要在「dsh 工具箱」设置页点击一次「授权桌面通知」;浏览器必须保持打开(页面级通知不注册 Service Worker)。权限被拒时回退为页面内提示框(页面未聚焦时不可见)。Windows「专注助手」开启时系统可能吞掉通知。
已知边界
- 多标签页各自弹各自的任务完成提示;
- 子代理完成不提示(宿主按根 Agent 过滤);
- 桌面通知依赖浏览器打开并已授权(设置页有授权按钮);
- 重启按钮依赖当前进程以 dsh web 直接启动(npm 包装器等父子进程场景下重生的新窗口可能不受原包装器管理)。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
LoKiGGo/dsh-tools
dsh web通用工具箱插件,纯AI制作包括仓库,零人工含量,可能不会维护,请谨慎使用。
相关插件 · 工具 / 效率
破甲管控台kingcharleslzy-ai/dsh-purge
dsh-purge Community · DeepSeek Harness 社区维护版:宿主兼容、状态诊断、提示词管理、更新与本机备份回滚。基于小杨 / YuJunZhiXue 的 dsh-purge。
★ 4,330已汉化DeepSeek 客户端
74.5
网文长卷lingfengQAQ/webnovel-writer
基于 Claude Code 的长篇网文辅助创作系统,解决 AI 写作中的「遗忘」和「幻觉」问题,支持 200…
★ 7,636已汉化DSH
72.2
多智能体协作HKUDS/AutoSwarm
AutoSwarm: Unify Your Agents. Unify Your Context (Codex · Claude Code · DeepSeek Harness · Muse · Grok · WorkBuddy· nanobot · and more)
★ 2,349已汉化DSH
71.6
Vox 拼贴视频生成Alisa0808/vox-director
🎬 Vox Director拼贴动效导演
★ 2,129已汉化DSH
71.4
Agent 演化引擎Q00/ouroboros
智能体 OS:智能体自己变聪明,我们只守住底线:面试准入、分阶段评估、带预算的进化循环。MCP 服务器,14 种运行时:Claude Code、Codex CLI、Gemini CLI、OpenCode、Copilot、Kiro 等。
★ 6,311已汉化DSH
71.4
智能体运行框架路由HarnessRouter/harnessrouter
智能体 harness 的统一接口。
★ 3,984已汉化DSH
71.3
这是你的仓库?认领条目