Bundle
dsh-accounts-ui
给 dsh-accounts 在 DSH 设置面板里加「账号」区,用原生 UI 组件渲染(不再 iframe)。
- Source
- kexuejin
- License
- MIT
- Updated
- Updated yesterday
Readme
# dsh-accounts-ui
> **状态:已被上游 PR 取代,保留作为旧版本的临时补丁。**
>
> 这个能力正在并入 `dsh-accounts` 自己:见 [yangwuan55/dsh-accounts#1](https://github.com/yangwuan55/dsh-accounts/pull/1)(把设置区做成该包自己的浏览器半边)。合并后请改用上游:
>
> ```sh
> dsh plugin --profile web remove dsh-accounts-ui
> dsh plugin --profile web add github:yangwuan55/dsh-accounts
> ```
>
> 两个入口同时存在会出现**两个「账号」区**,所以别一起装。本仓库在这段过渡期里,服务于「想立刻有设置入口、但上游还没合并」的场景,也当作那份 PR 的可运行参考实现。
给 [`dsh-accounts`](https://github.com/yangwuan55/dsh-accounts) 在 DSH 的**设置面板**里加一个「账号」区,**用 DSH 原生 UI 组件渲染**(不是嵌入它的独立网页)——你不用再记 `http://127.0.0.1:3080/dsh-accounts/` 这个网址。
## 为什么需要它
`dsh-accounts` 只有宿主半边(manifest 里没有 `dsh.client`),所以它的管理页是一个**独立网址**,不会出现在设置里:
```
dsh keys: bundle, compatibility ← 没有 client
```
对比 `dsh-mnemon`(记忆)/ `@xmanrui/dsh-im`(IM机器人)/ `dsh-opencode-go-pool`(套餐池)——它们都声明了 `dsh.client` 并注册 `settings.section`,所以能出现在设置左侧导航。本插件补的就是这一块。
## 形态与实现
- 向 `settings.section` 槽注册 section:id `dsh-accounts-ui`、order 22(排在「IM机器人」之后)、标签「账号」。
- 界面用 `@deepseek-ai/dsh-client-ui-primitives` 的 `Button` / `Input` / `Modal` / `Tag` / `StateDot` 渲染,配色走 `--dsw-alias-*` 主题令牌,因此跟随设置面板的主题与深浅色。
- 能力覆盖:列表(id/描述/类型/域名/TOTP/可读状态)、新建、编辑(按 id 取原始记录预填,密码打码)、删除(二次确认)、刷新、只读存储时禁用写入。
- 数据经 dsh-accounts 自己的 `/dsh-accounts/api` 同源接口读写,**账号值不进浏览器以外的任何地方**;该接口的围栏校验 loopback Host 与同源 origin,浏览器插件恰好满足。
## 安装
```sh
dsh plugin --profile web add file:/Volumes/Kapp/source/dsh-accounts-ui
```
装完重启 DSH(客户端 bundle 在启动时由宿主提供)。前提是已装 `dsh-accounts`,且它的 `dsh-accounts-manage` entry 能拿到 `webServer`(web profile 满足)。
## 开发:源码与构建
界面源码是 `src/client.jsx`(普通 React + JSX),提交的 `client.js` 由构建产出,**不要手改**:
```sh
node build.mjs # src/client.jsx → client.js
```
`build.mjs` 用 TypeScript 的 `transpileModule` 把 JSX/ESM 转成 CJS,再套上 Web 外壳要求的客户端 bundle 格式:
```js
window.__ModuleLoader__.load({
id: 'dsh-accounts-ui', // 必须是包名
factory: (require) => { var module = { exports: {} }; var exports = module.exports;
/* 转译产物:require('react') / require('react/jsx-runtime') / require('@deepseek-ai/dsh-client-ui-primitives') */
return module.exports },
})
```
外壳以**经典脚本**加载这个文件,依赖经注入的 `require` 从 platform module 表解析(`react`、`react/jsx-runtime`、`react-dom`、`@deepseek-ai/cordis`、`dsh-client-store`、`dsh-client-ui-slots`、`dsh-client-ui-primitives`、`dsh-client-ui-dockkit`)。因此:
- `dsh.client.inject` 声明必须**先加载的客户端包**:`@deepseek-ai/dsh-client-ui-settings`(声明 `settings.section` 槽)、`@deepseek-ai/dsh-client-ui-slots`(提供 `slots` 服务);
- `dsh.client.external` 声明从这个模块表取用的说明符:`@deepseek-ai/dsh-client-ui-primitives`;
- 宿主半边 `index.js` 故意留空,但这个包**必须作为 Loader entry 挂载**(`cordis.patch.yml` 的那一行),客户端模块系统才会提供 `./client`。
构建需要能解析 `typescript`:本目录下建一条指向 Harness 依赖的软链即可(已被 `.gitignore` 忽略):
```sh
ln -sfn ~/.dsh/profiles/node_modules node_modules
```
## 已知限制
- 编辑时 id 不可改(与宿主一致:id 即凭据键 `dsh-accounts/<id>`)。
- 环境变量名的合法性在保存时校验(`[A-Za-z_][A-Za-z0-9_]*`),规则与宿主相同。
- 若上游未来给 `dsh-accounts` 自己补了 `dsh.client` + `settings.section`,应卸载本插件以免出现两个「账号」入口。
Install
dsh plugin --profile web add github:kexuejin/dsh-accounts-ui
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-accounts-ui 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.