← 返回列表
未验证
未登录时全屏遮罩,校验通过后才放行访问页面
尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/9/9 · 已提供中文文档
DSH Web 登录门禁插件:未登录时全屏遮罩,Linear 风格登录页,配色跟随系统明暗,零滚动单页
综合分
30
GitHub 分
30
用户评分
—
★ Stars
1
周下载量
—
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add Haste123/dsh-plugin-login该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
数据截至 2026/9/16(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动
README
dsh-plugin-login
DSH(DeepSeek Harness)Web 端的登录门禁插件:启用后,整个页面被全屏登录界面遮挡,未登录不能访问/操作页面;输入默认账号 haste / 密码 haste123456 校验通过后放行。
- 配色随系统明暗主题自动切换(prefers-color-scheme;视觉设计参考 awesome-design-md 的 Linear 设计语言:近黑画布 / 炭色面板 / 发丝线分隔 / 单一薰衣草紫点缀)
- 单页零滚动(覆盖层 overflow:hidden + 阻断滚动链 + 登录期间锁定 html/body)
- 页面上不展示任何账号密码提示
- 纯前端校验,不调用后端接口(接入真实后端时只改一处逻辑,见下文「安全说明」)
目录结构
dsh-plugin-login/
├── package.json # 包元数据:dsh.client 声明、exports["./client"]、构建脚本
├── index.js # Node 半边(host face):空 apply,仅让包成为 Loader 条目
├── client.js # 浏览器半边 bundle(构建产物,供 DSH 模块系统加载)
├── build.mjs # 打包 + 自动注册 + 同步脚本(node build.mjs)
├── src/
│ └── client.js # 浏览器半边源码(真正的插件逻辑:登录界面 + 校验)
└── README.md
工作原理(为什么是「一面 Node、一面浏览器」)
DSH 的客户端插件采用 dual-face(双面)npm 包模型:
1. Node 半边(index.js,package.json.main)在 DSH 的 Cordis 组合里以普通插件行挂载。它的 apply 是空的——它唯一的作用是让这个包成为一条 Loader 条目。
2. DSH 的 dsh-client-modules(Node 半边)扫描所有 Loader 条目,读取包 package.json 的:
"dsh": {
"client": {
"platform": "web" // 必填:声明这是一个 web 客户端插件的包
// "inject": [...], // 可选:浏览器模块依赖的包名(本插件只 require("react"),无需)
// "external": [...], // 可选:静态表模块名(本插件无)
}
}
3. 扫描器再读取 exports["./client"] 指向的 bundle 文件(本插件是 ./client.js),把内容组合进 window.__DSH_BOOT__ 的 entry 图,浏览器加载后把 client.js 导出的 { inject, apply } 当作一个 Cordis 插件挂到客户端组合里。
bundle 必须是模块系统认识的格式(与官方包 @deepseek-ai/dsh-client-ui-cordis 的产物同构):
window.__ModuleLoader__.load({
id: "dsh-plugin-login", // 必须等于 package.json 的 name(= 模块条目 id)
factory: (require) => {
var React = require("react"); // Shell 种子模块,无需任何安装
// ……插件源码……
exports.inject = ['slots', 'timer'];
exports.apply = apply;
return module.exports;
}
});
本插件只依赖 Shell 已提供的 react、slots、timer 三个运行时设施,不需要任何 npm 安装、不需要在 dsh.client.inject/external 里声明别的包。
打包 / 注册(一条命令全自动)
零依赖:不需要 npm install,不需要 TypeScript/Vite。
node build.mjs # 默认凭据 haste / haste123456
node build.mjs admin admin@2024 # 自定义默认账号/密码(编译进 client.js)
node build.mjs admin # 只给账号,密码用默认值 haste123456
node build.mjs --no-register # 只打包,不碰 DSH 配置
build.mjs 默认做四件事(全部幂等,重复执行安全):
1. 打包:src/client.js → client.js(约 19 KB,未压缩),id 取自 package.json.name;账号/密码参数以 var AUTH_USER / AUTH_PASS 注入 bundle(JSON.stringify 转义,支持任意特殊字符),客户端用 typeof 兜底读取、未注入时回退内置默认值;
2. 安装:若插件还没被安装进 DSH web profile,自动执行 pnpm add file:(装过则跳过;失败会打印手工命令并返回非零退出码);
3. 注册:把插件行幂等写入 profile 的 cordis.patch.yml(自动找到 $DSH_HOME/profiles/web;DSH_PROFILE= 可指定别的 profile;已有该行时跳过);
4. 同步:把新 client.js / index.js 同步到 profile 的 node_modules 副本(字节一致则跳过,避免“改了源码忘了同步已安装副本”)。
环境变量:DSH_HOME(默认 ~/.dsh)、DSH_PROFILE(默认优先 web,只有一个 profile 时自动选用)。
⚠️ 改包名后必须重新 build:模块条目的 id 与包名绑定,二者不一致会在启动时编译失败(duplicate factory registration / entered the party 类报错)。
注册到 DSH
以 web profile(%USERPROFILE%\.dsh\profiles\web,即 ~/.dsh/profiles/web)为例。DSH 的组合结构是「分层 patch」:
- cordis.yml —— 自动生成的根文件(当前为 []),不要手改;
- package.json 的 dsh.profile.bundles —— 各 bundle 层(dsh-base、dsh-web-app),由安装的包提供;
- cordis.patch.yml —— 你的 patch 层(build.mjs 会自动写入插件行)。
正常流程:node build.mjs 一步到位
在插件目录执行一次 node build.mjs,安装 + 注册全部完成,写入的内容:
── 自动注册:dsh-plugin-login(由 build.mjs 写入,删除下列行即禁用)──
- insert:
- id: dsh-login
name: dsh-plugin-login
重复执行不会产生重复行。
手工流程(等价,可选)
cd %USERPROFILE%\.dsh\profiles\web
pnpm add file:
然后按上面格式手工编辑 cordis.patch.yml 即可(id 组合内唯一,name 为包名)。
注:pnpm 11 默认不执行 file: 依赖自身的生命周期脚本(Ignored build scripts),所以不能在 pnpm add 时自动写配置;自动写配置放在 node build.mjs 里完成。
重启启动 dsh web 的命令(按你实际的启动方式,例如 npx @deepseek-ai/dsh web),重新打开页面:
1. 页面应被登录界面全屏遮罩,任何滚动均被禁止;
2. 输入 haste / haste123456 → 进入应用,右下角出现「退出登录」胶囊;
3. 输错密码 → 红色错误提示 + 表单抖动。
如果没生效,先看 DSH 控制台是否有 client-modules: ... failed to compose 类报错(见下方排错表)。
卸载 / 禁用
从 cordis.patch.yml 移除(或注释掉)该 insert 行,或加上:
- id: dsh-login
disabled: true
然后重启。彻底移除依赖则再执行 cd %USERPROFILE%\.dsh\profiles\web && pnpm remove dsh-plugin-login。
开发迭代
1. 改 src/client.js(登录界面 / 校验逻辑 / CSS 都在这里)
2. 自动打包 + 安装 + 注册 + 同步(幂等,重复执行安全)
node build.mjs
3. 重启 dsh web,刷新浏览器
常见问题
| 现象 | 原因 / 处理 |
| --- | --- |
| 报 client bundle not found,提示 run pnpm run build before launch | exports["./client"] 指向的文件不存在:确认 client.js 已由 node build.mjs 生成且路径一致 |
| 报 duplicate factory registration / package resolves from multiple active Loader sources | 包名和 bundle 里 id 不一致,或同一包被插入了两条行:重新 build / 删除重复行 |
| 页面没变化 | 未运行 node build.mjs(它负责安装/写 patch/同步副本)、patch 行被误删、dsh 未重启,或 DSH_PROFILE/DSH_HOME 指向了别的 profile |
| pnpm add 报 ERR_PNPM_UNEXPECTED_STORE(v10/v11 store 不匹配) | 这台机器上有多个 pnpm 大版本。用当初安装该 profile 的同一个 pnpm 版本执行;或到 profile 目录先 pnpm install 统一 store,再重新安装 |
| 登录后刷新页面又要登录 | 预期行为:登录态只存在页面内存中(纯前端、无持久化)。要跨刷新记住登录,需要加 host 存储(见下文) |
安全说明与后续接入后端
当前校验是演示级:账号/密码由 node build.mjs 编译进 client.js(不指定时内置默认 haste / haste123456),纯前端比较,在浏览器源码里可见、可被绕过。
- 上线前把 check 换成真正的鉴权:客户端 host.call('login', {username, password})(Package 私有 RPC),由 Node 半边 harness.handle('login', ...) 校验并把结果写回(可借助 DSH credentials / storage 会话化)。
- UI 部分(登录界面、门禁、错误态、退出)不需要改动,只替换 check 的实现即可。
速查
node build.mjs # 打包+安装+注册+同步(默认 haste / haste123456)
node build.mjs admin admin@2024 # 自定义默认账号/密码
重启 dsh web → 访问页面 → 用构建时指定的账号登录扫码进群