在会话内重启、更新并体检桌面应用
30/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/21 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add cheng-wj/dsh-app-control该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · desktop
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 14 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件
查看扫描证据(共 18 处,展示前 13 条)
- 读取本地文件src/index.js:171
const buf = readFileSync(file) - 读取本地文件src/index.js:189
if (!existsSync(file)) return - 读取本地文件src/index.js:192
const text = readFileSync(file, 'latin1').replace(/ /g, '\n').replace(/ /g, '\r\n') - 写入本地文件src/index.js:193
writeFileSync(file, text, 'latin1') - 写入本地文件src/index.js:203
mkdirSync(SCRIPT_DIR, { recursive: true }) - 写入本地文件src/index.js:204
mkdirSync(LOG_DIR, { recursive: true }) - 读取本地文件src/index.js:207
if (!existsSync(from)) continue - 写入本地文件src/index.js:209
copyFileSync(from, to) - 执行外部命令固定命令src/index.js:218
const child = spawn('powershell.exe', [ - 读取本地文件src/index.js:268
const files = readdirSync(LOG_DIR) - 读取本地文件src/index.js:271
.filter((f) => statSync(f).isFile()) - 写入本地文件src/index.js:293
mkdirSync(LOG_DIR, { recursive: true }) - 写入本地文件src/index.js:294
writeFileSync(join(LOG_DIR, 'apply-trace.log'), trace.join('\n') + '\n', 'utf8')
扫描于 2026/11/3(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
DSH 插件:在模型侧重启、更新、检查 DeepSeek Harness 桌面应用(Windows)
README
由 DeepSeek 最新模型翻译生成dsh-app-control
在 DSH 会话内向模型提供三个工具,用来重启、更新和体检 DeepSeek Harness 桌面应用本身。
核心卖点不是「能重启」,而是重启不会把自己弄死。这件事比看上去难:从 DSH 会话里重启 DSH,要同时躲开四个独立的坑,每一个都会让应用关上之后再也打不开,而且不报错。
三个工具
| 工具 | 作用 | 是否中断会话 |
| dsh_status | 列出 DSH 进程、python 记忆桥、已装插件版本(对比 registry 最新版) | 不中断,只读 |
| dsh_restart | 干净地关闭全部 DSH 进程,等待退出,然后自动重新打开 | 中断 |
| dsh_update | 装指定版本插件(绕开 already-installed bug),然后重启 | 中断 |
模型可以直接调用。典型对话:
「帮我重启 DSH」→ 调用 dsh_restart 「dshmarket 更新失败了」→ 先 dsh_status 看版本,再 dsh_update 传 dshmarket@1.66.44 「记忆插件好像没生效」→ dsh_status 看 python 桥接进程在不在
安装
dsh plugin add 底层就是 pnpm add,它接受 Git 仓库、本地目录和 tarball。
展开完整文档(README 剩余 1 节)
dsh-app-control
在 DSH 会话内向模型提供三个工具,用来重启、更新和体检 DeepSeek Harness 桌面应用本身。
核心卖点不是「能重启」,而是重启不会把自己弄死。这件事比看上去难:从 DSH 会话里重启 DSH,要同时躲开四个独立的坑,每一个都会让应用关上之后再也打不开,而且不报错。
三个工具
| 工具 | 作用 | 是否中断会话 |
| dsh_status | 列出 DSH 进程、python 记忆桥、已装插件版本(对比 registry 最新版) | 不中断,只读 |
| dsh_restart | 干净地关闭全部 DSH 进程,等待退出,然后自动重新打开 | 中断 |
| dsh_update | 装指定版本插件(绕开 already-installed bug),然后重启 | 中断 |
模型可以直接调用。典型对话:
「帮我重启 DSH」→ 调用 dsh_restart 「dshmarket 更新失败了」→ 先 dsh_status 看版本,再 dsh_update 传 dshmarket@1.66.44 「记忆插件好像没生效」→ dsh_status 看 python 桥接进程在不在
安装
dsh plugin add 底层就是 pnpm add,它接受 Git 仓库、本地目录和 tarball。本插件不发布到 npm,仓库本身就是分发渠道。
方式一:从 Git 安装(推荐)
dsh plugin --profile desktop add git+https://github.com/cheng-wj/dsh-app-control.git
装的是仓库快照。已实测:从 Git 装下来的 assets/dsh-tools.bat 仍是 399 对 CRLF(.gitattributes 保住了它),三个工具正常注册。
缺点是升级要重新 add 一次。
方式二:本地目录链接(改代码立刻生效)
dsh plugin --profile desktop add link:"C:\Users\ZY\Documents\deepseek-harness\默认工作区\dsh-app-control-plugin"
link: 装的是目录软链,改完 src/index.js 重启就生效,不需要重新打包。适合自己开发调试。
方式三:tarball 离线分发
从 Releases 下载 .tgz,或从源码自行打包:
dsh plugin --profile desktop add "C:\path\to\dsh-app-control-1.0.0.tgz"
适合拷给别人、内网分发,或者留个可归档的快照。
五个坑(这是本插件的全部价值)
前三个坑在开发过程中都真实触发过,第四个是参数层面的隐蔽 bug,第五个是插件发布层面的坑——它让插件「看起来装好了,其实一次都没跑」。
坑 1:taskkill /T 会杀掉调用者自己
taskkill /IM "DeepSeek Harness.exe" /T /F 里的 /T 会向上遍历进程树。如果调度脚本是 DSH 的子进程,它就是自己的行刑对象:应用被关掉,脚本也被干掉,于是没人负责重新打开。
解法:用 WMI 的 Win32_Process.Create 启动调度器。新进程的父进程是 WmiPrvSE.exe,不在 DSH 树里,/T 打不到它。
$result = ([wmiclass] 'Win32_Process').Create($cmdLine)
坑 2:start "" "app.exe" 不是脱离
批处理里用 start 打开应用,新进程会继承 cmd 的控制台。用户关掉那个小黑窗时,Windows 发送 CTRL_CLOSE_EVENT,Electron 收到后直接退出——表现就是「关掉脚本窗口,DSH 也跟着退出了」。
解法:重开应用同样走 WMI,父进程是 WmiPrvSE.exe,没有共享控制台,关任何窗口都不影响它。
坑 3:.bat 必须是 CRLF(最阴的一个)
纯 LF 的批处理文件不会报错。cmd.exe 对 call :LABEL 是按字节偏移记账的,遇到 LF 只换行不回车时偏移算错,脚本会在中途静默停止:
[1/2] all DSH processes are gone ← 走到这里 [2/2] DSH is running again ← 永远不出现
应用被关掉了,再也没有重开,而且没有任何错误信息。这个坑排查了很久,最后用 A/B 对照确认:内容完全相同、只有行尾不同的两个文件,LF 版停在中途,CRLF 版完整跑完。
解法:ensureCrlf() 在每次运行前按字节统计 CR/LF 数量,不一致就原地修复。
function crlfCounts(file) {
const buf = readFileSync(file)
let cr = 0, lf = 0
for (const byte of buf) {
if (byte === 13) cr++
else if (byte === 10) lf++
}
return { cr, lf }
}
⚠️ 不要用 awk '/\r$/' 检查:它匹配的是字面字母 r,不是回车符,对正确的 CRLF 文件也会报「没有 CR」。只能用字节计数,或者 node。
坑 4:cmd.exe 把 = 当作参数分隔符
把 --delay=5 传给批处理,实际收到的是两个参数:--delay 和 5。只匹配字面量 --delay= 的解析器永远不会命中,选项被静默忽略。
解法:匹配裸 --delay,从下一个参数取值。
if /I "!ARG!"=="--delay" (
set "DELAY=%~2"
shift
shift
goto MAIN_LOOP
)
同一个解析器还负责 --profile,并且在倒计时之前校验包列表非空——否则一个没有包名的 update 会先把 DSH 关掉、什么也不装、再重开一遍。
顺带一个相关约束:WMI 创建的进程不继承调用者的环境变量。所以 DSH_DELAY / DSH_PROFILE 这类环境变量传不进去,选项必须在命令行上显式传。环境变量只作为手动运行 .bat 时的兜底保留。
坑 5:插件「装好了」但 apply() 从未执行(最隐蔽的一个)
现象:dsh plugin add 成功,profile 里能看到依赖,重启后也没有任何报错——但工具一个都不出现。日志全绿。
原因有两层,都会让 Loader 静默跳过整行:
(a)Config 必须是 schemastery Schema,不能是普通对象。
cordis 会把行的 Config 当成校验器调用。普通对象不可调用,apply() 前就抛错,整行被丢弃。
// ✗ 错误:apply() 永远不会被调用
export const Config = { delaySeconds: { type: 'number', default: 10 } }
// ✓ 正确 import z from '@deepseek-ai/schemastery'
export const Config = z.object({ delaySeconds: z.number().default(10) })
(b)peer 依赖必须惰性 + 可选解析。
@deepseek-ai/schemastery 和 @deepseek-ai/dsh-tools 都是 peer,只由宿主提供。用静态 import 时,只要宿主一解析不到,整个模块导入就失败——而 Loader 把「插件导入失败」当作非致命跳过:记一条日志、不建 fiber、其余插件照常工作。于是插件完全隐身。
更麻烦的是 link: 安装:node_modules/dsh-app-control 指向源码目录,裸包名会按源码树解析,而 peer 是 hoist 在 profile 里的,所以恰好解析不到。
// ✓ 惰性 + 可选,再从各 profile 目录兜底解析 let z = null
try { z = (await import('@deepseek-ai/schemastery')).default } catch {
const { createRequire } = await import('node:module')
z = createRequire(join(DSH_HOME, 'profiles', 'desktop', 'noop.cjs'))('@deepseek-ai/schemastery').default
}
export const Config = typeof z?.object === 'function' ? z.object({ /* ... */ }) : undefined
Config 缺失时导出 undefined 即可——cordis 会把行配置原样透传;工具本身不依赖 schema,代价只是少了设置界面。
诊断心法:这类失败在宿主进程里完全不可见。插件应把 apply() 的每一步 writeFileSync 到一个 trace 日志里,否则「工具没出现」和「插件没加载」无法区分。本插件的 trace 在 %DSH_HOME%\dsh-app-control\logs\apply-trace.log。
配置
在 profile 的 cordis.patch.yml 里给这一行加配置即可:
- dsh-app-control:
delaySeconds: 10 # 倒计时秒数,留出取消的余地 profile: desktop # dsh_update 的默认 profile
dsh_restart 和 dsh_update 每次调用也可以在参数里覆盖 delaySeconds,用 0 立即重启。
文件结构
dsh-app-control-plugin/
├── src/index.js # 插件主体:暂存脚本、驱动调度器、注册三个工具 ├── assets/ │ ├── dsh-tools.bat # 调度器:解析参数 → 倒计时 → taskkill /T → 重开 │ ├── launch-detached.ps1 # 经 WMI 脱离进程树启动,CRLF 守卫 │ ├── launch-app.ps1 # 经 WMI 打开应用本体 │ └── run-visible.ps1 # 输出同时打到控制台和日志(UTF-8 无 BOM) ├── cordis.patch.yml # bundle 挂载声明 └── package.json
运行时会把这四个脚本复制到 $DSH_HOME/dsh-app-control/scripts/,日志写到 $DSH_HOME/dsh-app-control/logs/。不写 node_modules(可能只读、升级时被替换),日志也放在插件目录外,所以升级插件不会丢历史记录。
平台
仅 Windows。调度器依赖 taskkill / tasklist / WMI / PowerShell,这些没有跨平台等价物。
在非 Windows 宿主上插件行仍会挂载,工具也会注册,但每次调用都会返回明确错误,而不是悄悄什么都不做。
已知限制
- 会中断正在进行的对话。dsh_restart / dsh_update 关闭应用时,当前会话跟着断。模型被告知要先提醒你保存工作。
- 单实例锁。Electron 的单实例机制会让重复启动落回已有实例,所以不会开出两个 DSH;但也意味着「重开失败」不会以弹窗形式暴露,只能看日志。
- 日志是 UTF-8 无 BOM。早先用 PowerShell 的 Tee-Object 写日志,PowerShell 5.1 下会写成 UTF-16LE,普通编辑器打开每个字符之间都是 \0。现在改用 StreamWriter,明确指定无 BOM 的 UTF-8。
License
MIT预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
cheng-wj/dsh-app-control
在会话内重启、更新并体检桌面应用
相关插件 · 桌面端
Codex 任务面板chuspeeism/dashi-taskboard
现代化可灵活嵌入的任务面板,支持 Codex、DeepSeek Harness
★ 3,409已汉化DSH
71.7
多智能体自进化开发平台Prism-Shadow/penguin-harness
统一、稳定的 Agent 自进化框架全自动优化:任意模型 · 任意算法 · 任意 Benchmark
★ 3,125已汉化DSH
71.1
桌面宠物PC2005-cloud/dsh-pet
DSH 桌面宠物:一行命令装好即用的透明动画小桌宠,支持多开、大小位置随心配置;还内置 DIY 素材链,能用 AI…
★ 5,465已汉化DSH
71
多端 Agent 工作台GCWing/OpenBitFun
OpenBitFun 是一个高度可定制的开源 Agent 工作台,让任务按你的方式持续推进。
★ 3,457已汉化DSH
70.8
DSH Desktopanywhere-labs/dsh-desktop
为 DeepSeek Harness DSH 插件生态打造的现代化桌面端解决方案。万物皆「插件」,桌面本身也是「插件」。
★ 34,710已汉化DSH
70.7
桌面宠物伴侣OpenPetsHQ/openpets
桌面伴侣平台,带宠物、插件,还能选配本地智能体集成。
★ 1,378已汉化DSH
70.2
这是你的仓库?认领条目