🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

版本角标与一键更新 Z-6354/dsh-version-autoupdate

DeepSeek Harnessv0.3.61
Z-635417 天前有提交已提供中文文档扫描:含敏感能力

0.3.61:兼容与更新结果

32.1/100
综合分
3
GitHub 星标
161
npm 周下载
—/5
用户评分

数据截至 2026/10/20 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add dsh-version-autoupdate
npm 源 · dsh-version-autoupdate 的发布者账号已校验与本仓库一致

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么[目录]—
dsh 原生插件 · dev
暂无时间戳·判据 →
装得上吗[实装验证]✓
本站已在 dsh 0.2.1-rc.2 下真实安装成功
非静态推断
L5 · 运行时冒烟等级说明 →
数据截至 2026/10/29·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/04·判据 →
还在维护吗[仓库]✓
活跃:最近一次提交在 17 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →

可信度证据

安装兼容性检查✓ 自动检查通过
展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✓npm 包dsh-version-autoupdate @ 0.3.61
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/22 11:44:32

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 135 处,展示前 120 条)
  • 读取本地文件
    lib/index.js:71
    const pkg = JSON.parse(readFileSync(p, 'utf8'));
  • 发起网络请求
    lib/index.js:170
    const res = await webSvc.fetch({ url: registryUrl });
  • 发起网络请求
    lib/client.js:21
    `;var z=D(require("react"),1);function k(e){return z.createElement("div",{style:{display:"flex",justifyContent:"space-between",gap:"8px",padding:"1px
  • 读取本地文件
    lib/npm-install-target.js:30
    const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'));
  • 读取本地文件
    lib/dsh-restart.mjs:39
    try { return /\.service(?:\/|$)/m.test(readFileSync('/proc/self/cgroup', 'utf8')) && Boolean(process.env.INVOCATION_ID || process.env.SYSTEMD_EXEC_PID
  • 读取本地文件
    lib/dsh-restart.mjs:45
    if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
  • 写入本地文件
    lib/dsh-restart.mjs:45
    if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
  • 写入本地文件
    lib/dsh-restart.mjs:53
    writeFileSync(p, `[${new Date().toISOString()}] ${line}\n`, { flag: 'a', encoding: 'utf8' });
  • 读取本地文件
    lib/dsh-restart.mjs:69
    if (existsSync(candidate)) return candidate;
  • 读取本地文件
    lib/dsh-restart.mjs:79
    if (!existsSync(stateDir)) mkdirSync(stateDir, { recursive: true });
  • 写入本地文件
    lib/dsh-restart.mjs:79
    if (!existsSync(stateDir)) mkdirSync(stateDir, { recursive: true });
  • 写入本地文件
    lib/dsh-restart.mjs:81
    writeFileSync(path, trimmed, 'utf8');
  • 执行外部命令来自配置/变量
    lib/dsh-restart.mjs:93
    const out = execFileSync(
  • 读取本地文件
    lib/dsh-restart.mjs:117
    if (!existsSync(lockFile)) return { handoff: false, lockFile, watchdogPid: null };
  • 读取本地文件
    lib/dsh-restart.mjs:120
    pid = parseInt(String(readFileSync(lockFile, 'utf8')).trim(), 10) || 0;
  • 写入本地文件
    lib/dsh-restart.mjs:502
    writeFileSync(scriptPath, ps, 'utf8');
  • 执行外部命令来自配置/变量
    lib/dsh-restart.mjs:504
    const child = spawn(powershell, [
  • 写入本地文件
    lib/dsh-restart.mjs:583
    writeFileSync(scriptPath, sh, { encoding: 'utf8', mode: 0o755 });
  • 执行外部命令固定命令
    lib/dsh-restart.mjs:584
    const child = spawn('bash', [scriptPath], {
  • 执行外部命令来自配置/变量
    lib/dsh-restart.mjs:652
    const child = spawn(process.execPath, [helper, jobPath], {
  • 读取本地文件
    lib/offline-install.mjs:19
    if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
  • 写入本地文件
    lib/offline-install.mjs:19
    if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
  • 读取本地文件
    lib/offline-install.mjs:34
    const raw = readFileSync(offlineStateFile(), 'utf8');
  • 写入本地文件
    lib/offline-install.mjs:42
    writeFileSync(offlineStateFile(), JSON.stringify(state, null, 2), 'utf8');
  • 读取本地文件
    lib/offline-install.mjs:49
    const text = readFileSync('/proc/meminfo', 'utf8');
  • 写入本地文件
    lib/offline-install.mjs:252
    writeFileSync(scriptPath, sh, { encoding: 'utf8', mode: 0o755 });
  • 读取本地文件
    lib/offline-install.mjs:253
    const bash = existsSync('/bin/bash') ? '/bin/bash' : 'bash';
  • 执行外部命令来自配置/变量
    lib/offline-install.mjs:254
    const child = spawn(bash, [scriptPath], {
  • 读取本地文件
    lib/update-operation.js:129
    const parsed = JSON.parse(await readFile(operationPath(this.home), 'utf8'));
  • 写入本地文件
    lib/update-operation.js:142
    await mkdir(dir, { recursive: true });
  • 读取本地文件
    lib/restart-outcome.js:10
    const parsed = JSON.parse(await readFile(path, 'utf8'));
  • 删除本地文件
    lib/restart-outcome.js:16
    await unlink(path);
  • 读取本地文件
    lib/github-update-worker.js:183
    const text = await readFile(join(input.checkoutRoot, input.tsconfig), 'utf8');
  • 发起网络请求
    lib/mirror-client.js:130
    const response = await this.request(`${this.options.mirrorBase ?? DEFAULT_MIRROR}/version?${query}`, true);
  • 请求外部主机registry.npmjs.org
    lib/mirror-client.js:139
    const response = await this.request(`https://registry.npmjs.org/${this.options.npmPackage ?? DEFAULT_NPM}`, false);
  • 发起网络请求
    lib/mirror-client.js:139
    const response = await this.request(`https://registry.npmjs.org/${this.options.npmPackage ?? DEFAULT_NPM}`, false);
  • 请求外部主机api.github.com
    lib/mirror-client.js:151
    const response = await this.request(`https://api.github.com/repos/${this.options.githubRepository ?? DEFAULT_REPO}/tags?per_page=100&page=1`, false);
  • 发起网络请求
    lib/mirror-client.js:151
    const response = await this.request(`https://api.github.com/repos/${this.options.githubRepository ?? DEFAULT_REPO}/tags?per_page=100&page=1`, false);
  • 发起网络请求
    lib/mirror-client.js:194
    const response = await this.request(url, transport === 'mirror');
  • 发起网络请求
    lib/mirror-client.js:263
    let response = await this.request(url, transport === 'mirror', extra, { acceptStatuses: [416] });
  • 发起网络请求
    lib/mirror-client.js:268
    response = await this.request(url, transport === 'mirror');
  • 写入本地文件
    lib/atomic-json-write.js:14
    await writeFile(temporary, `${JSON.stringify(value)}\n`, { encoding: 'utf8', mode: 0o600, flag: 'wx' });
  • 删除本地文件
    lib/atomic-json-write.js:22
    await unlink(temporary);
  • 删除本地文件
    lib/atomic-json-write.js:35
    await unlink(target);
  • 写入本地文件
    lib/atomic-json-write.js:43
    await rename(temporary, target);
  • 读取本地文件
    lib/github-archive.js:18
    const entries = await readdir(extractDir, { withFileTypes: true });
  • 读取本地文件
    lib/github-archive.js:36
    pkgText = await readFile(pkgPath, 'utf8');
  • 读取本地文件
    lib/github-archive.js:56
    await readFile(join(root, marker), 'utf8');
  • 写入本地文件
    lib/github-archive.js:69
    await mkdir(destDir, { recursive: true });
  • 写入本地文件
    lib/github-archive.js:71
    await writeFile(archivePath, data);
  • 执行外部命令固定命令
    lib/github-archive.js:73
    const child = spawn('tar', ['-xzf', archivePath, '-C', destDir], { stdio: ['ignore', 'pipe', 'pipe'] });
  • 写入本地文件
    lib/github-archive.js:111
    await mkdir(extractDir, { recursive: true });
  • 读取本地文件
    lib/credentials.js:16
    const parsed = JSON.parse(await readFile(credentialPath(home), 'utf8'));
  • 写入本地文件
    lib/credentials.js:28
    await mkdir(dir, { recursive: true });
  • 写入本地文件
    lib/credentials.js:33
    await chmod(target, 0o600);
  • 读取本地文件
    lib/github-promote.js:6
    await access(path);
  • 读取本地文件
    lib/github-promote.js:66
    entries = await readdir(dir, { withFileTypes: true });
  • 读取本地文件
    lib/github-promote.js:81
    pkg = JSON.parse(await readFile(pkgPath, 'utf8'));
  • 读取本地文件
    lib/github-promote.js:122
    entries = await readdir(dir, { withFileTypes: true });
  • 读取本地文件
    lib/github-promote.js:182
    needed = await readdir(stagingNm);
  • 写入本地文件
    lib/github-promote.js:258
    await mkdir(artifactBackupRoot, { recursive: true });
  • 写入本地文件
    lib/maintenance.js:14
    await mkdir(dirname(path), { recursive: true });
  • 读取本地文件
    lib/maintenance.js:28
    const parsed = JSON.parse(await readFile(resolveMaintenancePath(home), 'utf8'));
  • 删除本地文件
    lib/maintenance.js:41
    await unlink(path);
  • 写入本地文件
    lib/artifact-cache.js:22
    await mkdir(paths.dir, { recursive: true });
  • 读取本地文件
    lib/artifact-cache.js:24
    const prev = JSON.parse(await readFile(paths.partialMeta, 'utf8'));
  • 删除本地文件
    lib/artifact-cache.js:26
    await rm(paths.partial, { force: true });
  • 写入本地文件
    lib/artifact-cache.js:32
    await writeFile(paths.partialMeta, `${JSON.stringify({ version, transport }, null, 2)}\n`, 'utf8');
  • 删除本地文件递归
    lib/artifact-cache.js:35
    await rm(githubArtifactPaths(home, version).dir, { recursive: true, force: true });
  • 读取本地文件
    lib/artifact-cache.js:39
    const info = await stat(githubArtifactPaths(home, version).partial);
  • 读取本地文件
    lib/artifact-cache.js:51
    meta = JSON.parse(await readFile(paths.meta, 'utf8'));
  • 读取本地文件
    lib/artifact-cache.js:66
    data = new Uint8Array(await readFile(paths.archive));
  • 写入本地文件
    lib/artifact-cache.js:86
    await mkdir(paths.dir, { recursive: true });
  • 写入本地文件
    lib/artifact-cache.js:88
    await writeFile(tmp, artifact.data);
  • 写入本地文件
    lib/artifact-cache.js:98
    await writeFile(paths.meta, `${JSON.stringify(meta, null, 2)}\n`, 'utf8');
  • 写入本地文件
    lib/artifact-cache.js:99
    await rename(tmp, paths.archive);
  • 删除本地文件
    lib/artifact-cache.js:100
    await rm(paths.partial, { force: true });
  • 删除本地文件
    lib/artifact-cache.js:101
    await rm(paths.partialMeta, { force: true });
  • 读取本地文件
    lib/artifact-cache.js:120
    return new Uint8Array(await readFile(githubArtifactPaths(home, version).partial));
  • 发起网络请求
    lib/client/api.js:2
    const res = await fetch(pathname, {
  • 写入本地文件
    lib/promote-and-boot.mjs:45
    writeFileSync(p, `[${new Date().toISOString()}] promote-and-boot ${line}\n`, { flag: 'a', encoding: 'utf8' });
  • 读取本地文件
    lib/promote-and-boot.mjs:53
    const raw = readFileSync(path, 'utf8');
  • 执行外部命令来自配置/变量
    lib/promote-and-boot.mjs:72
    execFileSync(resolveWindowsPowerShellPath(), [
  • 执行外部命令来自配置/变量
    lib/promote-and-boot.mjs:106
    const out = execFileSync(resolveWindowsPowerShellPath(), [
  • 执行外部命令来自配置/变量
    lib/promote-and-boot.mjs:146
    execFileSync(resolveWindowsPowerShellPath(), [
  • 执行外部命令固定命令
    lib/promote-and-boot.mjs:154
    execFileSync('bash', ['-lc', `fuser -k ${p}/tcp 2>/dev/null || true`], {
  • 执行外部命令来自配置/变量
    lib/promote-and-boot.mjs:165
    const child = spawn(exe, args, {
  • 执行外部命令来自配置/变量
    lib/promote-and-boot.mjs:186
    const result = execFileSync(git, args, {
  • 读取本地文件
    lib/promote-and-boot.mjs:217
    if (exe === 'pnpm' || existsSync(exe)) {
  • 读取本地文件
    lib/promote-and-boot.mjs:237
    if (!job.operationFile || !existsSync(job.operationFile))
  • 读取本地文件
    lib/promote-and-boot.mjs:241
    op = JSON.parse(readFileSync(job.operationFile, 'utf8'));
  • 发起网络请求
    lib/promote-and-boot.mjs:273
    const res = await fetch(url, { method: 'GET', redirect: 'manual' });
  • 发起网络请求
    lib/promote-and-boot.mjs:278
    const again = await fetch(url, { method: 'GET', redirect: 'manual' });
  • 删除本地文件
    lib/promote-and-boot.mjs:453
    try { unlinkSync(jobPath); } catch {}
  • 删除本地文件
    lib/promote-and-boot.mjs:635
    unlinkSync(jobPath);
  • 读取本地文件
    lib/promote-and-boot.mjs:649
    if (jobPath && existsSync(jobPath)) {
  • 读取本地文件
    src/dsh-restart.mjs:39
    try { return /\.service(?:\/|$)/m.test(readFileSync('/proc/self/cgroup', 'utf8')) && Boolean(process.env.INVOCATION_ID || process.env.SYSTEMD_EXEC_PID
  • 读取本地文件
    src/dsh-restart.mjs:45
    if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
  • 写入本地文件
    src/dsh-restart.mjs:45
    if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
  • 写入本地文件
    src/dsh-restart.mjs:53
    writeFileSync(p, `[${new Date().toISOString()}] ${line}\n`, { flag: 'a', encoding: 'utf8' });
  • 读取本地文件
    src/dsh-restart.mjs:69
    if (existsSync(candidate)) return candidate;
  • 读取本地文件
    src/dsh-restart.mjs:79
    if (!existsSync(stateDir)) mkdirSync(stateDir, { recursive: true });
  • 写入本地文件
    src/dsh-restart.mjs:79
    if (!existsSync(stateDir)) mkdirSync(stateDir, { recursive: true });
  • 写入本地文件
    src/dsh-restart.mjs:81
    writeFileSync(path, trimmed, 'utf8');
  • 执行外部命令来自配置/变量
    src/dsh-restart.mjs:93
    const out = execFileSync(
  • 读取本地文件
    src/dsh-restart.mjs:117
    if (!existsSync(lockFile)) return { handoff: false, lockFile, watchdogPid: null };
  • 读取本地文件
    src/dsh-restart.mjs:120
    pid = parseInt(String(readFileSync(lockFile, 'utf8')).trim(), 10) || 0;
  • 写入本地文件
    src/dsh-restart.mjs:502
    writeFileSync(scriptPath, ps, 'utf8');
  • 执行外部命令来自配置/变量
    src/dsh-restart.mjs:504
    const child = spawn(powershell, [
  • 写入本地文件
    src/dsh-restart.mjs:583
    writeFileSync(scriptPath, sh, { encoding: 'utf8', mode: 0o755 });
  • 执行外部命令固定命令
    src/dsh-restart.mjs:584
    const child = spawn('bash', [scriptPath], {
  • 执行外部命令来自配置/变量
    src/dsh-restart.mjs:652
    const child = spawn(process.execPath, [helper, jobPath], {
  • 读取本地文件
    src/offline-install.mjs:19
    if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
  • 写入本地文件
    src/offline-install.mjs:19
    if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
  • 读取本地文件
    src/offline-install.mjs:34
    const raw = readFileSync(offlineStateFile(), 'utf8');
  • 写入本地文件
    src/offline-install.mjs:42
    writeFileSync(offlineStateFile(), JSON.stringify(state, null, 2), 'utf8');
  • 读取本地文件
    src/offline-install.mjs:49
    const text = readFileSync('/proc/meminfo', 'utf8');
  • 写入本地文件
    src/offline-install.mjs:252
    writeFileSync(scriptPath, sh, { encoding: 'utf8', mode: 0o755 });
  • 读取本地文件
    src/offline-install.mjs:253
    const bash = existsSync('/bin/bash') ? '/bin/bash' : 'bash';
  • 执行外部命令来自配置/变量
    src/offline-install.mjs:254
    const child = spawn(bash, [scriptPath], {
扫描于 2026/11/4(1 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包
涉及外部主机:registry.npmjs.org、api.github.com

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

社区实装还没有人打卡 · 装过的第一个就是你
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-tools@deepseek-ai/schemastery@deepseek-ai/dsh-host-webserver@deepseek-ai/dsh-client-runtime@deepseek-ai/dsh-client-locale
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 显示可拖动浮动版本胶囊
  • 版本检测与安装
  • 确认重启

DSH 版本徽标 + 一键自动更新(双界面 Cordis 插件)

v0.3.612026-10-19
整合现有 0.3.60 运行时并修复四条更新路径:GitHub 手动回滚恢复旧 ref/产物并重建链接;重启保留原 CLI 参数;npm 安装前核对实际全局目录,安装后核对目标版本;重启最终状态由持久化健康结果决定。 提供宽 peer 版本要求,包含当前 DSH 预发布版本,不按精确 DSH patch 锁定。源码仓库统一为 lib-first,移除已被替代的旧 TypeScript 实现,保留可直接打包运行的完整 lib。 验证:15 项相关回归通过,覆盖安装目录、版本核对、重启中状态、CLI 参数、回滚次序、产物恢复和健康等待。未通过测试发起真实 DSH 自更新或模型调用。
v0.3.222026-10-04
· v0.3.22 本次发布修复重复请求时更新状态损坏的问题,并避免全局更新指向另一个 DSH 安装。 · 安装前用运行中的 DSH 包核对包管理器的全局目录;识别桌面、npx 和源码安装,限制不支持的操作。 · 随 Cordis 上下文一起释放 HTTP 路由和悬浮胶囊;要求正确的 HTTP 方法,更新期间拒绝重启请求。 · 遵循 DSH 的 Node 版本范围 ^22.19.0 || >=24.0.0,改进 SemVer 校验和构建元数据比较,日志和离线状态遵循 DSH_HOME。 · 移除遗留的客户端运行时依赖,加入客户端类型检查。打包前重新构建,包含完整声明和源码导出,并单独输出 source map,把客户端脚本从约 102 KB 降到 18 KB。 · 更新配置文档,同步 lockfile,从随包模板中移除部署专用的可信来源。 验证:客户端类型检查、构建和 42 项测试通过;已检查 npm 包内容。安装测试使用模拟子进程。 兼容性基于 DSH 0.2.0-rc.2 和 0.2.1-alpha.1 的源码契约。实际 DSH 验证、原生桌面更新桥、alpha 反向代理路径前缀支持、进程重启成功交接仍未验证或未实现。预览仍选择已发布的最高版本,包括 alpha/rc。
v0.1.142026-08-22
· 变更 · Windows:不再自动重启,改为显示手动重启提示 · Linux/macOS:自动重启,用能识别 execArgv 的辅助函数 · 延长 npm install 超时;运行状态与磁盘状态徽章区分更清楚
数据来自仓库的 GitHub Release,可能与插件实际版本不一致。

README

由 DeepSeek 最新模型翻译生成
dsh-version-autoupdate DSH(DeepSeek Harness)双面 Cordis 插件:Web UI 版本胶囊 + 同源自动更新(npm 或 GitHub checkout,严格隔离)。 0.3.61:兼容与更新结果 不绑定 DSH 的精确版本或源码 SHA。沿用 Cordis 4.x 与注入服务接口,声明宽版本范围,并包含目前 0.2.0 / 0.2.1 的预发布版本。DSH 版本号改变不会触发运行时白名单拒绝;接口发生实质变化时仍可能需要适配,不承诺任意未来版本。 - npm 安装前核对包管理器全局目录与正在运行的 DSH;安装后从同一目录读取版本并核对目标。 - 要求重启时,状态保持 restarting,由独立 helper 的健康检查结果决定成功或失败;不重启时明确表示仅安装完成。 - GitHub 重启保留 host、port、trusted-host、profile、patch 等原 CLI 参数。 - GitHub 手动回滚在宿主退出后恢复旧 Git ref、构建产物并重建依赖链接,健康检查通过后才报告 rolled_back;保留原操作备份用于定位。 Host 运行时以 lib/.js 为维护源;src/dsh-restart.mjs 与 src/offline-install.mjs 通过 npm run build 同步。
展开完整文档(README 剩余 1 节)
dsh-version-autoupdate

DSH(DeepSeek Harness)双面 Cordis 插件:Web UI 版本胶囊 + 同源自动更新(npm 或 GitHub checkout,严格隔离)。

0.3.61:兼容与更新结果

不绑定 DSH 的精确版本或源码 SHA。沿用 Cordis 4.x 与注入服务接口,声明宽版本范围,并包含目前 0.2.0 / 0.2.1 的预发布版本。DSH 版本号改变不会触发运行时白名单拒绝;接口发生实质变化时仍可能需要适配,不承诺任意未来版本。

- npm 安装前核对包管理器全局目录与正在运行的 DSH;安装后从同一目录读取版本并核对目标。
- 要求重启时,状态保持 restarting,由独立 helper 的健康检查结果决定成功或失败;不重启时明确表示仅安装完成。
- GitHub 重启保留 host、port、trusted-host、profile、patch 等原 CLI 参数。
- GitHub 手动回滚在宿主退出后恢复旧 Git ref、构建产物并重建依赖链接,健康检查通过后才报告 rolled_back;保留原操作备份用于定位。

Host 运行时以 lib/.js 为维护源;src/dsh-restart.mjs 与 src/offline-install.mjs 通过 npm run build 同步。无需为了旧 TypeScript 树重新生成运行时。

功能概览

| 能力 | 说明 |
| 版本胶囊 | 会话头部显示运行/已装/最新版本、安装来源、检测通道、错误信息 |
| 同源检测 | 自动识别 npm / github / unknown;GitHub 安装只查 GitHub,npm 安装只查 npm |
| 镜像 + 官方 | 默认 auto:优先镜像;网络/限流失败时回退官方源;认证失败不回退(重新询问密码或选官方);完整性错误不回退 |
| MCP 更新 | dsh_update_check / dsh_update / dsh_update_status / dsh_update_watch / dsh_update_rollback |
| GitHub staging | 下载 → 校验 → staging 构建 → promote 到 live(含 pnpm rebuild 原生模块)→ 版本变化时默认重启。若桌面 Watchdog(watch-dsh-web)在跑,插件只退出并写 outcome,由 Watchdog 拉起,避免抢占 3080 |
| npm 更新 | 全局 npm install -g @deepseek-ai/dsh@<version>(走官方 registry,不弹镜像密码) |

UI 不再提供安装/重启按钮;写入类 HTTP 端点(/install、/start-update、/restart)返回 410 Gone,提示使用 dsh_update 工具。

HTTP API(只读)

| 路径 | 方法 | 说明 |
| /dsh-version-updater/status | GET | 同源 status(含 source / transport / updateAvailable) |
| /dsh-version-updater/check | POST | 纯检测,不安装、不重启、不询问密码 |
| /dsh-version-updater/install | | 410 — 请用 dsh_update |
| /dsh-version-updater/start-update | * | 410 |
| /dsh-version-updater/restart | * | 410 |

MCP 工具

| 工具 | 作用 |
| dsh_update_check | 同源只读检测 |
| dsh_update | 启动同源更新;restart / force;镜像密码由工具代码读取,缺失则弹出 userQuestions UI |
| dsh_update_status | 即时快照(用户追问时) |
| dsh_update_watch | 默认进度循环:阻塞到启动 / 1 分 / 5 分 / 每 10 分 / 终态,再让 Agent 用 summary 汇报 |
| dsh_update_rollback | npm 回滚到 backup 版本;GitHub 回滚到记录的 live root |

约束: 不接受 caller 指定的 source;检测类调用不触发密码交互;镜像密码存于 $DSH_HOME/version-autoupdate/credentials.json。

自然语言怎么用

插件会向 Agent 注入指引。新开对话后可直接说:

检查一下 DSH 有没有更新

有更新的话就更新 DSH,先不要重启;告诉我进度

更新 DSH 并重启

强制重新安装当前最新版(force=true)并重启,然后用 dsh_update_status 报告进度

回滚刚才的 DSH 更新

Agent 应自动调用 dsh_update_check → dsh_update → 循环 dsh_update_watch(直到 done)。用户追问进度时用 dsh_update_status。若模型没点到工具,可点名:调用 dsh_update,参数 force=true,restart=true。

配置(cordis.patch.yml)

| 字段 | 默认 | 说明 |
| updatePolicy | platform | Windows 可装可重启;Linux/macOS 仅检测。full / detect-only 可覆盖 |
| channel | preview | stable 只追正式版 |
| packageManager / packageManagerPath | npm | npm 更新用的包管理器 |
| installTimeoutMs | 1200000 | npm 全局安装超时(毫秒) |
| autoRestart | false | 旧向导用;MCP 显式 restart: true 时强制重启 |
| force | false | /status 绕过 registry 缓存 |

本地开发(Windows)

插件源码目录:D:\0HAN\Work\dsh-plugins\dsh-version-autoupdate

npm install --legacy-peer-deps
npm test
D:\0HAN\Work\dsh-plugins\sync-to-dsh.ps1

然后 关闭 Watchdog → 双击「DSH Web」 重启 DSH(不要用插件仓库 UI 的 detached 重启)。

验证

npm test
npm run build
npm pack --dry-run
git diff --check

许可

MIT
预览分享卡片长什么样 ↓Z-6354/dsh-version-autoupdate
分享 · DeepSeek Harness Hub
Z-6354/dsh-version-autoupdate

0.3.61:兼容与更新结果

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部