🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI
广告☁️ 云服务器特惠阿里云首购 8 折 · 腾讯云合作特惠
DeepSeek Harness Hub
← 返回列表

ice-ai-lab/dsh-plugin-pi-ui

DeepSeek 客户端兼容 / 相关生态spec-screened扫描:中风险在 GitHub 查看 ↗
未验证

description: "面向 DeepSeek Harness Web GUI 的 pi-web…

尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/9/11 · 已提供中文文档

为 DeepSeek Harness Web GUI 打造的受 pi-web 启发的侧边栏界面:临时会话、位于工作目录选择器下的单目录会话列表、在你发送前不会创建任何内容的草稿编辑器,以及一个紧凑的文件浏览器标签页。

综合分
28.6
GitHub 分
28.6
用户评分
—
★ Stars
0
周下载量
—
兼容 / 相关生态插件(非 dsh 原生,请按其对应运行时安装)
git clone https://github.com/ice-ai-lab/dsh-plugin-pi-ui.git
信任档位:已验证本站已于 0 天前真实安装成功
是什么
生态应用(桌面端 / Web 外壳,不以 dsh plugin add 安装)
装得上吗
本站已真实安装成功(非静态推断)
安全吗
本站尚未对该插件做风险分级(暂未覆盖,不等同于无风险)
还在维护吗
活跃:最近一次提交在 14 天前

档位由下列信号合成:本站实装验证(真实安装,当前最高到 L4)· 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。下方各区块是它的证据明细。 验证判据与等级说明 →

