Bundle
dsh-user-plugins
A dsh web GUI panel that lists the plugins you installed into your dsh profiles, with install spec, version, kind, and live loader phase.
- Source
- inxups
- License
- MIT
- Updated
- Updated 5 hours ago
Readme
# dsh-user-plugins
一个 DSH 插件(host + 浏览器双面),在 Web GUI 的 **设置 → 插件** 里增加一个
**「我安装的插件」** 标签页,列出你通过 `dsh plugin --profile <name> add` 装进各
profile 的插件:安装源(spec)、磁盘版本、贡献类型(插件包 / 前端 / 库)、以及该插件
在当前加载器里的实时状态。
中文 | [English](README.en.md)
安装:
```sh
dsh plugin --profile web add github:inxups/dsh-user-plugins
```
装完**重启 dsh** 让插件进入组合。若从源码运行,把 `dsh` 换成 `pnpm dsh`。
## 它和自带的「Plugin list」有什么区别
DSH 自带 `ui-settings-plugin-inventory`(设置 → 插件 → Plugin list)展示的是**加载器
里所有条目**:官方包和第三方包混在一起,且没有安装源、没有版本、不区分是哪个 profile。
两者互补:
| | Plugin list(自带) | 我安装的插件(本插件) |
|---|---|---|
| 数据源 | 加载器条目(运行时) | profile 的 `package.json` 依赖 + bundle 列表(磁盘) |
| 范围 | 全部组成的插件,含官方包 | **只列你装进 profile 的包**,`@deepseek-ai/*` 一律不显示 |
| 安装源 spec | 无 | 有(`github:` / `link:` / 版本范围) |
| 版本 | 无 | 有(读包的 manifest) |
| 归属 profile | 无 | 有,并标出当前运行中的那个 |
自带包在界面上不做开关、不折叠,直接过滤掉 —— 想看它们用隔壁的 Plugin list。
## 结构
```
dsh-user-plugins/
├── package.json # 声明 dsh.bundle(host 行)与 dsh.client(浏览器半边)
├── cordis.patch.yml # bundle 层:把 host 行插入 profile 的插件名单
├── lib/index.js # host 半边:扫描 profile 目录 + /dsh-user-plugins/api/list
├── lib/client.js # 浏览器半边(构建产物,随包分发)
├── src/client/ # 浏览器半边源码(React + TSX)
│ ├── index.ts # Cordis 注册:locale 命名空间 + 标签页
│ ├── UserPluginsTab.tsx # 面板本体 + selectUserPlugins 纯函数
│ └── locales.ts # zh / en 字典
├── scripts/build.mjs # 用 esbuild 产出 lib/client.js
└── tests/ # host、client、集成三层 node:test 用例
```
host 半边零运行时依赖(只用 `node:fs` / `node:path`)。浏览器半边只用平台模块
(`react` + `@deepseek-ai/dsh-client-ui-primitives`),不引入任何第三方 UI 库。
## 界面
标签页的控件全部来自平台自带的 UI 原子,因此和 GUI 其余部分共用同一套设计 token,
换主题、切深浅色都会自动跟随:
| 元素 | 来自 |
|---|---|
| 刷新按钮 | `Button`(`variant="outline"`、`size="sm"`)+ `IconRefreshOutline16` |
| 搜索框 | `Input` + `IconSearchOutline16` |
| 版本 / 类型标签 | `Tag`(`neutral` / `info` / `outline` / `quiet` 调色板) |
| 实时状态圆点 | `StateDot`(`done` / `ongoing` / `error` / `idle`,`ongoing` 自带跑马灯动画) |
刷新时按钮图标旋转并禁用按钮,标签文字保持不变(避免宽度跳动);失败时保留上次结果并在
上方提示,不会把面板清空。
## 安装
```sh
dsh plugin --profile web add /绝对路径/dsh-user-plugins
```
`dsh plugin` 会在 profile 目录里转发给 pnpm,并把本包追加进 `dsh.profile.bundles`
(因为它声明了 `dsh.bundle`)。之后**重启 dsh** 让新插件进入组合。
若从源码运行,把上面的 `dsh` 换成 `pnpm dsh`。
## 数据与接口
`GET /dsh-user-plugins/api/list` 返回只读快照:
```jsonc
{
"home": "/Users/you/.dsh",
"profiles": [{
"name": "web",
"dir": "/Users/you/.dsh/profiles/web",
"bundles": ["@deepseek-ai/dsh-base", "dsh-memory-evolve", "..."],
"active": true, // 与加载器条目匹配最多的 profile
"plugins": [{
"name": "dsh-memory-evolve",
"spec": "github:csyangwen/dsh-memory-evolve",
"shipped": false, // 是否官方 @deepseek-ai/* 包
"source": "profile", // profile 依赖 | installation(由 dsh 安装提供)
"version": "0.1.0",
"kind": "bundle", // bundle | client | plain
"client": true, // 是否带浏览器半边
"bundleEnabled": true, // 是否在 profile 的 bundle 列表里
"entryId": "dsh-memory-evolve",
"phase": "active", // pending|loading|active|failed|unloading|null
"enabled": true
}]
}]
}
```
只读:不提供任何启用/禁用/安装/卸载能力,与自带清单一致。接口仍然返回完整快照
(含自带包与 `shipped` 标志),**过滤只发生在前端** —— 这样数据层保持诚实,界面规则
由 `selectUserPlugins()` 一处决定,并有单测覆盖。
## 已知限制
- `version` / `description` 只对 profile 自己 `node_modules` 里的包可读;由 dsh 安装
提供的 `@deepseek-ai/*` 包不落 profile,因此这些字段为 `null`(`source` 标为
`installation`)。这是刻意的:官方包不是「你安装的」。
- 当前运行中的 profile 靠「与加载器条目匹配数最多」推断,不是从启动参数读取。
- 数据按请求实时读取,没有变更订阅;面板上的「刷新」按钮重新拉取。
- 插件自身的 `description`(`package.json` 里那句)不在字典内 —— 它是包元数据,
由各插件作者自己决定语言,所以英文界面下也可能显示中文描述。
- 目前只有 zh / en 两套字典;跟随 GUI 已注册的语言,新增语言需要再加一份字典。
## 许可
MIT
Install
dsh plugin --profile web add github:inxups/dsh-user-plugins
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-user-plugins from the hub
- This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.