npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@gestaltrun/dsh-client-ui-plugin-manager

v0.3.21-gestaltrun.0

Published

Plugin manager tab for the dsh web GUI Plugins settings section: installs plugins from npm or git through the official host channels, lists installed plugins with next-start enablement switches, surfaces install-time conflict actions with undo, and hands

Readme

@gestaltrun/dsh-client-ui-plugin-manager

English | 中文

面向 dsh web GUI「插件」设置分区的插件管理器 Tab:从 npm 或 git 安装插件,列出已装插件并提供下次启动生效的启用开关,如实呈现安装时冲突动作并支持撤销,失败一键转交修复会话。

功能

  • 在官方「插件」设置分区注册「插件管理」Tab(settings.plugins.tab 槽位,order 20,与官方安装器 Tab 并列)。
  • 双通道传输:带官方安装器服务的运行时(DSHCode 与 1.0.4 checkout 版 web)走官方 /plugin-installer、/plugin-control loopback RPC 通道;npm 发布的官方 web 没有这些通道,本包的 host 半区挂载 loopback 门禁的 HTTP 网关——安装/卸载 spawn 官方 dsh plugin CLI(唯一写入器),启停写入 disabled 覆盖行。
  • 从 npm 包名或 git 仓库 URL 安装插件,带进度。
  • 列出已装用户插件:下次启动生效的启用开关、更新检查(npm 源走 registry)、已核验的 npm 更新与卸载。
  • 聚合包逐行启停(网关模式):@gestaltrun/dsh-web-all 等声明多条入口行的聚合包展开为子行列表,每个家族插件有独立开关(写单行 disabled 覆盖,兄弟行不受影响);管理器自身、家族设置面与聚合 compat 面为锁定行,整包停用时也强制保留,管理入口不会被自己关掉。子行卸载保持整包粒度——代码随聚合包分发,停用即不再加载;需要独立版本管理时安装对应独立包(独立安装经双挂载保护优先于聚合行)。
  • 聚合包子插件列表默认收起:行上只显示「子插件 N/M 已启用」摘要,点击展开,携带 20+ 家族行的全家桶不再把设置页拉长。
  • 检测旧聚合包 @gestaltrun/dsh-web-ui-all,把更新动作转换为到 @gestaltrun/dsh-web-all 的事务迁移;网关先移除旧包、安装精确版本的新包、恢复旧聚合包的层顺序,并在 --dump-config 通过后才报告成功。
  • 更新前校验 DSH 运行时兼容(issue #754):更新检查读取最新版本清单声明的 DSH 最低版本(dsh.engines.dsh,兼容回退读顶层 engines.dsh),在更新按钮旁显示要求,运行 DSH 低于要求时禁用按钮;host 更新路由在启动任何 CLI 任务前若无法核实时也会返回 412 并拒绝。
  • 官方 plugin-control 面存在时展示内置产品开关。
  • 安装时冲突对账:官方模式对产品快照前后 diff;网关模式对每次 CLI 运行前后的 profile 层 diff,可撤销的动作给一键撤销,每条冲突都给「让 Agent 修复」转交。
  • 按插件渲染启动失败环:「让 Agent 修复」(以插件安装根为工作区的修复会话)与「复制错误」;npm web 运行时没有失败环,只有安装错误提供修复转交。
  • 显示宿主安全模式横幅与「恢复正常模式」操作(web 端在下次手动重启时生效)。
  • npm 运行时保护下次启动:安装后网关校验依赖真实落盘、拒绝重复入口 id 认领与引用不可解析包的 insert 行,并用 CLI 的 --dump-config 做组合预检;冲突或失败的安装会经官方 remove 路径自动回滚(绝不触碰现有插件),错误行带修复转交。

安装

从 npm 安装(推荐)

dsh plugin --profile web add @gestaltrun/dsh-client-ui-plugin-manager

从仓库安装(开发调试)

git clone https://github.com/gestaltrun/dsh-web.git
cd dsh-web
pnpm install && pnpm -r build
dsh plugin --profile web add link:$(pwd)/packages/dsh-plugin-manager

重启 dsh web 后,设置页「插件」分区出现该 Tab。

配置

本 Tab 不携带配置命名空间。开关与安装在下次重启后生效。

cordis 服务

浏览器半区把共享的双通道 face 以 cordis 服务名 pluginManager 提供,兄弟客户端插件无需重复实现通道探测即可驱动与观察插件管理。用 ctx.inject(['pluginManager'], cb) 注入并读取 ctx.pluginManager:

  • isLoopback: boolean — 本浏览器是否具有使用 host 路由的 loopback 权威。
  • list(): Promise<InstalledPluginItem[]> — 读取已装快照。
  • install(spec): Promise<InstalledPluginItem> — 从 npm spec 或 git URL 安装一个插件。
  • uninstall(id): Promise<InstalledPluginItem[]> — 卸载一个插件。
  • status(): Promise<InstallProgressItem> — 读取当前安装/更新进度。
  • failures(): Promise<PluginFailuresSnapshot> — 读取宿主侧记录的插件启动失败环(插件 id、消息、堆栈、安装路径);无失败环的运行时返回空快照。
  • setEnabled(id, enabled): Promise<InstalledPluginItem> — 经当前通道(官方安装器 RPC,或网关写 profile patch 的 disabled 行)翻转插件的下次启动启用状态;宿主重启后生效。
  • onChange(cb): () => void — 订阅成功变更;install()、update()、uninstall()、setEnabled() 任一成功 resolve 后触发,返回退订函数。

契约事实源在 src/core/service.ts(PluginManagerService)。服务随插件生命周期提供,插件卸载即消失。服务与「插件管理」Tab 共享同一个 face,因此 onChange 订阅者对两侧发起的变更都能收到通知。

已知限制

  • 仅限本机:LAN 或远程浏览器只显示「仅限本机操作」提示(与官方安装器 Tab 同一边界;网关对非 loopback 请求返回 403)。
  • npm 发布的官方 web 上,网关写入经官方 CLI 执行。网关先从 host 进程 PATH 解析 dsh,再从运行中 host 入口上层各项目根的 node_modules/.bin 回退查找,覆盖本地包装器与 npx 启动;两处都没有 CLI 时才不可写。git 源安装可能耗时数分钟,以后台任务运行。网关更新只适用于 npm registry 源,由 host 解析最新版本,且仅当同一已装包报告该精确版本时才算成功。
  • 兼容性门禁只在目标清单声明了最低 DSH 版本时生效;未声明 dsh.engines.dsh 的包更新不被检查,官方安装器运行时(DSHCode 与 checkout 版 web)不经过本门禁(其更新走官方安装器)。
  • npm 发布的官方 web 没有启动失败环与安全模式:这两处界面降级为空,只有安装错误提供修复转交。
  • npm 运行时上的启停显示下次启动的真实生效值:profile 覆盖行优先,其次由所装 bundle 自带的 disabled 行决定(聚合包的按需开启家族),两层都未提及的行视为启用。开启一个被 bundle 停用的行会写入显式 disabled: false 覆盖行——只删除用户行只会退回 bundle 默认值;该运行时 loader 在下次启动时认读这些行,但这条路径不如官方桌面写入器经过充分锻炼。
  • web 端无壳内重启:变更在下次手动重启后生效。
  • 安装时冲突检测报告安装实际改了什么(官方模式为产品行;网关模式为 profile 行与 bundle 条目)。npm 运行时上重复 insert id 认领在安装后即被检出并自动回滚新插件(共享 id 写 disabled 无法阻止 loader 的重复检查,只会误伤现有插件);官方运行时由官方规则与失败环处置该类冲突。
  • npm 运行时的启动预检(--dump-config)能抓组合失败,静态 insert 检查能抓引用不存在包的 insert 行;真正的运行时 import/apply 失败仍要到下次启动才暴露,官方运行时靠失败环呈现,npm 运行时没有失败环。
  • 重复挂载保护(网关模式):官方 CLI 的 bundle 对账会在任何安装/卸载后把所有声明 dsh.bundle 的依赖重新加进 dsh.profile.bundles——包括组合树里已由 patch 行挂载的包(全家桶聚合包以行挂载 @gestaltrun/dsh-better-sidebar),下次启动会重复挂载而失败(duplicate prefix route)。每次 CLI 变更成功后,网关只把「本次新增且已被 patch 行挂载」的 bundles 条目剥除(清单写入走备份 + tmp + 原子 rename),并在任务结果上为每个被剥除的条目发一条 notice;正常安装的 bundles 条目与用户此前已有的条目一律不动。
  • wire 形状镜像官方安装器 Tab 协议;漂移时宽容解析器降级为错误行,不误操作。
  • 修复会话工作区保留路径派生的默认标题。

安全模型

  • 信任边界是 loopback 门禁:每条网关路由都要求 loopback socket 地址、loopback Host 头与非跨站来源(socket + Host + Origin + sec-fetch-site 四重),与官方安装器通道同一权威。远程来源的浏览器没有可达路径;被拒请求返回 HTTP 403 与 { ok: false, error: "forbidden: loopback-only" }。
  • 变更类路由(install / update / remove / set-enabled)不带 token:loopback 权威即本机用户,与官方通道同模型。因此任何本机进程都能驱动插件安装与卸载,且 npm 安装会执行包的 install 脚本——请将本网关视为「设计上即本机代码执行」,绝不暴露到 loopback 之外。
  • 安装 spec 与包 id 含命令行展开字符或控制字符时一律拒绝。Windows 下,npm shim 会解析为 node.exe 加包内 bin.js;DSH Desktop 打包 shim 附近没有 npm 布局,因此通过带完整预引用、逐字参数封套的 cmd.exe /d /s /c 执行。桌面 profile 从打包启动器环境值或持久化的 profile 选择中读取,进程内官方安装器则由浏览器 RPC 能力探测确认。
  • 变更经同一队列串行,并发任务的 before/after profile 快照绝不交错。安装只有在依赖真实落入 profile 后才判 done(卸载以依赖消失为准),绝不轻信成功退出码。
  • 启停操作会在该变更队列内重新读取最新 profile 清单,并在写入前以 404 拒绝过期或未知的包 id,因此卸载后遗留在面板里的旧行不会制造孤儿 disabled 覆盖。
  • 冲突处置是 owner-aware 的:重复入口 id 或引用不可解析包的 insert 行会经官方 remove 路径回滚新包;网关绝不对共享 id 写 disabled 行(那既阻止不了 loader 的重复检查,又会误伤现有插件)。
  • 启动预检(--dump-config)只组合 patch 层、不 import 条目:能抓组合失败,抓不到 import 期失败——后者仍在首次真实启动时暴露。
  • profile 名(来自 --profile / DSH_PROFILE)在任何文件读写前做路径穿越校验;patch 写入走备份 + tmp + 原子 rename(cordis.patch.yml.bak-plugin-manager)。
  • 重复挂载保护只写 profile 清单的 dsh.profile.bundles,与 patch 写入同一纪律(备份 + tmp + 原子 rename,备份为 package.json.bak-plugin-manager);只移除 CLI 刚加入且与既有 patch 行挂载重复的条目;保护写回失败会让任务显式失败,绝不静默留下破坏下次启动的状态。

数据遥测

浏览器半区每个 UTC 日向 dsh-market.com 发送一次匿名安装心跳:仅含一个 localStorage 随机 ID 与本包名,无其他数据。服务端只存储该 ID 的加盐哈希,不存 IP,且只暴露聚合计数。完整契约见 docs/telemetry.md。

许可证

BSD-3-Clause。