WispOps(dsh-wisp-ops):DeepSeek Harness 的多主机服务器运维插件——集群巡检、磁盘与近期文件分析(含组学数据清理建议)、安全排查、按服务器定时生成报告、人工审批的 sudo
31.1/100
综合分
2
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/11/3 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add wisp-science/WispOps该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:需留意
是什么
dsh 原生插件 · market
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 5 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
⚠︎ 实装验证未通过(node_version · 2026/10/29) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 58 处,展示前 56 条)
- 读取本地文件lib/inventory.js:32
text = await readFile(expandHome(path), 'utf8'); - 读取本地文件lib/service.js:49
const mtime = (await Promise.all(paths.map(path => stat(path).then(s => `${s.mtimeMs}:${s.ctimeMs}:${s.size}`, error => { - 读取本地文件lib/skills.js:26
const candidates = readdirSync(root, { withFileTypes: true }) - 读取本地文件lib/skills.js:31
const { name, description } = parseSkill(readFileSync(path, 'utf8'), path); - 读取本地文件lib/skills.js:50
const raw = await readFile(locator, { encoding: 'utf8', signal: options.signal }); - 读取本地文件lib/wispterm.js:37
const text = await readFile(join(dir, 'passwords'), 'utf8'); - 执行外部命令来自配置/变量lib/wispterm.js:67
execFile(file, args, { encoding: 'buffer', timeout: 120_000, ...env === undefined ? {} : { env: { ...process.env, ...env } } }, (error, stdout) => { - 读取本地文件lib/wispterm.js:104
const key = await readFile(join(dir, 'passwords.key')); - 读取本地文件lib/wispterm.js:199
return parseSshHosts(await readFile(join(dir, 'ssh_hosts'), 'utf8')); - 执行外部命令来自配置/变量lib/vault.js:11
const child = spawn(file, args, { stdio: ['pipe', 'pipe', 'pipe'], timeout: 120_000 }); - 读取本地文件lib/vault.js:37
let stored = await readFile(file).catch(error => { if (error.code === 'ENOENT') - 写入本地文件lib/vault.js:44
await writeFile(file, stored, { mode: 0o600, flag: 'wx' }); - 写入本地文件lib/vault.js:48
await chmod(file, 0o600); - 写入本地文件lib/ssh.js:164
await chmod(dir, 0o700); - 写入本地文件lib/ssh.js:166
await writeFile(passfile, password, { mode: 0o600 }); - 写入本地文件lib/ssh.js:170
await writeFile(script, `@type "${passfile}"\r\n`, { mode: 0o700 }); - 写入本地文件lib/ssh.js:174
await writeFile(script, `#!/bin/sh\ncat ${shellQuote(passfile)}\n`, { mode: 0o700 }); - 删除本地文件递归lib/ssh.js:178
cleanup: () => rm(dir, { recursive: true, force: true }), - 写入本地文件lib/ssh.js:192
mkdirSync(this.controlDir, { recursive: true, mode: 0o700 }); - 执行外部命令来自配置/变量lib/ssh.js:280
const child = spawn(this.spec.binary, this.argv(host, request.sudo, withPassword), { - 读取本地文件lib/store.js:12
text = await readFile(path, 'utf8'); - 写入本地文件lib/store.js:97
await mkdir(path, { recursive: true, mode: 0o700 }); - 写入本地文件lib/store.js:104
await writeFile(tmp, kept.map(r => JSON.stringify(r)).join('\n') + '\n', { mode: 0o600 }); - 写入本地文件lib/store.js:105
await rename(tmp, file); - 写入本地文件lib/store.js:110
await appendFile(join(dir, `${month}.jsonl`), `${JSON.stringify(entry)}\n`, { mode: 0o600 }); - 读取本地文件lib/store.js:121
const names = (await readdir(join(this.dir, 'audit')).catch((error) => { - 删除本地文件lib/store.js:127
await rm(join(this.dir, 'audit', name), { force: true }); - 读取本地文件lib/store.js:133
const names = (await readdir(join(this.dir, 'audit')).catch((error) => { - 写入本地文件lib/store.js:158
await appendFile(file, `${JSON.stringify(record)}\n`, { mode: 0o600 }); - 读取本地文件lib/store.js:191
return JSON.parse(await readFile(join(this.dir, 'probes.json'), 'utf8')); - 写入本地文件lib/store.js:203
await writeFile(tmp, JSON.stringify(merged, null, 2), { mode: 0o600 }); - 读取本地文件lib/local-state.js:15
return await readFile(this.path, 'utf8').catch(error => { - 写入本地文件lib/local-state.js:30
await mkdir(dirname(this.path), { recursive: true, mode: 0o700 }); - 写入本地文件lib/local-state.js:32
await mkdir(lock, { mode: 0o700 }).catch(error => { - 写入本地文件lib/local-state.js:45
await writeFile(temp, `${JSON.stringify(next, null, 2)}\n`, { mode: 0o600, flag: 'wx' }); - 写入本地文件lib/local-state.js:46
await chmod(temp, 0o600); - 写入本地文件lib/local-state.js:50
await rename(temp, this.path); - 删除本地文件lib/local-state.js:64
await rm(this.path, { force: true }); - 写入本地文件lib/local-state.js:66
await writeFile(temp, previous, { mode: 0o600, flag: 'wx' }); - 删除本地文件lib/local-state.js:77
await rm(temp, { force: true }); - 删除本地文件递归lib/local-state.js:78
await rm(lock, { recursive: true, force: true }); - 读取本地文件lib/ssh-config.js:95
text = await readFile(file, 'utf8'); - 读取本地文件lib/ssh-config.js:119
const names = await readdir(dir).catch(() => []); - 写入本地文件lib/sync.js:137
await mkdir(dir, { recursive: true, mode: 0o700 }); - 写入本地文件lib/sync.js:139
await writeFile(join(dir, backupName), await sealSync(backup.snapshot, passphrase), { mode: 0o600, flag: 'wx' }); - 写入本地文件lib/sync.js:142
await mkdir(keyDir, { recursive: true, mode: 0o700 }); - 写入本地文件lib/sync.js:145
await writeFile(path, key.content, { mode: 0o600, flag: 'wx' }).catch(async (error) => { - 读取本地文件lib/sync.js:146
if (error.code !== 'EEXIST' || !(await lstat(path)).isFile() || await readFile(path, 'utf8') !== key.content) - 读取本地文件lib/sync.js:146
if (error.code !== 'EEXIST' || !(await lstat(path)).isFile() || await readFile(path, 'utf8') !== key.content) - 写入本地文件lib/sync.js:149
await chmod(path, 0o600); - 读取本地文件lib/updates.js:42
return this.runningVersion ??= readFile(join(this.root, 'package.json'), 'utf8').then(text => String(JSON.parse(text).version)); - 读取本地文件lib/updates.js:121
if (await stat(join(this.root, '.git')).then(() => true, () => false)) - 发起网络请求lib/webdav.js:47
const response = await this.request('PROPFIND', '', '<?xml version="1.0"?><d:propfind xmlns:d="DAV:"><d:prop><d:resourcetype/></d:prop></d:propfind>', - 发起网络请求lib/webdav.js:74
const collection = await this.request('MKCOL'); - 发起网络请求lib/webdav.js:78
const response = await this.request('PUT', name, body, { 'content-type': 'application/json', 'if-none-match': '*' }); - 发起网络请求lib/webdav.js:84
const response = await this.request('GET', name);
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-api-gateway@deepseek-ai/dsh-api-remote-access@deepseek-ai/dsh-commands@deepseek-ai/dsh-llm@deepseek-ai/dsh-skill@deepseek-ai/dsh-system-prompt@deepseek-ai/dsh-tools@deepseek-ai/dsh-typert-protocol@deepseek-ai/dsh-typert-registry@deepseek-ai/dsh-user-approval@deepseek-ai/schemastery给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
README
由 DeepSeek 最新模型翻译生成中文 · English
WispOps(dsh-wisp-ops)
DeepSeek Harness 的多主机服务器运维插件:服务器管理、独立加密密码库、按服务器的例行任务,以及巡检、磁盘诊断、安全排查和批量命令。变更、sudo、破坏性操作逐主机授权;密码只交给 SSH,不返回给页面或模型。不需要 WispTerm。
安装
需要 DeepSeek Harness >=0.2.1-rc.3 <0.3.0。推荐使用 npm 版:直接下载已打包的发行版本,安装更方便,无需访问 GitHub。npm 和 GitHub 是同一插件的两种安装来源,选择一种即可,均无需本地编译。
方式一:npm 版(推荐)
在终端中安装 npm 最新稳定版:
dsh plugin --profile desktop add dsh-wisp-ops@latest
需要固定版本时,例如安装 0.13.0:
dsh plugin --profile desktop add dsh-wisp-ops@0.13.0
desktop 是桌面版的默认 profile;Web 版通常改为 web。安装完成后重启 Harness,确认插件已启用。
方式二:GitHub 版
此方式需要能访问 GitHub,支持从插件页面或命令行安装。
展开完整文档(README 剩余 1 节)
中文 · English WispOps(dsh-wisp-ops) DeepSeek Harness 的多主机服务器运维插件:服务器管理、独立加密密码库、按服务器的例行任务,以及巡检、磁盘诊断、安全排查和批量命令。变更、sudo、破坏性操作逐主机授权;密码只交给 SSH,不返回给页面或模型。不需要 WispTerm。 安装 需要 DeepSeek Harness >=0.2.1-rc.3 <0.3.0。推荐使用 npm 版:直接下载已打包的发行版本,安装更方便,无需访问 GitHub。npm 和 GitHub 是同一插件的两种安装来源,选择一种即可,均无需本地编译。 方式一:npm 版(推荐) 在终端中安装 npm 最新稳定版: dsh plugin --profile desktop add dsh-wisp-ops@latest 需要固定版本时,例如安装 0.13.0: dsh plugin --profile desktop add dsh-wisp-ops@0.13.0 desktop 是桌面版的默认 profile;Web 版通常改为 web。安装完成后重启 Harness,确认插件已启用。 方式二:GitHub 版 此方式需要能访问 GitHub,支持从插件页面或命令行安装。 插件页面安装: 1. Harness 左侧 插件 → + 添加插件,粘贴 https://github.com/wisp-science/WispOps。 2. 安装源:国内网络选 中国大陆镜像源,其他选 npm 官方源。此选项只影响依赖下载,插件本身仍从 GitHub 获取。 3. 点击 安装,确认插件已启用。 4. 完全退出并重新打开 Harness。 命令行安装: dsh plugin --profile desktop add github:wisp-science/WispOps 安装完成后重启 Harness。 升级与切换来源 - npm 版:重新执行上面的 @latest 命令升级,或指定要安装的版本。 - GitHub 版:在运维面板的 版本更新 中检查并安装稳定 Release,也可开启自动更新。面板内更新目前仅支持 GitHub 来源。 - Windows 从 GitHub 切换到 npm:先完全退出 Harness(含托盘),再从外部 PowerShell 执行 npm 版安装命令,完成后重开。遇到 EPERM rename 时见恢复步骤。 两种来源使用相同的包名和安装目录。服务器、密码库和任务默认保存在 ~/.dsh-wisp-ops/,卸载重装不会删除这个目录。本地开发链接不会被面板更新覆盖。 本地源码安装和常见报错见 docs/install.md。 上手 打开左侧 服务器运维(或会话右侧栏 开始 → 服务器运维): 1. 服务器:添加地址、用户名和端口,或从 ~/.ssh/config 批量导入;保存后自动探测能力。不需要的 WispTerm / 配置服务器可从 WispOps 移除,并从“已移除”列表恢复,原始配置保留。 2. 密码库:新建凭据,只填名称和密码。再到服务器详情为 SSH 登录、sudo 提权分别关联凭据,可先测试再保存。密钥登录、免密 sudo 可跳过。 3. 任务库:选择内置模板或自建,点击 关联服务器,设置检查对象和运行时间。 4. 例行任务:选择接收报告的会话,点击 运行一次 立即执行看效果,或点击 启用调度 定时运行。Harness 需保持运行;漏跑的任务会在卡片上标出。 5. 操作审计:查看模型、面板和任务执行过的每条远程命令及其授权和结果。 也可以手写 ~/.dsh-wisp-ops/inventory.yml,参考 examples/inventory.yml。 能做什么 | 工具 | 用途 | | ops_inspect | 巡检负载、内存、磁盘、systemd、GPU、Slurm、OOM 等,按阈值告警并与上次对比 | | ops_disk | 磁盘诊断:大目录和大文件、是否被进程或作业占用、已删除仍占用的空间、各类缓存 | | ops_files | 近期新增文件:按目录和属主统计,识别测序/生信文件并生成清理计划 | | ops_security | 攻击排查:SSH 暴力破解、可疑进程与外连、异常账户、近期改动的启动项 | | ops_change | 文件、新建文件和目录的备份、变更、验证和失败恢复;按组逐台滚动,首台失败即停 | | ops_exec | 批量命令:并发执行,执行前做风险分级 | | ops_hosts / ops_history | 能力探测;操作审计、巡检历史与磁盘/内存趋势(审计按月、巡检按条数自动保留) | | ops_task | 运行例行任务:内置采集器、只读命令或检查脚本,附上一次结果供对比;mode=last 直接读取 WispOps 定时器已保存的结果 | | ops_template_draft | 提交检查模板草稿,由你在面板审核后保存;不能直接写任务库、关联服务器或启用调度 | | ops_script_draft | 提交检查脚本草稿,由你在面板测试、审核后保存;脚本任务可由 WispOps 定时器运行,只在异常时才唤醒 agent | 另带 6 个技能:磁盘写满、生信存储清理、安全排查、定时汇报、安全变更、GPU/Slurm。详见 docs/features.md。 支持企业微信、钉钉、飞书和邮件网关 webhook 通知,可只在异常、仅状态变化时投递并设置静默时段;面板随 Harness 切换中英文。设备同步 可通过坚果云 WebDAV 传输加密凭据、任务配置和明确选定的 SSH 私钥。详见通知、变更、同步与更新。 权限 每条命令分为 read / change / sudo / destructive,按 主机策略 > 分组 > 默认 裁决为 allow、ask 或 deny。默认只读直接执行,其余逐次审批;也可以在服务器详情的「操作权限」里按服务器改成 allow / ask / deny,或用 /ops-allow sudo @gpu 2h 临时放行,/ops-revoke all 撤销。模型不能读写清单、数据目录和密码库,包括通过只读命令读取密钥文件。 密码库使用 XChaCha20-Poly1305 加密,密钥存放在 macOS 钥匙串、Windows DPAPI 或权限为 0600 的文件中。详见 docs/security.md。 文档 - 安装与常见问题 - 管理面板与任务库 - 功能、技能与路线图 - 权限模型与密码库 - 配置与 YAML 任务 - 通知、安全变更、设备同步与更新 - 版本记录 - npm 发布配置与发版流程 开发 npm install npm test npm run typecheck npm run build lib/ 已纳入 Git,GitHub 安装直接使用。修改 src/ 或 client/ 后执行 npm run build,并把 lib/ 一起提交。测试中的 tests/fixtures/fake-ssh.sh 在本机模拟远程命令。 限制 - 目标主机按 GNU/Linux 处理,不支持 Windows 目标。 - 外部通知发送采集摘要;没有 commands 的 custom 任务仍需模型继续采集,不会伪装成已完成报告。 - 调度依赖 Harness 常驻和已打开的报告会话;错过的时间点不自动补跑,面板只标出疑似漏跑(cron 不判断)。 - 安全变更恢复范围限于列出的路径;设备同步是人工触发的快照替换,更新安装后需重启。 License MIT
预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
wisp-science/WispOps
WispOps(dsh-wisp-ops):DeepSeek Harness 的多主机服务器运维插件——集群巡检、磁盘与近期文件分析(含组学数据清理建议)、安全排查、按服务器定时生成报告、人工审批的 sudo
相关插件 · 市场 / 管理
插件精选列表awesome-dsh-plugin/awesome-dsh-plugin
DeepSeek Harness(dsh)插件精选列表
★ 22,225未汉化DSH
73.6
新词雷达zhuyansen/new-term-radar
new-term-radar新词雷达
★ 2,049已汉化MCP
72.8
插件生态导航0xsline/awesome-deepseek-harness
安装 贡献指南 DeepSeek Docs 公开插件目录 Issues
★ 1,188已汉化DSH
72.6
技能注册中心iflytek/skillhub
企业级开源智能体技能注册中心——发布、发现并管理组织内可复用的技能包。
★ 5,370已汉化DSH
71.9
插件市场目录imsai-sh/awesome-deepseek-harness-plugins
面向 DeepSeek Harnessdsh生态的社区插件目录,共收录 13941 个插件含 PR 收录与…
★ 355已汉化DSH
71.8
插件精选清单Anil-matcha/awesome-dsh-plugin
DeepSeek Harnessdsh精选指南——DeepSeek…
★ 1,013已汉化DSH
71.7
这是你的仓库?认领条目