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

浮动面板坞 hemppp/dsh-panel-dock-plugin

DeepSeek Harness
hemppp32 天前有提交已提供中文文档扫描:无法判定

拖动缩放折叠面板,布局自动保存并可一键还原

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

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

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add hemppp/dsh-panel-dock-plugin
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:需留意
是什么
dsh 原生插件 · vision
装得上吗
实装验证未通过(unknown),装前请到仓库确认最近更新与 issue
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 32 天前
档位由哪些信号合成

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

验证判据与等级说明 →
⚠︎ 实装验证未通过(unknown · 2026/11/4) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
⚪ 扫描:无法判定尚无人工评估
展开查看扫描说明与证据 ↓

已尝试扫描但取不到可分析的源码:仓库或包不存在、已删除,或为非 JS/TS 实现、未随包发布源码。无法判定,不代表安全。

  • · 取源不可用(Error: github tarball HTTP 404 @ https:
  • · api.github.com
  • · repos
  • · hemppp
  • · dsh-panel-dock-plugin
  • · tarball)
扫描于 2026/11/4(0 天前)

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

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 拖拽缩放折叠面板
  • 布局自动保存
  • 一键还原布局

给 DeepSeek Harness Web UI 加上 Photoshop 式浮动可停靠面板——可拖拽、可缩放、可折叠,布局自动保存。

README

由 DeepSeek 最新模型翻译生成
dsh-panel-dock-plugin Photoshop 式浮动面板坞,用于 DeepSeek Harness Web UI。 把界面上「可以安全新增」的区域做成一套独立面板系统:面板可拖动、可缩放、可折叠、可显示/隐藏、布局持久化、一键恢复默认。侧栏的「面板坞」图标会打开一个同名控制页,在那里能集中开关每个面板。面板颜色走 DSH 官方主题 token (唯一例外是投影,见 能做到 / 做不到),明暗主题一致。 诚实范围声明(先读这一段) 本插件不能把 DSH 已经发布的 sidebar / main / rightbar 区域「拆下来」塞进浮动面板。 那些 slot 是 single 且 replaceRisk: shadows-shipped-ui:第三方插件占用它们等于把整个界面顶掉。 因此本插件实现的是一套真实可用的、与原界面并存的浮动面板系统(新增面板),不是「原区域重挂载」。详见下面 能做到 / 做不到。
展开完整文档(README 剩余 1 节)
dsh-panel-dock-plugin

Photoshop 式浮动面板坞,用于 DeepSeek Harness Web UI。

把界面上「可以安全新增」的区域做成一套独立面板系统:面板可拖动、可缩放、可折叠、可显示/隐藏、布局持久化、一键恢复默认。侧栏的「面板坞」图标会打开一个同名控制页,在那里能集中开关每个面板。面板颜色走 DSH 官方主题 token (唯一例外是投影,见 能做到 / 做不到),明暗主题一致。

诚实范围声明(先读这一段)

本插件不能把 DSH 已经发布的 sidebar / main / rightbar 区域「拆下来」塞进浮动面板。
那些 slot 是 single 且 replaceRisk: shadows-shipped-ui:第三方插件占用它们等于把整个界面顶掉。
因此本插件实现的是一套真实可用的、与原界面并存的浮动面板系统(新增面板),不是「原区域重挂载」。详见下面 能做到 / 做不到。

1. 安装(未发布 npm)

方式 A:从 GitHub 仓库安装

dsh plugin add 是 pnpm 的包装(在 <DSH_HOME>/profiles/desktop 下执行 pnpm add),它 --help 列出的可用形式包含 <git host>:<git user>/<repo> 与 <git repo url>:

dsh plugin --profile desktop add github:hemppp/dsh-panel-dock-plugin
或
dsh plugin --profile desktop add https://github.com/hemppp/dsh-panel-dock-plugin

仓库里已内置构建产物 lib/index.js 与 lib/client.js(.gitignore 刻意没有忽略 lib/),所以安装端不需要装 devDependencies、也不需要自己构建。

方式 B:本地路径安装(开发用)

cd dsh-panel-dock-plugin
pnpm install
pnpm run bundle # 改完源码后重新构建
界面 Plugins → Add plugin,或:
dsh plugin --profile desktop add --save-exact <本地绝对路径>@0.1.2

