在 DSH 中和 SSH 一样无感地使用 VPS,除了精选的部分常用命令之外,使用时还能让对话中的大模型对 VPS…
38.2/100
综合分
6
GitHub 星标
578
npm 周下载
—/5
用户评分
数据截至 2026/10/17 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add dsh-vps-managernpm 源 · dsh-vps-manager 的发布者账号已校验与本仓库一致
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · market
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 18 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查✓ 自动检查通过展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✓npm 包dsh-vps-manager @ 0.6.8
✓Node 引擎要求 >=22.13 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/11/2 09:42:02
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件写入剪贴板(不计风险)发起外部网络请求
查看扫描证据(共 97 处,展示前 90 条)
- 读取本地文件lib/index.js:54
const content = await readFile(new URL('./skills/vps-operator.md', import.meta.url), 'utf8') - 发起网络请求lib/client.js:97
const res = await fetch('/api-vps/token', { method: 'POST', headers: { 'content-type': 'application/json' }, body: '{}', credentials: 'same-origin', c - 发起网络请求lib/client.js:107
const res = await fetch(`${window.location.origin}/`, { credentials: 'same-origin', cache: 'no-store' }) - 发起网络请求lib/client.js:125
res = await fetch(`/api-vps/${path}`, { - 写入剪贴板lib/client.js:400
await navigator.clipboard.writeText(text) - 写入剪贴板lib/client.js:1321
await navigator.clipboard.writeText(text) - 写入剪贴板lib/client.js:2580
if (text) navigator.clipboard?.writeText(text).catch(() => {}) - 写入剪贴板lib/client.js:3748
await navigator.clipboard.writeText(text) - 发起网络请求lib/client.js:4846
const r = await fetch(res.url, { credentials: 'same-origin', signal: abort.signal, headers: { 'x-dsh-vps-lang': lang() } }) - 写入剪贴板lib/client.js:4907
await navigator.clipboard.writeText(path) - 写入本地文件lib/config.js:94
await mkdir(dir, { recursive: true }) - 写入本地文件lib/config.js:96
await chmod(p.base, 0o700).catch(() => {}) - 写入本地文件lib/config.js:102
await mkdir(dirname(file), { recursive: true }) - 写入本地文件lib/config.js:104
await writeFile(tmp, content, { mode }) - 写入本地文件lib/config.js:108
await rename(tmp, file) - 删除本地文件lib/config.js:112
await unlink(tmp).catch(() => {}) - 读取本地文件lib/config.js:120
const exists = (file) => access(file, constants.F_OK).then(() => true, () => false) - 读取本地文件lib/config.js:179
const text = await readFile(hostsFile, 'utf8') - 读取本地文件lib/config.js:231
return JSON.parse(await readFile(file, 'utf8')) - 读取本地文件lib/config.js:383
const text = await readFile(file, 'utf8') - 读取本地文件lib/config.js:423
const entries = await readdir(dir) - 读取本地文件lib/config.js:473
return readFile(sshDropin, 'utf8') - 写入本地文件lib/config.js:501
await mkdir(p.sshDropinDir, { recursive: true, mode: 0o700 }) - 读取本地文件lib/health.js:64
const pkg = JSON.parse(await readFile(join(dir, 'package.json'), 'utf8')) - 写入本地文件lib/health.js:153
await mkdir(logDir(env), { recursive: true, mode: 0o700 }) - 写入本地文件lib/health.js:154
await appendFile(join(logDir(env), `errors-${monthKey()}.jsonl`), `${JSON.stringify(line)}\n`, { mode: 0o600 }) - 读取本地文件lib/health.js:164
files = (await readdir(logDir(env))).filter((f) => /^errors-\d{4}-\d{2}\.jsonl$/.test(f)).sort().reverse() - 读取本地文件lib/health.js:170
const text = await readFile(join(logDir(env), file), 'utf8').catch(() => '') - 读取本地文件lib/health.js:187
files = (await readdir(logDir(env))).filter((f) => /^errors-\d{4}-\d{2}\.jsonl$/.test(f)) - 删除本地文件lib/health.js:197
await unlink(join(logDir(env), f)).catch(() => {}) - 读取本地文件lib/health.js:239
return JSON.parse(await readFile(new URL('../package.json', import.meta.url), 'utf8')).version ?? '' - 读取本地文件lib/recipes.js:134
files = (await readdir(dir)).filter((f) => f.endsWith('.yml') || f.endsWith('.yaml')) - 读取本地文件lib/recipes.js:141
out.push(...parseRecipeFile(await readFile(full, 'utf8'), { source, file: full })) - 读取本地文件lib/engine.js:26
preludeCache = await readFile(new URL('./prelude.sh', import.meta.url), 'utf8') - 写入本地文件lib/engine.js:69
if (!stream) stream = createWriteStream(file, { mode: 0o600 }) - 删除本地文件lib/engine.js:77
await unlink(file).catch(() => {}) - 写入本地文件lib/audit.js:29
await appendFile(join(p.auditDir, `${monthKey()}.jsonl`), `${JSON.stringify(line)}\n`, { mode: 0o600 }) - 读取本地文件lib/audit.js:37
files = (await readdir(p.auditDir)).filter((f) => f.endsWith('.jsonl')).sort().reverse() - 读取本地文件lib/audit.js:43
const text = await readFile(join(p.auditDir, file), 'utf8').catch(() => '') - 读取本地文件lib/audit.js:61
files = (await readdir(p.auditDir)).filter((f) => f.endsWith('.jsonl')).sort() - 删除本地文件lib/audit.js:71
await unlink(join(p.auditDir, file)).catch(() => {}) - 执行外部命令来自配置/变量lib/spawn.js:108
child = spawn(file, args, { stdio: ['pipe', 'pipe', 'pipe'], env, cwd, windowsHide: true }) - 发起网络请求lib/safety.js:56
const outcome = await approval.request({ - 执行外部命令固定命令lib/filemgr.js:81
return spawn('ssh', sshArgs(alias, { command: `sh -c ${shellQuote(script)}` }), { stdio: ['pipe', 'pipe', 'pipe'], windowsHide: true }) - 读取本地文件lib/netcheck.js:441
return JSON.parse(await readFile(join(netDir(alias, env), 'latest.json'), 'utf8')) - 写入本地文件lib/netcheck.js:449
await mkdir(dir, { recursive: true }) - 读取本地文件lib/netcheck.js:456
for (const name of await readdir(dir)) { - 删除本地文件lib/netcheck.js:458
if (m && Date.parse(m[1]) < cutoff) await rm(join(dir, name), { force: true }) - 读取本地文件lib/onboarding.js:29
const exists = (f) => access(f, constants.F_OK).then(() => true, () => false) - 读取本地文件lib/onboarding.js:46
return { path: file, pubkey: (await readFile(pub, 'utf8')).trim(), created: false, ...(await keyInfo(file)) } - 写入本地文件lib/onboarding.js:50
await mkdir(p.sshDir, { recursive: true, mode: 0o700 }) - 写入本地文件lib/onboarding.js:58
await chmod(file, 0o600).catch(() => {}) - 读取本地文件lib/onboarding.js:59
return { path: file, pubkey: (await readFile(pub, 'utf8')).trim(), created: true, ...(await keyInfo(file)) } - 写入本地文件lib/onboarding.js:96
await writeFile(file, L(`#!/bin/sh\necho "把公钥放到服务器上(需要输入服务器密码)"\n${command}\necho\necho "完成后可以关闭这个窗口"\n`, `#!/bin/sh\necho "Putting the public key on - 删除本地文件lib/onboarding.js:98
setTimeout(() => unlink(file).catch(() => {}), 120_000) - 写入本地文件lib/onboarding.js:105
await writeFile(file, `${body.join('\r\n')}\r\n`) - 执行外部命令来自配置/变量lib/onboarding.js:109
const child = spawn(process.env.ComSpec || 'cmd.exe', ['/d', '/s', '/c', `"start "" "${file}""`], { - 删除本地文件lib/onboarding.js:119
setTimeout(() => unlink(file).catch(() => {}), 120_000) - 写入本地文件lib/onboarding.js:187
await writeFile(helper, `@set ELECTRON_RUN_AS_NODE=1\r\n@"${process.execPath}" -e "process.stdout.write(process.env.DSH_VPS_PW+'\\n')"\r\n`) - 写入本地文件lib/onboarding.js:189
await writeFile(helper, '#!/bin/sh\nprintf \'%s\\n\' "$DSH_VPS_PW"\n', { mode: 0o700 }) - 删除本地文件递归lib/onboarding.js:212
await rm(dir, { recursive: true, force: true }).catch(() => {}) - 删除本地文件lib/onboarding.js:260
await unlink(tmp).catch(() => {}) - 写入本地文件lib/recipe-store.js:117
await writeFile(file, header + body, { mode: 0o600 }) - 执行外部命令来自配置/变量lib/speedtest.js:37
child = spawn(cmd, args, { env, stdio: [uploadBytes ? 'pipe' : 'ignore', 'pipe', 'pipe'], windowsHide: true }) - 读取本地文件lib/speedtest.js:590
return JSON.parse(await readFile(join(speedDir(env), 'settings.json'), 'utf8')) - 写入本地文件lib/speedtest.js:597
await mkdir(speedDir(env), { recursive: true }) - 读取本地文件lib/speedtest.js:606
const names = (await readdir(dir)).filter((n) => /^\d{4}-\d{2}-\d{2}T.*\.json$/.test(n)).sort() - 读取本地文件lib/speedtest.js:610
const rec = JSON.parse(await readFile(join(dir, n), 'utf8')) - 读取本地文件lib/speedtest.js:623
return JSON.parse(await readFile(join(speedDir(env), alias, 'latest.json'), 'utf8')) - 写入本地文件lib/speedtest.js:630
await mkdir(dir, { recursive: true }) - 读取本地文件lib/speedtest.js:635
for (const n of await readdir(dir)) { - 删除本地文件lib/speedtest.js:637
if (m && Date.parse(m[1]) < cutoff) await rm(join(dir, n), { force: true }) - 读取本地文件lib/speedtest.js:744
return JSON.parse(await readFile(candFile(env), 'utf8')) - 写入本地文件lib/speedtest.js:750
await mkdir(join(dshHome(env), 'vps-manager'), { recursive: true }) - 读取本地文件lib/status.js:421
return JSON.parse(await readFile(cacheFile(alias, env), 'utf8')) - 写入本地文件lib/status.js:430
await mkdir(join(dshHome(env), 'vps-manager', 'status'), { recursive: true }) - 执行外部命令固定命令lib/terminal-server.js:218
return spawn('ssh', terminalSshArgs(alias, remoteScript({ cols, rows })), { - 读取本地文件lib/terminal-server.js:737
const body = await readFile(new URL(file, assetDir)) - 读取本地文件lib/uninstall.js:37
await stat(file) - 读取本地文件lib/uninstall.js:52
const sshConfigText = (await exists(p.sshConfig)) ? await readFile(p.sshConfig, 'utf8') : '' - 读取本地文件lib/uninstall.js:114
const pub = (await exists(`${p.defaultKey}.pub`)) ? (await readFile(`${p.defaultKey}.pub`, 'utf8')).trim() : '' - 读取本地文件lib/uninstall.js:152
const text = await readFile(p.sshConfig, 'utf8') - 写入本地文件lib/uninstall.js:154
await copyFile(p.sshConfig, `${p.sshConfig}.dsh-uninstall-bak`) - 写入本地文件lib/uninstall.js:167
await rename(p.sshDropin, `${p.sshDropin}.uninstall-bak`) - 删除本地文件lib/uninstall.js:177
await rm(p.defaultKey, { force: true }) - 删除本地文件lib/uninstall.js:178
await rm(`${p.defaultKey}.pub`, { force: true }) - 删除本地文件递归lib/uninstall.js:191
await rm(p.base, { recursive: true, force: true }) - 读取本地文件lib/update.js:79
return JSON.parse(await readFile(new URL('../package.json', import.meta.url), 'utf8')).version ?? '' - 读取本地文件lib/update.js:89
return JSON.parse(await readFile(cacheFile(env), 'utf8')) - 写入本地文件lib/update.js:114
await mkdir(dirname(cacheFile(env)), { recursive: true })
扫描于 2026/11/2(1 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-tools给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
界面预览
1 张 · 点击查看大图功能亮点
- 零token命令
- 对话内终端
- AI分级确认运维
最近更新
在 GitHub 查看全部 →v0.6.82026-10-16
Network check-up on the Status tab. Three new cards at the top of the Status tab. Each gives plain conclusions first; the numbers are folded under Details.
· Network: is this server blocked in China (TCP probes from China Telecom, Unicom and Mobile nodes via the public Globalping network, with the US, Japan and Germany for comparison); do ChatGPT, Claude, Gemini, YouTube Premium, Netflix and Disney+ work from its IP, and in which region; is the IP clean (datacenter or residential, spam blacklists). About 30 seconds, no tokens. Also available as the new command /vps-netcheck.
· Speed: measured from your own computer, with your broadband plan as 100%. Through the proxy (your proxy app routes as usual; the exit is checked to really be this VPS) and direct to this server (bypassing the proxy app). The direct bandwidth test opens a temporary port on the server, allowed only for your home IP and removed afterwards; you are asked the first time, and it falls back to SSH if the provider's security group blocks it. The verdict says whether it is enough for 4K, video calls and gaming, and where it is slow.
· Compare servers: for choosing a VPS provider. Enter IPs, domains or a provider's Looking Glass address (+ adds a row, up to 10); latency, loss and download speed are measured directly from your computer and compared side by side, with the server you use now for reference.
Bypassing a TUN-mode proxy app is supported on macOS and Linux; when the card cannot bypass it, it says so instead of showing a wrong number.
+AI on the cards. The Network, Speed, Compare servers, Ports, Firewall and Security cards have a +AI at the right of their title row. It sends that card's findings to the conversation as one message, so the AI answers in the chat and you can follow up or let it act. Only the findings are sent, not the raw data or your home IP. The AI interpretation at the top of the page is unchanged.
状态页网络体检。 「状态」页签顶上多了三张卡,都是先给结论,数字收在「详细数据」里。
· 网络:这台在国内是不是被墙(经公共的 Globalping 网
v0.6.72026-10-15
No more false "certificate expires today" on servers without a domain. When dsh-vps runs without a domain, Caddy signs its own short-lived certificate (internal CA, valid for 12 hours, renewed automatically). The status page used to flag it as about to expire. Certificates under Caddy's certificates/local/ are no longer checked; real certificates (Let's Encrypt and others) are checked as before.
Disk rows fit on phones. When a disk row doesn't fit on one line, "free of total" moves to a second line instead of being cut off.
Both fixes were made first in vpssh and ported back.
没域名的服务器不再误报"证书今天到期"。 dsh-vps 没配域名时,Caddy 会自己签一张只有 12 小时、自动续期的证书(内部 CA),状态页以前会把它当成快到期。现在不再检查 Caddy certificates/local/ 下的证书;正式证书(Let's Encrypt 等)照常检查。
手机上磁盘一行放得下了。 一行放不下时,"剩多少"换到第二行,不再被截断。
这两处都是 vpssh 先修好、再搬回来的。
Install / 安装:Settings → VPS Manager → Update, or the plugin marketplace / 「设置 → VPS 管理」右上角「更新」,或插件市场。Command line / 命令行(quit DSH first / 先完全退出 DSH):dsh plugin --profile desktop add dsh-vps-manager@0.6.7
v0.6.62026-10-10
dsh plugin 命令现在带上了 --profile。从 DSH 0.2.0 起,dsh plugin 必须带 --profile,而且要写在 add / remove 前面;不带会报 required option '--profile ' not specified。
· 插件提示你自己执行的命令(更新装不上、卸载没法直接移除插件时)都带上了正确的 profile:官方桌面版 DeepSeek Harness 是 desktop,dsh web 是 web。名字由 DSH 告诉插件
· 这些提示也写明要先完全退出 DSH,官方桌面版必须这样
· README 和官网:命令行安装改成 dsh plugin --profile desktop add dsh-vps-manager(dsh web 换成 web)。要先退出 DSH,用桌面版自带的 dsh 命令(应用菜单「管理 dsh 命令…」里安装)。旧版 DSH Desktop「打开 DSH 终端」那套步骤删掉了
兼容性检查:修好了在 DSH 0.2.1-alpha.2 上的失败(#6),并且会检查插件能不能从 DSH 拿到 profile 名字。
安装:插件市场,或「设置 → VPS 管理」右上角「更新」。命令行(先完全退出 DSH):dsh plugin --profile desktop add dsh-vps-manager@0.6.6
数据来自仓库的 GitHub Release,可能与插件实际版本不一致。
README
由 DeepSeek 最新模型翻译生成dsh-vps-manager
在 DSH 中和 SSH 一样无感地使用 VPS,除了精选的部分常用命令之外,使用时还能让对话中的大模型对 VPS 进行操作。
Use your VPS inside DeepSeek Harness as seamlessly as over SSH: curated zero-token commands, plus the AI in the conversation can operate the server.
简体中文 · English
简介
安装:DSH 插件市场搜索 dsh-vps-manager 一键安装;也可以先完全退出 DSH,在终端执行下面这行(命令行版 dsh web 把 desktop 换成 web,见安装)。装完打开 DSH,到 设置 → VPS 管理 添加机器。
dsh plugin --profile desktop add dsh-vps-manager
在 DeepSeek Harness(DSH)里管理你的 VPS:用命令查看服务器状态(不走模型、不花 token),跟 AI 说一句话让它登上服务器干活,在对话里一页看清服务器状态,要自己动手就打开真终端、传文件,常见软件和系统维护按菜谱完成。
展开完整文档(README 剩余 1 节)
dsh-vps-manager 在 DSH 中和 SSH 一样无感地使用 VPS,除了精选的部分常用命令之外,使用时还能让对话中的大模型对 VPS 进行操作。 Use your VPS inside DeepSeek Harness as seamlessly as over SSH: curated zero-token commands, plus the AI in the conversation can operate the server. 简体中文 · English 简介 安装:DSH 插件市场搜索 dsh-vps-manager 一键安装;也可以先完全退出 DSH,在终端执行下面这行(命令行版 dsh web 把 desktop 换成 web,见安装)。装完打开 DSH,到 设置 → VPS 管理 添加机器。 dsh plugin --profile desktop add dsh-vps-manager 在 DeepSeek Harness(DSH)里管理你的 VPS:用命令查看服务器状态(不走模型、不花 token),跟 AI 说一句话让它登上服务器干活,在对话里一页看清服务器状态,要自己动手就打开真终端、传文件,常见软件和系统维护按菜谱完成。 Windows、macOS、Linux 上的 DSH 都能用,DSH Desktop 和命令行版 dsh web 都支持;家里、公司的几台电脑可以同时管同一台服务器。 添加机器时填一次密码,之后一律用 SSH 钥匙登录。所有操作共用同一套执行机制:会改东西的操作跑成远端任务,断线后在服务器上继续;同一台机器上的改动一个接一个执行;改配置文件前自动备份;改防火墙和 SSH 前,先在服务器上设好自动恢复;每次执行都记审计日志。 想把 DSH 本身装到 VPS 上? 看姊妹项目 dsh-vps:在 VPS 上执行一条命令,装好带登录页、自动 HTTPS 的原版 DSH,从任何地方用浏览器访问,设置、API Key、插件市场都能正常用,DSH 出新版本时在页面上一键升级。两者可以配合:在 VPS 上的 DSH 里装上本插件,就能在对话里直接管理这台服务器。 能力一览 | 能力 | 说明 | | 零 token 命令 | 22 条 /vps- 命令:看状态、装软件、重启并等机器回来,不走模型 | | VPS 模式 | 对话头部点一下,这个对话就在操作这台服务器;每个对话各自绑定,一个窗口操作服务器、另一个窗口照常写代码 | | 真实连接状态 | 头部方块 灰 没选 · 黄 连接中 · 绿 已连上 · 红 连不上;连不上直接说原因,带「重试」 | | 对话里的终端 | 真终端(xterm.js + ssh -tt),菜单脚本、top、vim 都能用;红黄绿三键结束 / 最小化 / 最大化;最小化、切对话不丢内容,断线自动接回 | | 对话里的状态页 | 一页看清服务器怎么样:先列规则判出的「需注意」(服务失败、磁盘快满、证书快到期、待装安全更新),再是环形图、磁盘、服务、容器、端口、防火墙等;点 让 AI 解读,DSH 的默认模型用几句话说清楚。可以扩展到 DSH 的右侧栏一直开着、边聊边看,看得见时每分钟刷新,还能切换看你的任何一台机器 | | 对话里的文件管理 | 服务器上的「访达」:拖进来上传、右键下载、双击编辑、删了进回收站能还原;覆盖和编辑前自动备份;右键「让 AI 看看这个文件」 | | AI 操作服务器 | 5 个工具,按风险分级确认:只读自动、改动问你、高危再问;档位可按机器、分组、全局设置 | | 三道保护 | 改文件先备份、校验失败自动还原;改防火墙和 SSH 前设连通性保险;长操作跑成远端任务,断线不中断 | | 按系统写命令 | 体检出系统、包管理器、init、权限、在跑的服务和容器,告诉模型按这台的实际情况写命令 | | 菜谱库 | 29 条可重复执行的菜谱(安装 7 · 配置 6 · 查询 16),AI 做成的事可以一句话存成菜谱 | | 设置页 | 一页表单添加机器(填一次密码,自动放好钥匙,密码不保存)、从 ~/.ssh/config 导入、基础配置、终端设置、卸载 | | 三个平台、两种 DSH | Windows、macOS、Linux;DSH Desktop 与 dsh web。终端连接过 DSH 登录校验、同源检查和插件令牌,默认只许本机打开 | | 几台电脑一起管 | 每台电脑各有钥匙;改动在服务器上排队,写明是哪台电脑在改;回收站、备份、任务记录共用;卸载只撤销自己的钥匙 | | 中文 / English | 界面跟着 DSH 设置里的语言走,切换后立刻变,不用刷新;服务端的提示、/vps- 命令的输出、菜谱名字也跟着变 | | 装起来轻 | 不用原生模块(不编译 node-pty),运行时依赖只有 ws 与 yaml | 截图 三张截图在这里轮流显示(1 → 2 → 3);点图片到项目网页上一张张点着看。原图:1 · 2 · 31 设置 → VPS 管理:编号的机器清单 · 2 对话下方是文件管理,右侧栏常驻「VPS 状态」 · 3 常用入口都在哪 从装插件到接上第一台机器的完整过程(演示里的地址、用户名已涂去) 目录 - 三种用法 · 运行要求 · 各平台 · 安装 · 添加机器 · 几台电脑管同一台服务器 - 在对话里选机器 · 对话里的终端 · 对话里的文件管理 · 对话里的状态页 · 命令 · 跟 AI 说话 - 菜谱 · 设置页 · 运行机制 · 它防不住什么 - 数据放在哪 · 反馈与建议 · 仓库内容 · 开发 三种用法 | | 看信息 | 跟 AI 说话 | 按菜谱安装与维护 | | 怎么用 | /vps-sysinfo 这类命令 | 「给这台装个 nginx,把 a.com 反代到 3000 端口」 | /vps-install <菜谱id> 看计划,/vps-yes 执行 | | 走不走模型 | 不走 | 走 | 不走 | | 花费 | 零 token | 正常消耗 token | 零 token | | 能做什么 | 固定的只读查询 | SSH 能做的都能做,按风险分级确认 | 29 条可重复执行的菜谱 | 运行要求 - DeepSeek Harness 0.1.5-rc.2 及以上(到 0.2.x),DSH Desktop 和 dsh web 都可以 - Windows、macOS、Linux 任一系统(见下面的各平台) - Node.js >= 22.13 - 日常一律用 SSH 钥匙登录。 密码只在添加机器时用一次(把钥匙放上去);不支持需要输密码的 sudo - 会改系统的操作要求远端用户是 root 或有免密 sudo;只读查询不需要 各平台 | | Windows | macOS | Linux | | SSH 客户端 | 系统自带的「OpenSSH 客户端」。Windows 10 / 11 一般已经装好,没有的话到「设置 → 系统 → 可选功能」添加 | 系统自带 | 系统自带;没有就装 openssh-client | | 连接速度 | Windows 版 OpenSSH 不支持连接复用,每条命令单独连一次,多零点几秒 | 复用一条连接,几十毫秒 | 复用一条连接,几十毫秒 | | 终端里复制 | 选中文字后 Ctrl+C(没选中时 Ctrl+C 是中断) | ⌘C | 选中文字后 Ctrl+C | | 数据位置里的 ~ | 用户目录 C:\Users\你的用户名 | 家目录 | 家目录 | | 怎么验证的 | 每次推送代码,在 GitHub 的 Windows 2022、2025 上连真的服务器走完整流程 | 作者日常使用 | 每次推送代码连真的服务器走完整流程;每 6 小时拿最新 DSH 做兼容性检查 | 功能在三个平台上完全一样:命令、AI 操作、终端、文件管理、菜谱、设置页、卸载都一样用。 界面语言跟着 DSH 走:在 DSH 设置 → 通用设置 → 语言里选中文或 English,插件的设置页、对话头部、终端和文件面板立刻跟着变;服务端的报错和提示、/vps- 命令的输出、菜谱的名字和计划也用同一种语言。DSH 目前自带的就是这两种;装了别的语言包时,按语言包声明的退回语言显示中文或英文。 安装 插件市场:在 DSH 的插件市场(dshmarket)里搜索 dsh-vps-manager,点安装。DSH Desktop 和 dsh web 都可以。 命令行:先完全退出 DSH,再按你用的 DSH 执行: 官方桌面版 DeepSeek Harness dsh plugin --profile desktop add dsh-vps-manager 命令行版 dsh web dsh plugin --profile web add dsh-vps-manager - 官方桌面版要用它自带的 dsh 命令:在应用菜单「管理 dsh 命令…」里安装。npm 装的 dsh 改不了桌面版的插件。 - --profile 必须写在 add 前面。DSH 0.2.0 起不带它会报 required option '--profile <name>' not specified。 想装 GitHub 上的最新代码(可能比 npm 上发布的版本新),把包名换成 github:AIcivilization/dsh-vps-manager。 装好后打开 DSH,插件在 DSH 启动时加载。每个版本改了什么,见 Releases。 卸载:打开 DSH 设置 → VPS 管理,拉到最下面点「卸载…」(见设置页)。也可以完全退出 DSH,在终端执行 dsh plugin --profile desktop remove dsh-vps-manager(dsh web 换成 --profile web),再打开 DSH;这样只移除插件,机器清单、钥匙、SSH 配置和审计日志都会留着。 添加机器 打开 DSH 设置 → VPS 管理 →「+ 添加机器」,一页表单: - 服务器:IP 或域名、SSH 端口、用户名、密码 - 怎么称呼它(选填):别名(不填就按地址自动起)、分组、备注 点 「保存并连接」: 1. 插件生成一把专用钥匙 ~/.ssh/dsh_vps_ed25519(不动你原有的钥匙) 2. 用你填的密码登录一次,把这把钥匙的公钥放进服务器的 ~/.ssh/authorized_keys(已经有就不重复加) 3. 连接配置写入 ~/.ssh/config.d/dsh-vps.conf,在 ~/.ssh/config 最顶部加一行 Include(改之前备份为 ~/.ssh/config.dsh-bak),然后用钥匙连一次、体检一次 4. 显示结果和主机指纹(首次连接时记录,以后指纹变了会拒绝连接,防止有人冒充你的服务器) 密码只用这一次,不保存:它只放进那一次 ssh 子进程的环境变量,经 SSH_ASKPASS 交给 ssh,不写进任何文件、日志或审计记录;之后一律用钥匙登录。带密码的添加只能在运行 DSH 的这台电脑上操作(从别的设备发,密码会经过网络)。 密码不对、服务器不允许密码登录、指纹变了,都会在表单里直接说明。服务器只允许密钥登录的,展开表单下面的「没有密码?」:复制公钥粘到服务商后台的「SSH 密钥」里,或者复制一行命令到已经能登录的服务器上执行,放好后点「公钥已经放好了,直接连接」。 ~/.ssh/config 里已有的机器,可以用「从 ~/.ssh/config 导入」直接接管。插件不会改写你自己写的 ~/.ssh/config 内容。 Windows 上路径一样,只是 ~ 指你的用户目录(比如 C:\Users\你的用户名)。 几台电脑管同一台服务器 Windows、Mac、Linux 上的 DSH 可以各装一份插件,同时管同一台服务器,互不干扰: - 每台电脑有自己的钥匙,所以每台电脑上都要添加一次(各填一次密码)。服务器的 authorized_keys 里会有几行,备注是 dsh-vps-manager@电脑名,一眼看出是哪台电脑的 - 会改东西的操作在服务器上排队:一台电脑的改动任务没做完,另一台发起的改动会提示「另一个改动任务在跑」,并写明是哪台电脑发起的。查询、终端、浏览文件不受影响 - 服务器上的任务记录、改文件前的备份、文件页的回收站是大家共用的:在 Mac 上删进回收站的文件,在 Windows 上也能还原 - 两台电脑编辑同一个文件:后保存的那台会提示「文件已经被改过」,不会悄悄覆盖 - 在一台电脑上卸载:只撤销这台电脑的钥匙;别的电脑还在用这台服务器时,服务器上的共用目录保留 在对话里选机器 对话头部有一个 VPS 开关:VPS 后面先是终端按钮 >_,再是每台机器一个小方块。方块里写着编号(第一台 1,第二台 2,依次类推),和设置页里的一致。 - 方块的颜色是真实的连接状态,不只是「选没选」: - 灰:这个对话没选这台 - 黄(闪):选了,正在连接 - 绿:选了,而且刚测过连得上 - 红:选了,但连不上。输入框下方写明原因(比如「SSH 配置里找不到这台机器」),旁边有「重试」;鼠标停在方块上也能看到原因 打开开关、打开这个对话、切回 DSH 窗口时都会现测一次(走复用连接时几十毫秒,Windows 上零点几秒);命令、AI 工具、终端每次连服务器的成败也会记下来,方块跟着变 - 点一个方块:这个对话进入 VPS 模式。之后的 /vps- 命令都作用在这台机器上;插件还会告诉模型「这个对话在操作哪台、是什么系统(包管理器、init、权限)、80/443 端口被哪个程序占着、在跑哪些服务和容器」,以及几条必须遵守的规矩(名字不许猜、systemd 管的服务只用 systemctl、查不到不许改成重启重装),模型按这个系统写命令,你说「这台」「服务器」它就知道指哪台 - VPS 模式下模型不能用本机 bash:一调用就会被拦下,并提示它改用 VPS 工具。这样模型不会把服务器上的问题拿到你的电脑上去查。读文件、搜索这类工具不受影响 - 再点一次:退出 VPS 模式,方块变灰,本机 bash 恢复。没有绑定时没有任何默认机器:命令不执行,AI 必须写明要操作哪台 - 每个对话同一时间只能绑定一台;绑定只对当前对话有效:一个窗口开着 VPS 模式操作服务器,另一个窗口照常写本机代码,互不影响 - 也可以用命令:/vps-use <别名> 绑定,/vps-use off 解除 - 还没体检过的机器,打开开关时会在后台自动体检一次,让模型拿到系统信息 输入框下方平时不显示任何内容,只有这三种情况才出现一行提示:这台机器上有任务在跑、机器连不上、磁盘用到 85% 以上。 对话里的终端 对话头部 VPS 后面的 >_ 按钮就是终端。绑定机器后点一下,输入框下方出现一个真正的终端,跟在 SSH 里操作一样(只有一台机器时,没绑定也可以直接点,会顺手绑上): - 菜单脚本、top、htop、vim、docker exec -it、mysql 这类要反复按键的程序都能用,Ctrl+C、方向键、中文正常。复制:Mac 用 ⌘C;Windows、Linux 选中文字后按 Ctrl+C(没选中时 Ctrl+C 照常是中断) - 终端右上角三个圆按钮: - 红色 ×:结束这个终端,服务器上的 shell 和里面正在跑的程序一起结束 - 黄色 −:最小化成输入框下方的一条横栏(显示「终端在后台运行 · 已开 N 分钟」),终端在后台继续跑;点横栏恢复 - 绿色:最大化,终端撑满对话区,输入框被推到最上面;再点一次(或双击标题栏)恢复原来大小 - 顶部 >_ 仍是开关:没开 → 打开;开着 → 最小化;最小化 → 恢复。最小化时它的右上角有个小绿点 - 最小化、切到别的对话再回来,终端和里面的内容都还在 - 刷新页面或网络断开:服务器把终端保留一段时间(默认 10 分钟,可在设置里改),期间回来会自动接上,断开期间的输出也补回来;超过时间才结束 - 普通大小时右下角可以拖动调高度,全屏程序会按新尺寸重画;高度会记住 - 关掉 VPS 开关或换到另一台机器,这个对话的终端随之结束 - 这里敲的内容和输出不经过 AI;想让 AI 看结果,用 /vps-sh 执行 - 每次打开、结束记一行审计日志(不记录按键内容) 设置(DSH 设置 → VPS 管理 → 界面):颜色方案(跟随系统 / 暗色 / 白色,跟随系统即与 DSH 的外观一致)、字号(11–20)、断线后保留多久(5 分钟 / 10 分钟 / 30 分钟 / 1 小时)、是否允许从其他设备打开。 DSH Desktop 和 dsh web 都能用,终端连接跟着页面地址走(https 页面自动用加密连接)。连接要过三道检查:DSH 自己的登录校验、来源必须是 DSH 页面本身、页面里的插件令牌。另外默认只能在运行 DSH 的这台电脑上打开:用局域网地址或反向代理访问 dsh web 时,要先在 DSH 设置 → VPS 管理 → 界面 里勾选「允许从其他设备打开 VPS 终端」。终端等于这台服务器的完整操作权限,只在你信任访问途径时打开。 实现上不需要本机编译任何原生模块:服务器那头的伪终端由 ssh -tt 申请,窗口大小改变时另开一条 SSH 连接调整。终端显示用的是 xterm.js(MIT 许可,随插件附带,第一次打开终端时才加载)。 对话里的文件管理 终端面板标题栏上有 「终端 | 文件 | 状态」 切换,切到「文件」就是服务器上的「访达」,操作的是这个对话绑定的那台机器: - 浏览:左边是常用位置(家目录、网站目录、/etc、/var/log、根目录、回收站),上面是可点的路径,点空白处可以直接输入路径(~ 表示家目录);列名可排序;以 . 开头的文件默认不显示,点「显示隐藏文件」 - 上传:把电脑上的文件直接拖进来,或者点「上传」,有进度条、能取消。覆盖同名文件前会问一句,原文件先备份到服务器的 ~/.cache/dsh-vps/backups/,权限和属主保持不变;新文件按 644、新文件夹按 755,网站程序读得到。传一半断了,原文件不受影响 - 下载:右键「下载」,底部显示进度、能取消;文件夹会边打包边下载成 .tar.gz。电脑上装了下载工具(IDM、Folx 这类)也不影响 - 编辑:双击文本文件(1 MB 以内)直接打开编辑,⌘S / Ctrl+S 保存,保存前自动备份;打开之后如果文件被 AI 或别人改过,会提示你重新加载还是覆盖。改 sshd_config、防火墙这类改错会连不上的文件,顶部会标出来 - 删除:进服务器上的回收站(~/.cache/dsh-vps/trash),能还原;彻底删除和清空回收站要再确认一次。系统顶层目录(/etc、/usr 这类)不让删 - 让 AI 看看这个文件:右键点它,文件内容打码后交给 AI,并替你在对话里发一句「看看这个文件」,AI 马上开始看,结果就在对话里;之后可以接着问(比如「这个配置哪里不对」)。输入框里有你还没发出去的话时不替你发,你发出去时 AI 会一起看到这个文件。大文件(日志)只给最后 48 KB - 还有:新建文件夹、改名、复制路径、「在终端打开此目录」(切回终端并 cd 过去) - 每次上传、下载、编辑、删除、还原都记审计日志。和终端一样,默认只能在运行 DSH 的这台电脑上打开 - 以 SSH 登录的账号操作,不提权:这个账号改不了的地方会如实提示「没有权限」 对话里的状态页 终端面板的第三个页签 「状态」,一页看清这个对话绑定的那台服务器怎么样: - 切到这个页签时看一遍(约 2 秒,只读),之后只在点 ↻ 时刷新。面板打开时还是先显示「终端」,不切到「状态」就不采集 - 最上面是结论(「需注意 3 项」或「一切正常」),还有主机名、系统、内核、已运行多久、权限;下面绿色那一行数一数、列一列正常的项 - 「需注意」由固定规则判断,不用模型:服务失败或设了开机自启却没在跑、定时任务上次失败、可用内存低于 10% / 5%、swap 用了一半以上、磁盘或 inode 到 85% / 95%、负载超过核数、退出了又不会自动重启的容器、快到期的证书(按证书本身的有效期算,几天就换的 IP 证书不会一直被标出来)、待装的安全更新、需要重启、24 小时登录失败 100 次以上且没有 fail2ban。每一行有 看日志(服务和容器:在终端里显示最近 50 行)、打开(磁盘:在「文件」里打开那个目录)和 问 AI(把这一项交给对话) - 其余部分:CPU、内存、Swap 用环形图,加上开机以来的流量;每个磁盘一条用量;再往下是按内容排的卡片,每张多高就占多高:服务、容器(状态和镜像)、最占 CPU 和内存的进程、监听端口(对外和只在本机分开)、防火墙、计划任务、证书(剩几天和有效期细条)、安全,以及插件自己的回收站和备份。默认高度下这些收成一行,最大化面板或点 展开全部 才显示 - AI 解读:点 让 AI 解读,DSH 的默认模型读一遍采到的数据,用几句话说这台机器怎么样、最要紧的是什么。点了才调用模型,按界面语言回答,并注明是根据哪一次采集说的;在对话里追问 把它带进对话接着问 - 不想看的可以收起:除了 CPU、内存那一排和磁盘,每一块右上角都有一个倒三角,点它(或点那一块的标题)就收成一行,项数、摘要和轻重颜色还在。收起哪些存在本机,底部面板和右侧栏共用 - 非 root 用户读不到的(容器、防火墙、登录失败)直接说读不到,不去猜 - 最近一次采集和解读存在本机($DSH_HOME/vps-manager/status/),再打开立刻显示;你的每台电脑各存各的 - 看一遍的同时,也会刷新 VPS 模式告诉 AI 的机器信息(在跑的服务、容器、80/443 被谁占) 在右侧栏常驻 切到「状态」页签时,面板标题栏三个圆点左边有一个「方框中间一道竖线」的按钮,点它就把状态页放进 DSH 自己的右侧栏(文件、文档预览用的那一栏):和对话并排,边聊边看,一直开着;切到别的对话再回来、刷新页面都还在。右侧栏的开始页里也有 「VPS 状态」 入口。 - 顶上一排编号方块选看哪台,编号和对话头部一致。颜色是那台机器的连接状态,本对话操作的那台下面有一道线;上次看有需注意的项,方块右上角有个小红点或小黄点(悬停看是什么时候看的) - 选别的机器只是「看」,这个对话操作的还是原来那台。顶上会写清楚,旁边有 「让这个对话改用 N 号」(和点头部方块一样)。看别的机器时,会对它动手的按钮(问 AI、看日志、在对话里追问)不显示,「让 AI 解读」照常能用 - 看得见时每分钟采一次;右侧栏收起、切到别的页签、窗口最小化时不采;重新看见时,上次超过一分钟就马上采一次。连不上的机器也只是一分钟试一次,不会连着重试 - 底部面板和右侧栏看同一台时用的是同一份数据,不会采两次 - 需要带右侧栏的 DSH(0.2 起);老版本没有这个按钮,其他照旧 网络体检 状态页的卡片里第一张是 「网络」。点 开始体检(约 30 秒,不花 token),一项一行告诉你实际能不能用,数字收在 详细数据 里: - 国内能不能连:请 Globalping 公共探测网络(jsDelivr 运营,免费)从国内电信、联通、移动的节点,用 TCP 连这台的 SSH 端口和对外开放的端口(最多 3 个),同时从美国、日本、德国连一次对照。能分清"被墙了""只封了某个端口""某家运营商连不上"和"端口没开、不是墙的问题"。会把服务器地址交给它,每小时最多 250 次。UDP 端口(Hysteria2、TUIC 这类代理)测不了 - ChatGPT、Claude:用这台的 IP 访问它们的 API 地址(不带密钥),按返回判断"能用"还是"不支持这个地区" - Gemini、谷歌认为你在哪:读谷歌对这台 IP 的判断,Gemini 按它推断。谷歌认为在中国大陆(俗称"送中")会单独标红 - YouTube 会员、Netflix、Disney+:能不能开、是哪个区;Netflix 分清"全部片库"和"只能看自制剧" - IP 干不干净:Cloudflare、OpenAI、谷歌、ipinfo、ip-api、Netflix 各认为你在哪个国家,不一致就是"广播 IP",容易被误判地区;是不是机房 IP;有没有上主要的垃圾邮件黑名单 - 判断全用固定规则;连不上某个网站、或者返回了没见过的内容,就写"说不准",不硬猜 - 服务器上只用 curl,不装任何东西。结果存本机($DSH_HOME/vps-manager/net/,每次另存一份,保留 90 天);也可以发 /vps-netcheck 在对话里看 「网速」卡片:在你这台电脑上测,以你的签约带宽为 100%(在卡片里填一次,比如 1000)。 - 走代理上网:照常发请求,交给你电脑上的代理软件(小火箭等)按规则走,用 fast.com 的 Netflix 测速服务器测下载、单个连接、上传和延迟;测完核对出口确实是这台 VPS - 直连这台(不走代理):绕开代理软件(绑定物理网卡,域名用阿里 DNS 查真实 IP),直接连这台。测带宽要在服务器上临时开一个端口,防火墙只对你家的 IP 放行,测完就关、规则撤掉,记进审计日志;第一次会先问你同不同意。云厂商安全组挡住时退回经 SSH 测(会偏低,结果里写明)。测完还核对服务器看到的来源是不是你家 - 结论:满速 / 还行 / 慢和百分比条;够不够 8K、4K、视频通话、打游戏;慢在哪(代理协议或 CPU、线路本身、VPS 出口),有晚上和白天的记录时还会比一比 - 一次大约用掉 1~2 GB 流量(看速度)。结果存本机($DSH_HOME/vps-manager/speed/,保留 90 天) 「挑机器」卡片:挑 VPS 服务商时用。填几台候选机器的 IP、域名或商家 Looking Glass 地址(点「+」加一行,最多 10 个),从你这台电脑直连测(不走代理),放在一起比: - 延迟、抖动、丢包(ping 被挡就看 TCP 建连接的时间) - 填 Looking Glass 页面的,自动在页面里找测试文件(优先 100MB 的)测下载速度,多个连接和单个连接各一次;只填 IP 的会试几个常见的测试文件名 - 一句推荐(下载最快、延迟最低),下面附上你现在用的这台当参照。下载一个一个测,免得互相抢你家的带宽 卡片上的「+AI」:网络、网速、挑机器、端口、防火墙、安全六张卡的标题行右边有一个蓝紫色的 +AI。点它把这张卡的结论和关键数字整理成一段话发进对话,AI 在对话里回答,你可以接着问、让它动手。只发结论不发原始数据,也不发你家宽带的 IP;右侧栏在看别的机器时不显示。整页的解读照旧用顶上的「AI 解读」 命令 命令不走模型、不花 token。DSH 会把命令结果收成一行,所以每条结果的第一行就是结论。 两条使用规则: 1. 命令作用在当前对话绑定的机器上;没有绑定就不执行。 2. 下表里没写参数的命令,只发命令名本身。 DSH 只会把声明了参数的命令后面的文字交给插件。在不收参数的命令后面加字,整句会被当成普通消息发给模型。需要确认的操作都是先出计划,再单独发 /vps-yes。 自己敲的命令会附给 AI:DSH 本身不会把命令结果交给模型。插件会记下你用 /vps-sh 执行的最近几条命令和输出(令牌、密码、私钥等先打码),在你下次跟 AI 说话时一起附上。所以你可以先自己查,再直接问「看看上面为什么报错」。不想附上的那条,在命令前加 --private。 入口 | 命令 | 作用 | | /vps-help | 全部命令与用法 | | /vps-yes | 确认刚才的计划:重启、安装,或被拦下的高危命令。只对当前对话有效,5 分钟内有效,执行一次后作废 | 看信息 | 命令 | 作用 | | /vps-sysinfo | 系统、CPU、内存、磁盘、负载、公网 IP | | /vps-disk | 挂载点、inode、占用最大的目录(扫描有时间上限) | | /vps-ports | 监听端口和对应进程 | | /vps-services | 正在运行和失败的服务 | | /vps-net | 网卡、累计流量、连接数 | | /vps-docker | 容器列表与磁盘占用 | | /vps-ping | 主机名、系统、负载、运行时长 | | /vps-netcheck | 网络体检:国内能不能连、ChatGPT 等 AI 和流媒体能不能用、IP 干不干净(约 30 秒,见网络体检) | | /vps-logs <服务名> | 某个服务最近 100 行日志 | | /vps-q <菜谱id> | 运行任意一条查询菜谱,如 ip-info、top-procs、cron-list、cert-expiry、firewall-status、updates、login-history | | /vps-sh <命令> | 在机器上执行命令,输出直接显示在对话里:同一个对话里记住 cd 到的目录;top、tail -f、journalctl -f、less、watch 这类会一直刷新或翻页的命令自动改成一次性输出,vim、进入交互 shell 这类做不了的会提示改用终端;判定为高危的先拦下,发 /vps-yes 才执行。前面加 --bg 放到后台跑,加 --private 表示这条输出不附给 AI | 机器 | 命令 | 作用 | | /vps-list | 已登记的机器与状态,★ 标出当前对话绑定的那台 | | /vps-use <别名> | 把当前对话绑定到一台机器;/vps-use off 解除绑定 | | /vps-probe | 重新体检:系统、init、包管理器、权限、CPU、内存、磁盘 | | /vps-reboot | 重启前先检查:为什么该重启(内核或 libc 更新待生效)、现在适不适合重启(包管理器正在装东西、或插件有任务在跑时会拦下)、会停掉哪些容器、它们能不能自己启动。发 /vps-yes 才重启,之后等机器回来,报告内核变化、容器状态和失败的服务;5 分钟后还连不上就提示你去服务商后台查看 | 安装与任务 | 命令 | 作用 | | /vps-recipes | 菜谱清单,按安装 / 配置 / 查询分组 | | /vps-install <菜谱id> [key=value …] | 出计划:检测结果、参数与默认值、步骤、脚本原文。发 /vps-yes 执行 | | /vps-tasks | 这台机器上的远端任务列表 | | /vps-task <任务号> [--stop] | 一个任务的状态和日志;加 --stop 终止它 | 排查 | 命令 | 作用 | | /vps-doctor | 插件与 DSH 版本(是否验证过)、各部分注册情况、当前对话绑定的机器、连通测试、最近的错误与执行;末尾附预填好的反馈链接 | 跟 AI 说话 插件给模型注册了 5 个工具,并附带一份操作规则(skill vps-operator,模型需要时自己读取): | 工具 | 作用 | | vps_hosts | 列出已登记的机器 | | vps_exec | 在机器上执行脚本 | | vps_write_file | 写远端文件:先备份,校验不通过自动还原 | | vps_task | 远端任务:列表、状态、日志、终止 | | vps_recipe | 菜谱:列表、查看、运行,以及把刚做成的事存成菜谱 | 分级确认 插件在每段脚本执行前判定风险级别。模型自己声明的级别只能往高调,不能往低压。 | 级别 | 例子 | | 只读 | df -h、systemctl status、docker ps、journalctl | | 改动 | apt-get install、sed -i、systemctl restart、写文件 | | 高危 | rm -rf、mkfs、改防火墙(ufw、iptables)、passwd、reboot、杀进程(kill、pkill、killall)、curl … \| sh | 要不要弹确认框,取决于这台机器的确认档位(优先级:机器 > 分组 > 全局): | 档位 | 只读 | 改动 | 高危 | | 谨慎(默认) | 自动 | 问 | 问 | | 放手 | 自动 | 自动 | 问 | | 全自动 | 自动 | 自动 | 自动 | | 没有审批界面的环境 | 自动 | 拒绝 | 拒绝 | 三道保护 - 改文件先备份。 vps_write_file 先把原文件备份到服务器的 ~/.cache/dsh-vps/backups/,再原子写入(覆盖已有文件时权限和属主保持原样),然后运行你给的校验命令(比如 nginx -t),不通过就自动还原 - 连通性保险。 改防火墙、SSH、网络配置之前,先在服务器上设一个定时恢复(默认 120 秒),改完后用全新的连接测试。连不上就等它到时自动恢复,你不会被锁在门外 - 长操作不怕断线。 会改东西的操作跑成远端任务,断线后在服务器上继续,可以再接回来查看。取消只是停止等待,不会杀掉任务;终止任务必须明确发起 菜谱 内置 29 条,每条都可以重复执行: - 安装(7 条):Docker、Nginx、fail2ban、常用命令行工具、Portainer、Uptime Kuma、Nginx Proxy Manager - 配置(6 条):系统更新、系统清理、虚拟内存(swap)、时区、BBR 拥塞控制、自动安全更新 - 查询(16 条):系统信息、磁盘、端口、服务、网络、容器、服务日志、连通与负载、机器体检、出口 IP、资源占用最多的进程、定时任务、证书到期、防火墙状态、可升级的包、登录记录 安装和配置类菜谱都由四部分组成: - detect:判断是否已经装好,或已经是目标状态 - plan:写给人看的执行步骤 - run:执行 - verify:证明真的能用,比如用 docker info 而不是 docker --version 已经是目标状态的菜谱,执行时会跳过安装,直接验证。 参数用 key=value 传入,计划页会列出每个参数和它的默认值: /vps-install setup-swap size_mb=4096 /vps-yes 添加自己的菜谱 - 让 AI 存。 AI 帮你做成一件可以复用的事之后,说一句「存成菜谱」。它会把具体值抽成参数,补上 detect 和 verify;插件检查有没有夹带密码或密钥,然后保存为 $DSH_HOME/vps-manager/recipes/my-<id>.yml - 自己写 YAML 文件,放进这个目录 自定义菜谱的 id 带 my- 前缀,不能覆盖内置菜谱。要修改,就用同一个 id 再存一遍;要删除,删掉对应的文件即可。 自定义菜谱按不可信内容对待:风险级别取「菜谱声明的」和「插件静态判定的」中更严的那个;新增或内容改动后,第一次运行至少按「改动」级别确认一次。 设置页 DSH 设置 → VPS 管理,纯界面操作,不经过模型: - 更新(右上角,版本号旁边):GitHub 上发了新版本,按钮就变成 「更新到 vX.Y.Z」,下面一行提示带「查看更新内容」链接。点它交给 DSH 自己的插件管理器去装(和 DSH「插件」页同一套:带锁运行 pnpm,出错会把配置还原),装好后完全退出 DSH 再打开就是新版。npm 上还没同步到新版时按钮先等着;装失败会写清原因,并给出可以自己运行的 dsh plugin add 命令。查到的结果存 6 小时,点按钮马上重查 - 机器列表:编号(与对话头部的方块一致)、地址、权限、分组、备注;可一键测试连通 - 添加机器,以及从 ~/.ssh/config 导入 - 单台机器设置:别名、地址、端口、用户名、跳板机、放公钥、主机指纹、确认档位、移除机器 - 基础配置:填写想要的状态(时区、虚拟内存大小、BBR、自动安全更新、fail2ban、常用命令行工具),保存时只执行和当前状态不一样的项,每项作为一个远端任务执行,显示进度 - 全局设置:默认确认档位、连通性保险时长;当 DSH 的 Web 服务对局域网开放时,是否允许在设置页执行会改动服务器的操作 - 界面:颜色方案(跟随系统 / 暗色 / 白色)、字号、断线后保留多久、是否允许从其他设备打开终端(默认不允许) - 在手机、平板上也用 DSH:两行介绍姊妹项目 dsh-vps:把 DSH 装进你的 VPS,手机、平板用浏览器就能访问;带 GitHub 链接,也可以在插件市场搜索 dsh-vps。已经装了 dsh-vps 时,改为提示到设置左侧「VPS 部署」里部署 - 反馈与建议:「反馈问题」「提建议」一键打开预填好的 GitHub 问题单;诊断信息(插件与 DSH 版本、各部分注册情况、最近的错误,已打码)平时收起,点「诊断信息」才显示 - 数据位置 - 卸载:勾选要做的事,确认后执行,每一步显示结果。插件本身最后移除:官方桌面版 DeepSeek Harness 交给 DSH 自己的插件管理器(移除时这个设置页会随之消失,完全退出 DSH 再打开就干净了),旧版 DSH Desktop 用它自己的服务移除并一键重启;其他环境会给出要在终端执行的命令 - 移除插件本身(默认勾选) - 移除 SSH 连接配置(默认勾选):去掉 ~/.ssh/config 顶部插件加的 Include 行,config.d/dsh-vps.conf 改名留作备份,两者都能找回 - 清理服务器上的插件目录 ~/.cache/dsh-vps(有任务在跑的机器会跳过;别的电脑上的插件也在管的机器会保留,因为这个目录是共用的) - 撤销这台电脑的插件钥匙在服务器上的登录权限(从 authorized_keys 删掉这台电脑那一行,先备份;别的电脑的钥匙不动)。如果这把钥匙是你登录某台服务器的唯一方式,撤销后就登不上了 - 删除插件专用钥匙、删除插件数据(机器清单、审计日志、自定义菜谱),删了不能恢复 服务器上的项会先做,因为本机的配置和钥匙一删就连不上服务器了。除了前两项,其他默认都不勾选 设置页的后端接口只接受同源的 JSON 请求,并校验 DSH 每次启动时随机生成的 token;接口不提供任意命令执行,也不能随意改文件。 当 DSH 的 Web 服务绑定在 0.0.0.0 时,会改动服务器的操作默认关闭。 运行机制 - 一个引擎,三个入口:设置页、/vps- 命令、AI 工具都走同一套执行引擎。脚本经 SSH 的标准输入送到服务器,先落成文件再执行,远端命令行里不拼任何外部数据 - 连接复用:同一台机器共用一条 SSH 主连接(OpenSSH ControlMaster),命令和连接检测走复用连接时只要几十毫秒。Windows 自带的 OpenSSH 不支持复用,改为每次新连 - 远端任务:会改东西的操作在服务器的 ~/.cache/dsh-vps/ 下跑成任务,带锁,断线后继续;可以随时接回来看日志 - 几台电脑:锁、任务记录、备份、回收站都放在服务器上,几台电脑上的插件看到的是同一份,改动自动排队 - 终端:伪终端由 ssh -tt 在服务器上申请,浏览器经 WebSocket 连到插件;连接断了会话保留一段时间,接回时从断开处补发输出 - 给模型的说明:对话进入 VPS 模式时,插件把这台机器的系统、服务、容器和必须遵守的规则附给模型;模型在 VPS 模式下不能用本机 bash 它防不住什么 - 分级确认防的是 AI 失误,不防存心绕过的 AI。 静态判定识别不了所有变形写法,模型也可以用 DSH 自带的 bash 工具直接 ssh 到服务器 - DSH 的沙箱管不到这个插件自己启动的 ssh 进程 - 终端里的操作不分级确认。 那是你自己在敲命令,跟直接用 SSH 一样,插件不拦截 - 没有通用回滚。 能兜底的只有文件备份、连通性保险和可重复执行的菜谱。重装系统、升级大版本、动分区之前,请先到服务商后台打快照 数据放在哪 | 位置 | 内容 | | $DSH_HOME/vps-manager/hosts.yml | 机器清单、分组、确认档位(可以手工编辑) | | $DSH_HOME/vps-manager/state.json | 体检结果、各对话绑定的机器 | | $DSH_HOME/vps-manager/status/ | 「状态」页最近一次采集和 AI 解读,每台机器一个文件 | | $DSH_HOME/vps-manager/recipes/ | 你自己的菜谱 | | $DSH_HOME/vps-manager/audit/ | 审计日志:每次执行一行 JSON(来源、机器、动作、档位、结果),按月分文件,保留 6 个月 | | ~/.ssh/config.d/dsh-vps.conf | 插件维护的 SSH 连接配置 | | ~/.ssh/dsh_vps_ed25519 | 插件生成的专用钥匙 | | 服务器上的 ~/.cache/dsh-vps/ | 远端任务目录、日志、文件备份、回收站(几台电脑共用) | $DSH_HOME 默认是 ~/.dsh;Windows 上 ~ 指用户目录(C:\Users\你的用户名)。 插件不读取私钥内容。添加机器时填的密码只用那一次,不写进任何文件,也不保存。 反馈与建议 - 遇到问题:在 DSH 里发 /vps-doctor,或点 设置 → VPS 管理 → 反馈问题。会打开 GitHub 上已经预填好插件版本、DSH 版本和诊断信息的问题单,你看过、改好再提交。诊断信息已打码,不含机器地址;插件不会自动上传任何东西 - 提建议:新建建议 - DSH 升级后不能用:插件每 6 小时会自动拿 DSH 的正式版、下一版、尝鲜版各测一遍(装上插件、启动网页版、逐项检查),测不过会自动开问题单,见 兼容性问题。当前 DSH 版本没验证过时,设置页和 /vps-doctor 会提示 插件自己出的错(注册失败、接口报错、界面组件出错)记在本机的 $DSH_HOME/vps-manager/logs/,打码后保存,保留 3 个月。 仓库内容 | 文件 | 作用 | | lib/index.js | 插件入口:注册工具、命令、skill、VPS 模式、设置页路由与终端 | | lib/commands.js | 22 条 /vps- 命令 | | lib/tools.js | 给模型的 5 个工具 | | lib/risk.js · lib/safety.js | 风险判定、分级确认、连通性保险 | | lib/engine.js · lib/payload.js · lib/prelude.sh | 执行引擎:载荷、远端任务、跨系统的前导脚本 | | lib/actions.js · lib/task.js · lib/files.js | 体检、执行、远端任务、改文件(备份 + 校验 + 还原) | | lib/recipes.js · lib/recipe-store.js · recipes/ | 菜谱的加载、执行、保存;29 条内置菜谱 | | lib/vps-mode.js · lib/skills/vps-operator.md | VPS 模式与给模型的操作规则 | | lib/terminal-server.js · lib/vendor/xterm/ | 对话里的终端(服务端)与附带的 xterm.js | | lib/terminal.js | /vps-sh 迷你终端:记住目录、交互命令改写、打码 | | lib/reach.js | 连接状态检测(头部方块的颜色) | | lib/health.js · lib/verified-dsh.json | 插件体检:各部分注册结果、DSH 版本验证状态、本地错误记录、反馈链接 | | scripts/compat-smoke.mjs · scripts/install-dsh.sh · .github/workflows/dsh-compat.yml | 兼容性检查:装上插件、启动真实 DSH 网页版逐项检查,每 6 小时跑一遍 DSH 的三个通道。DSH 刚发版、npm 上还缺包时隔 10 分钟重装,最多 4 次,不误报 | | lib/client.js | 界面:头部开关、终端面板(终端、文件、状态)、输入框下方提醒、设置页 | | lib/status.js | 「状态」页:只读采集脚本、判断规则、本机缓存、AI 解读 | | lib/netcheck.js | 「网络」卡片(网络体检):VPS 上的只读检查、国内连通(Globalping)、判断规则 | | lib/speedtest.js | 「网速」「挑机器」卡片:在这台电脑上测走代理 / 不走代理的速度,VPS 上的临时测速服务,候选机器对比 | | lib/update.js | 设置页的「更新」:查 GitHub 和 npm 上的最新版本,交给 DSH 的插件管理器安装 | | lib/routes.js | 设置页接口 | | lib/config.js · lib/onboarding.js · lib/ssh.js | 机器清单、SSH 配置、添加机器、ssh 参数 | | lib/reboot.js · lib/uninstall.js · lib/audit.js | 重启并等机器回来、卸载、审计日志 | | test/ | 339 个测试 | | scripts/windows-e2e.mjs · .github/workflows/platform-e2e.yml | 跨平台实测:在 GitHub 的 Windows 和 Linux 电脑上连真的 sshd,把添加机器、执行命令、文件页、状态页、终端、卸载走一遍 | 开发 npm install npm test 339 个测试,不需要真实服务器:用本机的 sh -s 代替远端 sshd,覆盖载荷协议、远端任务、并发锁、备份还原、风险判定、VPS 模式、卸载、命令、设置页接口、终端连接(鉴权、本机限制、输入输出、窗口大小、断线保留与接回、结束清理)、状态采集脚本与判断规则,以及界面渲染。装了 DSH Desktop 的机器上,还会拿 DSH 自带的 dsh-tools、dsh-skill、dsh-user-approval 核对工具定义、返回值、skill 字段、审批结果词汇,以及插件插入对话的那条说明能不能被宿主的会话格式收下。 另有跨平台实测:每次推送代码,GitHub 的 Windows(2022、2025,系统自带的 OpenSSH)和 Linux 电脑各连一台真的 sshd,用密码添加机器、执行命令、跑远端任务、在文件页上传下载编辑、开终端调窗口大小、卸载时撤销钥匙,全程和用户操作的路径一样。 许可 MIT 附带的第三方代码:lib/vendor/xterm/ 下是 xterm.js 6.0.0 与 addon-fit 0.11.0,MIT 许可,版权归 xterm.js 作者,许可原文见 lib/vendor/xterm/LICENSE。
预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
AIcivilization/dsh-vps-manager
在 DSH 中和 SSH 一样无感地使用 VPS,除了精选的部分常用命令之外,使用时还能让对话中的大模型对 VPS…
相关插件 · 市场 / 管理
插件精选列表awesome-dsh-plugin/awesome-dsh-plugin
DeepSeek Harness(dsh)插件精选列表
★ 22,025未汉化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,358已汉化DSH
71.9
插件市场目录imsai-sh/awesome-deepseek-harness-plugins
面向 DeepSeek Harnessdsh生态的社区插件目录,共收录 13938 个插件含 PR 收录与…
★ 350已汉化DSH
71.8
插件精选清单Anil-matcha/awesome-dsh-plugin
DeepSeek Harnessdsh精选指南——DeepSeek…
★ 1,013已汉化DSH
71.7
这是你的仓库?认领条目