🟢实装验证通过· 2026/9/25
由本站实装验证器在真实 dsh 环境安装成功,非静态推断。
数据截至 2026/9/24(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis
用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动

README

由 DeepSeek 最新模型翻译生成
description: "面向 DeepSeek Harness Web GUI 的 pi-web 风格侧边栏:顶部临时会话、工作目录选择器与其下"一次只显示一个目录"的会话列表、发送前不创建任何东西的草稿输入框,以及接管右侧栏「文件」标签页的紧凑文件浏览器。"
kind: "package-reference"

dsh-plugin-pi-ui

概述

本包把 Web GUI 的左侧边栏重新组织成读起来像同一套系统的几个区块,全部使用
harness 的 --dsw- 设计变量,因此跟随所有内置主题:

1. 顶部:临时会话。 最新的即用即弃会话,默认显示 5 条,查看更多每次再
加载 10 条。+ 按钮进入草稿态;🗑 清理没有任何会话在使用的临时目录。
2. 中间:工作目录。 锚定在侧边栏垂直中央,紧凑下拉框用来选择当前工作的
目录——它下面的随附会话列表永远只显示该目录的会话。
3. 右侧栏:紧凑文件浏览器,占据原本显示内置工作区文件视图的「文件」标签页。

贯穿三者的一条规则:发送之前什么都不存在。 任何"新建会话"手势都只是进入
草稿输入态;在你真正发出第一条消息之前,不会创建任何临时目录、也不会在侧边栏
多出任何会话行——发送的那一刻目录与会话才一起创建,或者复用指定目录里已有的
空白会话。

目录

- 安装
- 使用
- 实现说明
- 延伸阅读
- 模型侧体验
- 已知限制与后续工作
- 开发备注

安装

这是一个普通的树外插件包:一个 node 半部、一个浏览器半部,以及一个 loader
patch。把它加进 profile 后重启 dsh web。

在已能解析该包的 profile 中:
dsh plugin --profile web add dsh-plugin-pi-ui

包内声明了 dsh.bundle.patch,所以上面这条命令会把它追加到
dsh.profile.bundles,其自带的 cordis.patch.yml 会在下次启动时生效。等价的
手写行放在 profile 自己的 patch 层:

~/.dsh/profiles/web/cordis.patch.yml
- insert:
- id: pi-ui
name: 'dsh-plugin-pi-ui'

两种方式只能用一种:同一个 row id 插入两次会导致启动失败。本地开发时用
link 依赖,改动在重启后依然有效:

// ~/.dsh/profiles/web/package.json
{
"dependencies": {
"dsh-plugin-pi-ui": "link:/absolute/path/to/dsh-plugin-pi-ui"
}
}

必须重启 dsh web。 浏览器半部在启动时被合成进 window.__DSH_BOOT__,所以
新加入的客户端插件无法出现在已经运行的服务器里(node 半部是可以热加载的)。
重启后刷新页面。

卸载时:从 dsh.profile.bundles(或 profile patch)里删掉该行、移除依赖、重启。
临时目录会留在磁盘上,不需要时删除 /scratch/。

使用

侧边栏一瞥

[ 临时会话                         1  🗑  + ]
⋮  (侧边栏垂直中央)
[ 工作区  [ 📁 …/my-project ▾ ]        + ]
[ 该目录下的会话 …                        ]

侧边栏展开时,随附的整宽"新建会话"按钮、搜索放大镜、添加工作区按钮都会让位,
由插件提供下表控件;折叠成 rail 时插件不绘制任何东西,随附控件全部回来。

| 控件 | 行为 |
| --- | --- |
| 临时会话标题行的 + | 进入临时会话草稿态。点击本身不创建任何东西;发送时临时目录与会话一起创建。若会话创建失败,刚建的目录会被删除,不留孤儿目录。 |
| 临时会话标题行的 🗑 | 删除没有会话在使用的临时目录(仅当存在这样的目录时出现)。会先确认,且从不碰正在使用的目录。 |
| 工作区与其 + 之间的下拉框 | 工作目录选择器:已有目录、打开文件夹…、删除工作目录…。选中有会话的目录会打开它的空白会话(否则打开最新会话);选中还没有任何会话的目录,则进入草稿态而不是先建一个会话。 |
| 工作区行右侧的 + | 进入"在所示目录中新建会话"的草稿态。点击不创建任何东西;第一条消息才创建会话,若该目录已有空白会话则直接复用。 |
| 删除工作目录… | 列出所有已注册目录及其会话数,可移除选中的那个。移除只动注册表:目录本身、其中的文件与会话日志都保留,那些会话只是不再按该工作目录分组。 |

临时会话行用于重新打开对应的 scratch 会话。临时会话刻意不出现在下拉框里
(那个控件保持为纯粹的目录选择器),也不会注册成 workspace,因此不会在持久化的
工作区注册表里越积越多。

发送之前什么都不存在

任何开始手势最终都落在同一个地方:草稿输入框,而不是新会话。这样侧边栏不会再
出现没人写过的"新会话"行;临时会话的目录也只在你发送的那一刻才出现在
/scratch/ 下。

草稿输入框就是随附的空白态卡片,只是上面叠了两个可用的镜像控件:覆盖在卡片
自身输入区上的可编辑输入框,以及覆盖在卡片(禁用的)发送圆钮上的发送控件。卡片
的其它一切都还是随附原样——虚线边框、附件按钮、权限选择、模型座位、发送按钮的
外观,全部由随附组件渲染。插件不加提示文字,也不添加自己的控件。打字后按 Enter
或点发送圆钮即可。

会话列表永远只显示一个工作目录

工作区下面的区域是"某个工作目录的会话列表",一次只显示一个目录的会话——就
是选择器当前显示的那个:当前会话所属工作区优先,否则是你上次选定的目录。临时
会话不携带工作目录,因此既不会改变这个列表,也不会出现在其中。没有开关、也没有
"显示全部"状态:选择器本身就是选择动作。

选择器属于你,而不是属于当前会话:上次选定的目录记在浏览器里,所以进出临时会话
永远不会把它清空。搜索(区块标题行的放大镜)不受列表显示范围影响,仍然搜索全部
会话。

设置

设置 → 通用新增两个开关:

- 文件浏览器——用本插件的浏览器替换右侧栏内置的文件视图;关掉立即恢复内置
视图,无需刷新。
- 工作目录切换器——本插件侧边栏 chrome 的总开关。

两者都只在内存中,刷新后重置。这是有意为之:要持久化就应该走设置服务,而不是
客户端本地存储。

实现说明

为什么用浮层实现

随附侧边栏在其浏览区域上方没有声明任何座位,而品牌行里的座位
(sidebar.brand.mark / sidebar.brand.name)都是已被随附包占用的 single
单元——注册进去会遮蔽产品品牌,而且两者都在一个"开始会话"的  里。
所以本插件注册到 frame 级、可叠加的列表座位 shell.overlay,再把它的
界面定位到侧边栏列上。

座位拿不到几何信息,所以插件自己测量。它用语义化的 CSS module 类名后缀定位
侧边栏列(构建保留了它们:运行时类名形如 _regionArea),并写入一个自定义
属性:

[class="regionArea"] {
padding-top: var(--dshpi-reserve-top, 0px);
}

随附区域会为这条预留带留出空间,于是临时会话列表位于会话列表内容之上而不是覆盖
它。另外三个标记同样是刻意而克制的:

- 列上的 data-dshpi-wide(仅在列较宽时设置)隐藏随附的整宽"新建会话"按钮、
标题行操作与搜索按钮,并预留品牌右侧内边距,让这一行原有文字不被替代控件压住;
折叠 rail 保留全部随附控件。
- data-dshpi-focus 加上一条单规则样式表,只显示一个会话分组(见下)。
- data-dshpi-header-controls 让标题行没有插件绘制控件时这个 CSS 钩子仍然有意义。

其余随附元素一律不动。

"一次一个目录"的会话列表

浏览区域是 ui-workspace 已占用的 single 座位,其分组行不携带工作区标识,
所以插件无法过滤列表数据。它能依赖的是列表自身的顺序:groupByWorkspace 按
Host 顺序为每个 workspace 输出一个分组,并把"无工作区"桶放在最后——因此分组的
位置就是它对应工作目录的位置。给列打标记、再用一条 nth-of-type 规则只显示
那一个位置,是声明式的,也不会被 React 重渲染抹掉。

被聚焦分组的文件夹标题会在展开时隐藏,让这一区域读起来像普通会话列表,而不是
只有一个子项的文件夹。之所以只在展开时隐藏:折叠状态下那条标题是唯一能展开它的
控件——而折叠状态是持久化的,又已经没有开关可以退出,保留这个控件才不会让某个
折叠的分组把目录彻底困住。同样的道理也解释了下拉框里的 删除工作目录…:其它
分组都被隐藏、聚焦分组的标题在展开时也被隐藏,随附的重命名/删除手势已经够不到。

草稿输入框

空白态下随附卡片是禁用的:ui-conversation 只为"带工作目录的会话"激活它(靠它
自己的 chip 标题),而且在没有会话时连模型座位都不渲染。因此插件只镜像草稿真正
需要的两个控件,其余那一行原样保留:

- 输入框通过 [data-composer-card] / [data-composer-input] 测量,用一个无边框
但填了卡片自身 --dsw-specific-input-major 的 textarea 覆盖(这样下面的随附
占位文字不会透出来),字号、行高、光标色也取自卡片;
- 发送控件通过卡片的主按钮测量,用同样尺寸、圆角与填充色的可用镜像覆盖。

测量是一次按帧合并的流程,由 400ms 轮询、窗口 resize 监听与 body 子树
MutationObserver 触发,因此镜像会跟随 hero 的入场动画、侧边栏折叠与窗口缩放。

开始手势与待定目标

开始手势会设置一个内存中的待定目标并清空当前选中,从而把草稿输入框推到台前:

| 目标 | 发送时创建什么 |
| --- | --- |
| scratch(临时会话 +,默认) | 先 POST /dsh-pi-ui/scratch 在 scratch 根下生成目录,再以该 cwd 创建会话。会话创建被拒绝时会删除刚建的目录。 |
| workspace(工作区 +、以及没有任何会话的目录) | 以该 workspaceId 创建会话——完全不写磁盘。若该目录已有空白会话,则复用它而不是再建一个。 |
| cwd(插件能看到的无会话目录) | 以该 cwd 创建会话。 |

目标只存在于内存中,并且一旦有任何会话打开就被清除,所以在首次发送前刷新页面
只是丢掉草稿而已。

文件浏览器作为右侧栏标签类型

ctx.sidebarRightTabs.register(...) 以 extension 优先级接管内置文件视图的类型
——即 files kind(这是"产品之外的类型"可以接管 builtin kind 的那一档);键控座位
sidebar.right.pane.tab 则以本类型自己的 id 提供主体。guide 条目让右侧栏的
"新标签页"页面继续列出它;由于该条目替换了内置的那个,右侧栏的默认页仍然是同一个
kind。

树以当前会话的工作目录为根——临时会话就是它的 scratch 目录——并通过本包的 node
半部逐层读取。点击文件经由 harness 资源地址打开,因此和随附树的行为一致。把设置
开关关掉即注销该类型,内置视图立即恢复。

node 半部

三条普通 exact HTTP 路由——树外插件没有 Remote 命名空间的代码生成步骤:

| 路由 | 方法 | 边界 |
| --- | --- | --- |
| /dsh-pi-ui/tree | GET | 只读、只列直接子项、经 harness fs 后端解析;解析后若逃出会话工作目录即拒绝;上限 800 条;从不读取文件内容。 |
| /dsh-pi-ui/scratch | GET / POST | POST 不接受任何调用方输入:目录名在服务端生成,且只落在 scratch 根下。 |
| /dsh-pi-ui/scratch/delete | POST | 只接受名字。每个名字必须是单一路径段,解析后再做一次包含性检查,scratch 根自身永远不是删除目标。单请求上限 200 个名字 / 64 KiB。 |

与本生态中的其它插件界面一样,这些路由不在浏览器会话 cookie 之后。请把它们视为
仅本机可用,不要把服务器暴露到 loopback 之外。

持久化了什么

只有一个客户端本地键:dsh-pi-ui.workspace,即选择器上次显示的目录。其它东西
——待定目标、两个设置开关、测量到的几何信息——都在内存里。临时会话完全不需要
额外记账:它们通过把会话的工作目录与规范化后的 scratch 根做匹配来识别。

延伸阅读

- @deepseek-ai/dsh-client-ui-slots 与渲染器的座位语义——single、list、
keyed、chain 各自对注册者承诺了什么。
- @deepseek-ai/dsh-client-ui-sidebar-right——本插件浏览器所注册的标签注册表,
包括优先级分档。
- @deepseek-ai/dsh-client-ui-workspace——被本插件逐次聚焦的会话分组所在浏览器。
- @deepseek-ai/dsh-host-directory-picker-browse 及其客户端半部——组合它们即可
用 pi-web 的应用内浏览器替换操作系统选择器。插件的 打开文件夹… 会先试
应用内原语、再回退到系统选择器,无需改动插件。
- dsh --profile web --dump-config——合成后的 profile 树,查看当前生效的 bundle
与 patch 层最快的方式。

模型侧体验

本插件不注册任何工具或命令,模型只会看到 harness 本来就提供的东西。本包改变的
部分:

- 临时会话的工作目录是 /scratch/-/,在发送
时创建。普通沙箱策略会像对待任何其它会话一样把会话限制在那里。
- 会话列表、选择器、草稿输入框、文件浏览器都是纯界面,不会写会话日志,也不会
触达模型。
- node 半部的三条路由是 HTTP,不是工具,永远不会提供给模型。

安全提示。 scratch 根位于 harness home 内,而那里也存放着凭据。以此处为根
的会话和其它会话一样受普通沙箱策略约束;但如果你的策略允许会话读取工作目录之外
的内容,临时会话就能读到  下的祖先目录。若在意这一点,请把
DSH_HOME 指向别处,或优先使用显式指定的工作目录。

已知限制与后续工作

- 随附的那一行保持原样。 空白态下随附的权限与模型座位是禁用的,因为随附会话
只为"带工作目录的会话"激活它们。插件只让输入与发送可用,并且刻意不重排、不
替换这一行的其余部分。
- 待定目标只在内存中。 首次发送前刷新页面会丢掉草稿;由于什么都没创建,除了
已输入的文字没有任何损失。
- 移除只动注册表。 删除工作目录… 从不删除目录或会话日志。
- node 半部改动需要重启。 随附 web profile 启动时关闭了宿主 HMR,所以
lib/index.js 在启动时读取;浏览器半部则通过 dsh-client-hmr 热更新。
- 永远只显示一个目录。 已经不存在"显示全部目录"的状态;这正是选择器的意义,
但也意味着没有任何会话的目录会显示为空区域,直到你切走。

开发备注

lib/index.js        node 半部:上面三条路由
lib/client.js       浏览器半部:chrome、草稿输入框、浏览器标签
cordis.patch.yml    本包贡献的 loader row
README.md           英文版
README.zh.md        本文件(中文版)
README.i18n.yaml    双语配对记录(git blob 哈希)

lib/client.js 是手写的客户端模块系统构建格式包
(window.__ModuleLoader__.load({ id, factory }))。它只请求平台种子模块——
react 与 @deepseek-ai/dsh-client-ui-primitives——因此没有声明
dsh.client.external,整个插件就是两个脚本文件,没有构建步骤。

npm run check   # 对两个半部执行 node --check

单个界面内的崩溃是被隔离的:切换器及其对话框各自有错误边界,一处失败不会卸载其余
chrome;浏览器标签的注册也逐步做了保护,右侧栏接线出问题只会损失浏览器,而不会
影响侧边栏。

README 双语版本靠人工保持同步;README.i18n.yaml 记录两侧的 blob 哈希,两边一起
改,或者都不改。

上游仓库有新提交时邮件通知你(每天最多一封,无更新不打扰),随时一键退订。

同作者(ice-ai-lab)的其他插件

💬 加入社群

插件用法、部署报错、新插件第一时间同步——群里问,比一个人翻文档快。

DPharness QQ 群二维码,QQ 扫码进群
QQ 扫码进群
DPharness 飞书群二维码,飞书扫码进群
飞书扫码进群