本仓库从未发布到 npm。GitHub 上提供源码 + 已构建的 lib/,Release 里附带 npm pack 产出的 .tgz。仓库自身不做任何自动安装,也不改动 DSH 宿主或任何 profile ——安装是你手动执行的一步;桌面 profile 由 Electron 独占管理。

2. 面板系统能力

| 能力 | 状态 | 实现位置 |
| 浮动面板层 | ✅ 已实现 | shell.overlay 入口 panel-dock(src/client/index.tsx) |
| 拖动 | ✅ 已实现 | 标题栏 pointer 事件 + setPointerCapture,拖动中按视口 clamp |
| 调整大小 | ✅ 已实现 | 右下角 resize 手柄,最小 240×140 |
| 折叠 / 展开 | ✅ 已实现 | 标题栏折叠按钮(双击标题栏亦可) |
| 关闭 / 隐藏 | ✅ 已实现 | 标题栏 ✕;底部 chips 或 sidebar.panellist 图标重新打开 |
| 全部显示 / 全部隐藏 | ✅ 已实现 | 坞右下角工具条的「全显 / 全隐」 |
| 恢复默认布局 | ✅ 已实现 | 工具条「复位」:清 localStorage 并回到默认位置 |
| 布局持久化 | ✅ 已实现 | localStorage key dsh-panel-dock-plugin:layout:v1 |
| 明暗主题一致 | ✅ 已实现(有一处例外) | 除投影外全部颜色走 --dsw-alias- / --dsw-specific- token |
| 面板开关图标 | ✅ 已实现 | sidebar.panellist 入口 id panel-dock-toggles;点击打开下面那个控制页 |
| 图标打开的控制页 | ✅ 已实现 | main 入口同 key panel-dock-toggles(selectPanel 要求两者成对) |
| 视口变化自适应 | ✅ 已实现 | resize 监听把所有面板 clamp 回可见范围 |
| 把已发布 sidebar/main 搬进浮动面板 | ❌ 不能做 | 平台限制,见下节 |

内置面板(3 个)

1. 会话与工作区(overview)— 通过 slot 标准 props 读取真实数据:工作区数量、会话总数、每个工作区的会话数。不请求任何远端接口。
2. 插件与环境(environment)— 显示插件 id / 版本 / 三个入口 id / 当前可见面板数,并能探测 Node half 的健康路由 GET /dsh-panel-dock-plugin/health。
3. 便签(notes)— 自动保存到 localStorage(key dsh-panel-dock-plugin:notes)。

3. 能做到 / 做不到

做到了

- 一套独立于宿主原区域的浮动面板系统,真实注册在 shell.overlay (slot 目录原文:"Frame-wide floating layer, above every column and outside their scroll containers.")。
- 浮层本身是 click-through 的(pointer-events: none),面板自身 pointer-events: auto,所以不会挡住底下的界面。
- 拖动 / 缩放 / 折叠 / 显隐 / 持久化 / 复位全部是真实逻辑,含视口 clamp 边界处理。
- 面板内容读取宿主真实状态(useWorkspaces 快照),不是占位文字。

做不到(平台限制,不假装实现)

- 无法把 sidebar / main / rightbar 的既有内容整体搬进浮动面板。 sidebar / rightbar 在 slot catalog 中标记为 single + replaceRisk: shadows-shipped-ui,一旦第三方插件注册进去就会替换掉官方实现,等于让整个界面消失;main 是 keyed,只有已被占用的 key(conversation、plugins)才会替换占用者。
本插件因此刻意没有注册 root、sidebar、sidebar.workspaces、sidebar.settings 等任何 single 槽位,也没有抢 main 的 conversation / plugins 键 —— 它只在 main 上新增了自己的 key(panel-dock-toggles)。这个新增是必需的:sidebar.panellist 的图标 id 必须寻址到一个同名的 main key,否则点图标时 ctx.layout.selectPanel(id) 会抛错并保留当前面板。
pnpm run gates 会静态校验这两点(不注册 single 槽位 + key 成对且不抢占用者)。
- 因此「像 Photoshop 那样把已有面板拆下来重新排布」在当前 DSH 插件 API 下不可实现。
可以实现的上限是:新增可浮动面板 + 用 sidebar.panellist 提供开关图标。
- 面板之间没有 docking/吸附与拖拽合并(截图里的 Photoshop 停靠行为)。当前是自由浮动 + 整体复位;拖拽重排、磁吸停靠属于未实现范围。
- 未做:面板 z-order 手动置顶、多显示器坐标、面板分组为 tab、跨设备同步布局。
- 投影(box-shadow)颜色是固定的半透明黑,不随主题走。 原因:DSH 的 alias 清单里没有 shadow / elevation token(client/Theme.listTokens 只有 bg、border、brand、label、 state、sidebar-fill 六类),而明暗两套主题都需要投影,所以三处 elevation 投影(SHADOW:面板常态 0 6px 20px rgba(0,0,0,0.16)、hover 0 12px 32px rgba(0,0,0,0.22)、工具条 0 6px 18px rgba(0,0,0,0.18))是本产物中唯一非 token 驱动的颜色。
这不影响可读性(暗色下投影只变弱,不会让文字/边框失效),但确实不算「完全主题化」。
该例外被 pnpm run gates 显式枚举校验:除这三条投影和 var(<token>, <fallback>) 的回退值之外,产物里不允许再出现任何颜色字面量。

