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

插件自动更新 InariNGT-Ofiicial/dsh-plugin-updates

DeepSeek Harnessv2026.1031.13045
InariNGT-Ofiicial7 天前有提交已提供中文文档扫描:含敏感能力

DSH 插件自动更新:连接原 GitHub 仓库,默认每 24 小时检查并安装更新,支持人工控制、备份与失败回退。

37.7/100
综合分
12
GitHub 星标
—
npm 周下载
—/5
用户评分

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

自动兼容检查未通过:engines.node 要求 >=24.0.0,不满足 Node 22.19.0。以下命令仍可尝试,但可能失败。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add InariNGT-Ofiicial/dsh-plugin-updates
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · market
装得上吗
本站已在 dsh 0.2.1-rc.2 下真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 7 天前
档位由哪些信号合成

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

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装

engines.node 要求 >=24.0.0,不满足 Node 22.19.0

展开查看检查明细 ↓

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

✓npm 包dsh-plugin-updates @ 2026.1031.13045
✗Node 引擎要求 >=24.0.0 · 基线 Node 22.19 不满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/11/1 02:38:07

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

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

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 46 处,展示前 42 条)
  • 写入本地文件
    lib/service.mjs:14
    try { await writeFile(tmp, data, { mode: 0o600 }); await rename(tmp, path); } finally { await unlink(tmp).catch(()=>{}); }
  • 写入本地文件
    lib/service.mjs:14
    try { await writeFile(tmp, data, { mode: 0o600 }); await rename(tmp, path); } finally { await unlink(tmp).catch(()=>{}); }
  • 删除本地文件
    lib/service.mjs:14
    try { await writeFile(tmp, data, { mode: 0o600 }); await rename(tmp, path); } finally { await unlink(tmp).catch(()=>{}); }
  • 读取本地文件
    lib/service.mjs:28
    try { this.state = JSON.parse(await readFile(join(this.dataDir,'cache.json'),'utf8')); } catch {}
  • 读取本地文件
    lib/service.mjs:30
    try { this.report = JSON.parse(await readFile(join(this.dataDir,'latest.json'),'utf8')); } catch {}
  • 读取本地文件
    lib/service.mjs:32
    const schedule = JSON.parse(await readFile(join(this.dataDir,'schedule.json'),'utf8'));
  • 写入本地文件
    lib/service.mjs:51
    await mkdir(this.dataDir,{recursive:true,mode:0o700});
  • 删除本地文件
    lib/service.mjs:56
    await unlink(join(this.dataDir,'schedule.json')).catch(e=>{if(e.code!=='ENOENT')throw e;});
  • 写入本地文件
    lib/service.mjs:94
    await mkdir(this.dataDir,{ recursive: true, mode: 0o700 });
  • 写入本地文件
    lib/service.mjs:100
    async saveReport(report){await mkdir(this.dataDir,{recursive:true,mode:0o700});await atomicFile(this.paths().html,reportHtml(report));await atomicFile
  • 读取本地文件
    lib/executor.mjs:10
    const embeddedArchive=normalized.includes('.asar/')&&existsSync(normalized.slice(0,normalized.indexOf('.asar/')+5));
  • 读取本地文件
    lib/executor.mjs:13
    const desktop=desktopCandidates.find(p=>existsSync(p))||(embeddedArchive?desktopCandidates.at(-1):null);
  • 读取本地文件
    lib/executor.mjs:14
    const cli=desktop||[join(root,'lib/bin.js'),join(root,'node_modules/@deepseek-ai/dsh/lib/bin.js')].find(p=>existsSync(p));
  • 读取本地文件
    lib/executor.mjs:16
    if(!existsSync(cli)&&!embeddedArchive)return null;
  • 读取本地文件
    lib/executor.mjs:21
    if(!existsSync(executable))return null;command=executable;
  • 写入本地文件
    lib/executor.mjs:29
    const finish=async(error)=>{if(settled)return;settled=true;clearTimeout(timer);signal?.removeEventListener('abort',abort);if(logPath){let diagnostics=
  • 执行外部命令来自配置/变量
    lib/executor.mjs:35
    child=spawn(launcher.command,[...launcher.args,'plugin',...args],{env:{...process.env,ELECTRON_RUN_AS_NODE:'1',DSH_HOME:home,npm_config_ignore_scripts
  • 读取本地文件
    lib/inventory.mjs:7
    const json = async p => JSON.parse(await readFile(p, 'utf8'));
  • 读取本地文件
    lib/inventory.mjs:38
    const pointer = await readFile(gitDir, 'utf8');
  • 读取本地文件
    lib/inventory.mjs:42
    const text = await readFile(join(gitDir, 'config'), 'utf8');
  • 读取本地文件
    lib/inventory.mjs:51
    const dirs = allProfiles ? (await readdir(profilesRoot, { withFileTypes: true })).filter(d => d.isDirectory()).sort((a,b)=>a.name.localeCompare(b.name
  • 读取本地文件
    lib/inventory.mjs:62
    try { packageDir = await realpath(join(dir, 'node_modules', name)); pkg = await json(join(packageDir, 'package.json')); }
  • 发起网络请求
    lib/github.mjs:32
    connectRequest = (proxy.protocol === 'https:' ? https : http).request({ hostname: proxy.hostname, port: proxy.port || (proxy.protocol === 'https:' ? 4
  • 发起网络请求
    lib/github.mjs:45
    request = https.get(target, { headers, agent }, res => {
  • 请求外部主机api.github.com
    lib/github.mjs:82
    const response = await this.request(`https://api.github.com${path}`, { headers, timeoutMs: this.timeoutMs, proxyUrl: this.proxyUrl, signal: this.signa
  • 发起网络请求
    lib/github.mjs:82
    const response = await this.request(`https://api.github.com${path}`, { headers, timeoutMs: this.timeoutMs, proxyUrl: this.proxyUrl, signal: this.signa
  • 写入本地文件
    lib/updater.mjs:10
    async function atomic(path,value){const tmp=path+'.'+randomUUID()+'.tmp';try{await writeFile(tmp,JSON.stringify(value,null,2),{mode:0o600});await rena
  • 写入本地文件
    lib/updater.mjs:10
    async function atomic(path,value){const tmp=path+'.'+randomUUID()+'.tmp';try{await writeFile(tmp,JSON.stringify(value,null,2),{mode:0o600});await rena
  • 删除本地文件
    lib/updater.mjs:10
    async function atomic(path,value){const tmp=path+'.'+randomUUID()+'.tmp';try{await writeFile(tmp,JSON.stringify(value,null,2),{mode:0o600});await rena
  • 读取本地文件
    lib/updater.mjs:11
    const readJson=async p=>JSON.parse(await readFile(p,'utf8'));
  • 写入本地文件
    lib/updater.mjs:45
    await mkdir(this.dataDir,{recursive:true,mode:0o700});await atomic(join(this.dataDir,'auto-update.json'),{enabled});this.enabled=enabled;this.override
  • 删除本地文件
    lib/updater.mjs:47
    if(action==='reset'){await unlink(join(this.dataDir,'auto-update.json')).catch(e=>{if(e.code!=='ENOENT')throw e;});this.enabled=this.config.autoUpdate
  • 写入本地文件
    lib/updater.mjs:50
    async saveHistory(){await mkdir(this.dataDir,{recursive:true,mode:0o700});await atomic(join(this.dataDir,'update-history.json'),this.history.slice(-50
  • 写入本地文件
    lib/updater.mjs:52
    const dir=join(this.config.home,'plugin-updates');await mkdir(dir,{recursive:true,mode:0o700});const path=join(dir,'auto-update.lock');
  • 删除本地文件
    lib/updater.mjs:54
    try{const file=await open(path,'wx',0o600);const token=randomUUID();await file.writeFile(JSON.stringify({pid:process.pid,token}));await file.close();r
  • 删除本地文件
    lib/updater.mjs:58
    if((await readJson(path)).token!==prior.token)throw new Error('UPDATE_BUSY');await unlink(path);
  • 写入本地文件
    lib/updater.mjs:115
    const dir=join(this.dataDir,'downloads');await mkdir(dir,{recursive:true,mode:0o700});target=join(dir,digest+'.tgz');await writeFile(target,data,{mode
  • 读取本地文件
    lib/updater.mjs:141
    for(const name of ['package.json','pnpm-lock.yaml','pnpm-workspace.yaml','cordis.patch.yml']){try{await writeFile(join(backup,name),await readFile(joi
  • 读取本地文件
    lib/updater.mjs:142
    oldArchive=join(backup,'previous.tgz');await writeFile(oldArchive,await snapshotPackage(await realpath(join(dir,'node_modules',row.name))),{mode:0o600
  • 读取本地文件
    lib/updater.mjs:150
    const packageDir=join(dir,'node_modules',row.name);this.validateManifest(current,row,p=>existsSync(join(packageDir,p)));
  • 读取本地文件
    lib/archive.mjs:52
    for(const entry of await readdir(join(dir,relative),{withFileTypes:true})){
  • 读取本地文件
    lib/archive.mjs:58
    const data=await readFile(join(dir,path));bytes+=data.length;if(bytes>64*1024*1024||++count>20000)throw new Error('BACKUP_TOO_LARGE');
扫描于 2026/10/31(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
涉及外部主机:api.github.com

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

依赖的 DSH / Cordis 模块
@deepseek-ai/dsh-tools@deepseek-ai/schemastery@deepseek-ai/dsh-app-boot
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

README

由 DeepSeek 最新模型翻译生成
DSH 插件自动更新 · 0.2.3 兼容维护:同时支持 DSH 0.2.1-rc.2 / rc.3,保留旧版用法与设置。验证范围与复现见 DSH 兼容说明。 原生 DSH 插件,连接已安装插件的原 GitHub 仓库,默认开启自动更新,每 24 小时检查一次。检查和安装直接使用程序与官方 DSH CLI,不发起模型调用。 最新 Release · 安装包 v0.2.3 · 问题反馈 首次启动延迟 15 秒;重启读取上次检查时间,未到期不会重复检查。默认覆盖同一 DSH 主目录下所有 profile 的直接安装插件,包含未启用的安装条目。更新保留它们原有的启用状态。更新安装完成后,在对应 profile 重新加载或重启时生效;插件不会自动重启 DSH。 安装或升级 需要 Node.js 24+、DSH 0.2.1-rc.2 或 rc.3。
展开完整文档(README 剩余 1 节)
DSH 插件自动更新 · 0.2.3

兼容维护:同时支持 DSH 0.2.1-rc.2 / rc.3,保留旧版用法与设置。验证范围与复现见 DSH 兼容说明。

原生 DSH 插件,连接已安装插件的原 GitHub 仓库,默认开启自动更新,每 24 小时检查一次。检查和安装直接使用程序与官方 DSH CLI,不发起模型调用。

最新 Release · 安装包 v0.2.3 · 问题反馈

首次启动延迟 15 秒;重启读取上次检查时间,未到期不会重复检查。默认覆盖同一 DSH 主目录下所有 profile 的直接安装插件,包含未启用的安装条目。更新保留它们原有的启用状态。更新安装完成后,在对应 profile 重新加载或重启时生效;插件不会自动重启 DSH。

安装或升级

需要 Node.js 24+、DSH 0.2.1-rc.2 或 rc.3。可直接安装 Release URL,无需构建:

dsh plugin --profile desktop add https://github.com/InariNGT-Ofiicial/dsh-plugin-updates/releases/download/v0.2.3/dsh-plugin-updates-0.2.3.tgz

桌面版命令未加入 PATH 时:

& 'D:\DSH\resources\runtime\cli\bin\dsh.cmd' plugin --profile desktop add https://github.com/InariNGT-Ofiicial/dsh-plugin-updates/releases/download/v0.2.3/dsh-plugin-updates-0.2.3.tgz

也可从 Release 下载 .tgz 后通过本地路径安装。命令安装后重新加载或重启 DSH。旧版的检查时间设置会保留,已有人工设置仍优先于默认值。

本插件的 package.json.repository 指向本仓库,通过 Release URL 或下载包安装后,也会检查自己的后续正式 Release。默认排除预发布;升级安装本插件后需要重新加载才能运行新版代码。

插件市场适配

v0.2.3 已提供中英文标题、说明、作者和蓝白更新图标,兼容 DSH 插件管理展示。支持 format 1 自定义索引的市场可添加:

https://raw.githubusercontent.com/InariNGT-Ofiicial/dsh-plugin-updates/main/market/index.json

搜索「插件自动更新」,核对作者与原仓库后安装。索引固定到已发布 Git 提交,后续 Release 自动刷新。不同版本的 Discover 属于可选功能;没有该页面时仍可直接安装 Release 包。第三方精选市场是否默认收录由其维护者决定,详见 市场安装说明。

在 DSH 对话中人工控制

可以直接说「把检查间隔改成 48 小时」「关闭自动更新,只保留检查」「开启自动更新」「现在检查并更新插件」。

| 接口 | 参数示例 | 行为 |
| plugin_updates_check | {} | 立即检查版本,不安装;15 分钟 HTTP 缓存可复用 |
| plugin_updates_status | {} | 查看最近报告、检查时间和自动更新开关,不发网络请求 |
| plugin_updates_schedule | {"action":"set","intervalHours":24} | 每 24 小时检查,立即调整计时并持久化 |
| plugin_updates_schedule | {"action":"set","intervalHours":0} | 暂停所有定时检查和定时更新,仍可手动调用 |
| plugin_updates_schedule | {"action":"get"} / {"action":"reset"} | 读取间隔 / 清除人工覆盖并恢复插件配置值 |
| plugin_updates_auto_update | {"action":"get"} | 查看自动更新开关及最近更新历史 |
| plugin_updates_auto_update | {"action":"set","enabled":false} | 关闭自动安装,保留版本检查 |
| plugin_updates_auto_update | {"action":"set","enabled":true} | 开启自动安装 |
| plugin_updates_auto_update | {"action":"reset"} | 恢复插件配置的开关,默认开启 |
| plugin_updates_auto_update | {"action":"run"} | 按当前开关立即检查并更新 |
| plugin_updates_auto_update | {"action":"run","packageName":"example-plugin","profile":"desktop"} | 只更新指定已安装插件;名称为示例占位符 |

检查间隔支持 0~168 小时,非零间隔最短按 1 分钟计时。开关更改在当前安装结束后阻止后续更新,不强行终止正在执行的包管理操作。人工设置优先于原生配置;调用对应 reset 后重新使用原生配置。

自动更新怎样选择安装源

先从本地安装信息确定原仓库:用户配置 → GitHub 安装来源 → .git origin → package.json.repository。检查最近 30 条 Release,默认排除草稿与预发布;无可核对 Release 时检查最近 30 条标签,再降级查看分支版本。候选版本必须与仓库中的包名、版本匹配,使用 MIT node-semver 7.8.5 比较。

自动安装范围:
- 通过 npm 正式包安装的插件:从该配置档配置的包源读取同名、精确版本包,重新核对其 GitHub 仓库、包名、版本和 DSH 要求,再通过官方 DSH 命令行安装。不会把另一个仓库的同名包当成原插件。
- 通过 GitHub 或 tarball 安装的插件:优先取对应 Release 的插件 .tgz,没有时尝试标签归档;核对安装包内容、包名、版本、可运行入口和 bundle patch。Release 提供 SHA-256 digest 时同时校验。只接受 GitHub 官方下载域名,跨域下载不传递 GitHub token。
- 本地 link/workspace 源码、仅开发分支的新版本、缺少可安装包的多包仓库、别名安装、缺少 GitHub 来源等情况:在报告中说明原因,保留原安装。多包仓库需要插件专用 .tgz,或原本通过 npm 正式包安装。

每次安装固定到检查过的版本,关闭安装生命周期脚本,不自动批准构建脚本或 DSH 版本豁免。不适配当前 DSH / Node.js、需要构建但没有运行入口、包名不符或包摘要校验失败的条目会被标记。

安装前保存旧包 tarball 和配置档的 manifest、lockfile、workspace 设置、patch。安装成功后回读包名、版本、入口及启用状态;失败且文件已改变时尝试通过官方命令行安装旧版本。回退也失败则标记 needs_attention,暂停对该插件的自动重试,供人工处理。备份及日志保留本地,不自动删除。

这里的「已更新」表示安装文件已核对,不代表插件业务功能已在运行中重新验收。不同插件、依赖和宿主版本可能仍需重新加载后检查。无法确认的结果不会显示为成功。不会自动合并本地源码或比较同版本的提交变化,不递归管理普通依赖,也不更新 DSH 内置核心包。

原生配置

在当前配置档的 cordis.patch.yml 中设置已有条目:

- id: plugin-updates
config:
autoUpdate: true
intervalHours: 24
checkOnStart: true
startupDelaySeconds: 15
allProfiles: true
includePrereleases: false
timeoutMs: 12000
maxRequests: 40
githubTokenEnv: DSH_GITHUB_TOKEN
proxyUrl: ""
repositories: []

autoUpdate: false 只关闭安装,intervalHours: 0 暂停全部定时任务。checkOnStart: false 在启动时不立即进行到期检查。插件只在 DSH 运行且启用时执行,不创建操作系统计划任务。

缺少来源或子目录时,可以通过可信本地配置补充:

repositories:
- packageName: example-plugin
repository: https://github.com/example/plugin-repository
directory: packages/plugin
profile: desktop
ref: main

单包仓库省略 directory,跨配置档适用时省略 profile。上例只是占位符。工具不接受模型临时传入任意 URL、命令或版本;可更新目标来自本地已安装条目和核对过的上游版本。

报告、数据与网络

默认报告位于 $DSH_HOME/plugin-updates/<当前profile>/,没有设置 DSH_HOME 时使用 ~/.dsh/。

| 文件 | 用途 |
| latest.html / latest.json | 可读报告 / 完整结构化结果,含自动更新状态、安装及失败原因 |
| cache.json | GitHub ETag、HTTP 缓存和限流退避 |
| schedule.json / auto-update.json | 人工检查间隔 / 人工更新开关 |
| update-history.json | 最近 50 次安装记录及恢复结果 |
| backups/ | 更新前的可安装旧包和配置档文件 |
| downloads/ | 核对过的 GitHub 安装包,安装规格可能持续引用这些文件 |

不要删除仍被配置档安装规格引用的下载或备份包。同一主目录的自动安装通过共享锁串行进行;同一实例内并发调用合并。检查 GitHub 不超过单轮请求预算,默认 40 个;正式包安装及其依赖下载由官方包管理器单独处理。

公开仓库不强制 token。私有仓库或更高 API 额度可通过用户环境变量 DSH_GITHUB_TOKEN 配置,或用 githubTokenEnv 指定变量名;不会读取 DSH 凭据文件,也不会把 token 写入报告。GitHub 检查与归档下载支持配置的 HTTP/HTTPS 代理,其次使用 HTTPS_PROXY;正式包安装使用官方命令行的网络和账号配置。

报告、备份和历史可能含私有仓库名或本地配置档配置,保留本地。HTML 报告没有远程字体、脚本或统计请求,重新打开或刷新查看新结果。

独立源码命令行保持只检查,自动安装在 DSH 插件运行中执行:

node bin/check.mjs --offline
node bin/check.mjs --data-dir 'D:/DSH-update-report'

开发与验收

npm run check
npm test
npm pack

源码使用本机 Node.js 和随包附带的 MIT semver,无需安装开发依赖。验证口径见 docs/VALIDATION.md。合成 GitHub 响应与真实平台联网、安装文件验证与业务功能运行验证分别记录。

维护者更新 package.json.version、CHANGELOG 和 docs/RELEASE.md 后,推送对应 v<版本> 标签即可触发 Release 工作流。工作流在 Windows / Linux 上运行检查,再生成 .tgz 和 SHA256SUMS.txt,最后发布正式 Release,供默认自动更新使用。不要替换已经公开版本的安装包;修正应使用新版本。
预览分享卡片长什么样 ↓InariNGT-Ofiicial/dsh-plugin-updates
分享 · DeepSeek Harness Hub
InariNGT-Ofiicial/dsh-plugin-updates

DSH 插件自动更新:连接原 GitHub 仓库,默认每 24 小时检查并安装更新,支持人工控制、备份与失败回退。

回到顶部