4. 三个入口(为什么是这三个)

| Slot | kind / scope | 为什么用它 |
| shell.overlay | list / root | 帧级浮层,位于所有列之上且在它们的滚动容器之外 —— 浮动面板的唯一正确落点。replaceRisk: none,用新 id 追加即可,不会顶掉已有的 10 个 occupant。 |
| main | keyed / root | 开关图标必须有一个页面。 sidebar.panellist 的 id 寻址 main keyed slot 的同名 key;ctx.layout.selectPanel(id) 遇到缺失的 key 会抛错并保留当前选中态。官方 ui-schedule({name:'main',key:PANEL_ID} + {name:'sidebar.panellist',id:PANEL_ID})就是这么成对注册的。本插件只新增 key panel-dock-toggles,不碰 conversation / plugins。 |
| sidebar.panellist | list / root | 全局面板图标栏,按 list id 寻址。用来放面板开关图标,符合该 slot 的设计意图("Global panel icons")。replaceRisk: none。 |

注册都包在 ctx.effect(...) 里,卸载插件时三个入口一起 dispose。

shell.overlay 的条目不会收到 ctx:service 在 apply 闭包里,组件只拿到标准 props。
本插件因此把面板状态放在 client 模块作用域的 store(同一个 client 模块注册三个入口,所以是同一个实例),组件通过 useSyncExternalStore 订阅。

浮层的层叠与边界(静态可定论,不需要实机验证):shell.overlay 由官方 @deepseek-ai/dsh-client-ui-layout 渲染成 AppFrame 内的 {overlays},其规则为 position:absolute; inset:0; z-index:20; pointer-events:none,并且 overlayLayer > * { pointer-events:auto }。z-index 20 不是「很大的数」,它只在该层自己的 stacking context 里比较;它之所以盖住三列,是因为这个层位于 frame 的 stacking context 内、并且是 frame 的倒数第二个子元素(三列都没有 z-index)。
本插件在根节点写 inline pointer-events:none、在面板上写 auto —— inline 样式覆盖上面那条 > 规则,这正是「浮层 click-through、面板本身可点」成立的机制。
另外 frame 是 overflow:hidden(Windows 下还带 padding-top: var(--dsh-windows-titlebar-height)),所以面板在结构上不可能跑到窗口之外:本插件的 clampPanel 按视口夹取与之一致,同时也是「多显示器 / 跨窗口面板」做不到的根因。

5. 冒烟检查

1. UI 标记:浮动层根节点带 data-dsh-panel-dock-plugin="ready",并带 data-dsh-panel-dock-count="<可见面板数>"。
在 DevTools 里:document.querySelector('[data-dsh-panel-dock-plugin]')。
2. Node half 命令:在 composer 输入 /hello,返回 panel-dock: hello world。
3. 健康路由:GET /dsh-panel-dock-plugin/health → 200 { "ok": true, "plugin": "dsh-panel-dock-plugin", "version": "0.1.2", "node": "v24.x", "uptimeSeconds": 12, "time": "..." }

「插件与环境」面板里的按钮就是调它。
4. 脚本自检(无需浏览器):
pnpm run bundle # esbuild → lib/index.js + lib/client.js
pnpm run gates # 产物 / 合同 / 命名 / React external / 种子模块纯净性 / 无假 inject 边 / 版本一致 / 诚实性文档 / panellist↔main 成对 静态门禁(18 条)
node scripts/test/client-runtime.mjs # 用假 window + 假 ModuleLoader 跑真实 bundle
node scripts/test/client-render.mjs # jsdom + 真 react-dom:真实挂载三个入口并操作 DOM

client-runtime.mjs 会真的执行 lib/client.js,断言 ModuleLoader id、require("react")
确实被外部化、apply() 注册了三个正确 entry(含 sidebar.panellist ↔ main 的成对 key),
并把 layout helper(clamp / persist / reset)跑一遍;client-render.mjs 在真实 DOM 里挂载三个入口,并断言控制页上的面板开关能驱动同一份 store。

6. 合同要点(为什么这样写)

- package.json#name = cordis.patch.yml 的 insert id/name = client ModuleLoader 的 id = dsh-panel-dock-plugin,三处一致(门禁静态校验)。
- 未声明任何 @deepseek-ai/ 依赖;两个宿主服务(commands、webServer)只通过 export const inject = [...] 声明,靠 profile 注入。
- react / react/jsx-runtime / react-dom / react-dom/client 在 client bundle 中全部 external。打第二份 React 会直接 Cannot read properties of null (reading 'useState')。
- dsh.client.inject 刻意留空。 该字段声明的是「必须先物化的 client module 行」,浏览器侧物化器的循环是 const dependency = this.graphRows.get(packageName); if (dependency !== void 0) await this.arriveDependency(...) —— 名字不是一个行就被静默跳过:不报错,也不生效。@deepseek-ai/dsh-client-ui-slots 是纯核心包(没有 lib/client.js,因此永远不可能是行),把它写进 inject 是一条 假依赖边;官方若干插件(如 dsh-client-ui-jobs / dsh-client-ui-schedule 声明 @deepseek-ai/dsh-client-ui-primitives)与部分第三方插件也这么写,但本产物不复制这个错误。
真正保证 ctx.slots 存在的是 client half 的 export const inject = ['slots'] (Cordis 服务等待),与 dsh.client.inject 无关。
- 壳预置模块(staticModules)只有 9 个:react、react/jsx-runtime、react-dom、 react-dom/client、@deepseek-ai/cordis、@deepseek-ai/dsh-client-store、 @deepseek-ai/dsh-client-ui-slots、@deepseek-ai/dsh-client-ui-primitives、
@deepseek-ai/dsh-client-ui-dockkit。require() 直接由这张表解析,不需要图谱边;
本 bundle 只 require react 与 react/jsx-runtime,pnpm run gates 会静态断言「bundle 里的每个 require() 都落在这 9 个名字里」。
- 4 处版本串(package.json、src/index.ts 的 health payload、环境面板显示的版本、 README 的健康响应示例)必须一致,pnpm run gates 会静态比对 package.json#version。
- lib/* 是构建产物,不要手改;改 src/ 后重新 pnpm run bundle。

7. 目录

dsh-panel-dock-plugin/
├── package.json # 合同字段 + dsh.bundle / dsh.client ├── tsconfig.json ├── cordis.patch.yml # insert id/name = dsh-panel-dock-plugin ├── pnpm-workspace.yaml # 允许 esbuild 运行安装脚本(pnpm 11 读这里) ├── .gitignore ├── LICENSE ├── README.md ├── docs/plan.md # 设计计划 + 诚实性说明 ├── src/ │ ├── index.ts # Node half:/hello 命令 + /health 路由 │ └── client/ │ ├── index.tsx # Client half:面板系统(真源) │ └── index.ts # 再导出 barrel(verifier 约定路径) ├── scripts/ │ ├── build.mjs # esbuild:Node 走 ESM,Client 走 ModuleLoader 包装 │ ├── gates/run.mjs # 一致性门禁 │ └── test/client-runtime.mjs # 无浏览器运行时探针 └── lib/ # 构建产物(随仓库发布:git 源安装不需要构建工具链)

8. 许可证

MIT — 见 LICENSE。
预览分享卡片长什么样 ↓hemppp/dsh-panel-dock-plugin
分享 · DeepSeek Harness Hub
hemppp/dsh-panel-dock-plugin

拖动缩放折叠面板,布局自动保存并可一键还原

这是你的仓库?认领条目

回到顶部