- Accueil
- Plugins
- Améliorations UI
- dsh-better-workspace
dsh-better-workspace
kannakuron/dsh-better-workspace
Arborescence hiérarchique des espaces de travail pour la barre latérale DSH : chaque barre oblique d'un titre devient un dossier virtuel (profondeur arbitraire), le flux d'ajout d'espace de travail gagne un popup de groupe parent, les renommages recalculent l'arbre instantanément, les sessions s'imbriquent selon la même règle avec un style visuel distinct, et chaque ligne dispose d'actions au clic droit plus une personnalisation d'apparence par ligne (couleur, lueur du texte seul, graisse de police, icône de la famille primitives).
Installer
dsh plugin --profile web add github:kannakuron/dsh-better-workspaceREADME
dsh-better-workspace
简体中文 | English
给 DeepSeek Harness (DSH) 的侧边栏「工作区」列表装上一套两层文件夹系统——磁盘层按目录路径嵌套(官方 workspace-tree 语义:子目录里的工作区挂在父目录工作区之下),名称层吃工作区名字里的
/(「网页前端」「网页后端」归到同一个web分组),两层正交组合。
磁盘层(目录路径,自动嵌套) 名称层(名字里的 /,虚拟分组)
~/projects/ web/
├─ web/ ← 工作区(目录) ├─ 前端 ← 工作区「web/前端」
│ └─ api/ ← 子目录工作区 └─ 后端 ← 工作区「web/后端」
└─ docs/ ← 同级工作区
功能与效果
![]() |
层级树 工作区名称里的 / 即分组:web/前端、web/后端归到同一个 web 分组下,支持任意多级;不带 / 的工作区照常显示在根层。重命名工作区后树即时重排——分组只是名字的投影,没有第二份需要同步的数据。 |
添加工作区:官方目录流
点「添加工作区」走的是 DSH 官方的目录拾取流(v0.12.0 起):webserver 只绑本机 loopback 且有显示会话时,弹出宿主桌面上的原生选择器;绑到 0.0.0.0(局域网访问)、SSH 转发或宿主没有可用显示会话时,自动切换为官方应用内目录浏览器(多栏目录、从根开始的面包屑、可编辑路径、行内新建文件夹、隐藏文件开关)——这正是 0.11.x 自绘浏览器打磨的场景,官方补齐后整体让位。选完目录即创建工作区并开始一个新会话,与官方浏览器行为一致;对话空态页的「添加工作区」用的是同一套官方占用者,只是入口由本插件渲染(见下)。
分组不靠添加时弹窗——改名即归组:新建后重命名工作区(名称里的 / 就是分组),或直接拖拽进分组行。
分组:名字的投影
分组由工作区名称里的 / 自然派生,没有第二份需要同步的数据——右键分组行可重命名分组(批量改写组内所有工作区名称的前缀),分组树即时重排;根分组 = 名称不带 / 的工作区。
会话也吃这套规则
工作区里的会话名称同样用 / 分层(如 测试1/两个插件维护)。会话分组用次级配色且无文件夹图标渲染,和工作区文件夹一眼可辨;会话分组可整组重命名(批量改写成员标题)。
重启后标题不回退:DSH 重启后的冷列表只为命中投影缓存的会话携带标题——分叉出的会话与从未写过检查点的会话会暂时没有标题,真实的标题其实还在会话日志里。本插件把每个会话最近一次的真实标题持久化在浏览器里(带防抖的本地缓存,变更合并整写一次),回退窗口内直接用记忆标题渲染,/ 分级分组照常成立;打开会话后官方数据到位即自动纠正。从未有过标题的会话(例如只写了头部、零轮次的空会话)不再回退成「工作区名」,而是显示官方语义的「未命名」(v0.36.14,issue #16)。
设置与外观:外观自定义、默认外观与开关保存在当前设备,并随当前 DSH profile 持久化;折叠状态与会话本地序仍保持每端独立。
![]() |
外观自定义 右键任意一层(工作区分组 / 工作区 / 会话 / 会话分组)→「自定义外观」:颜色(预设色板 + 取色器 + RGB)、发光强度(0..14 拖动条,只作用于文字)、字体粗细、字体阴影开关、**字体描边**(开关 + 0.5–4px 粗细,**新安装默认关闭**——干净主题下描边更像浮凸噪点,配背景图时再打开;描边颜色默认**灰**,可改黑 / 白 / 任意取色,或选「自动」按字体颜色取反差色——浅色字配黑边、深色字配白边,并跟随主题与背景插件的界面明暗。升级安装不受影响:已开启描边的浏览器保持原样)、图标(与 dsh 图标库同族的 69 个,工作区与工作区分组专属),底部带实时预览。清除自定义一键复原。 |
![]() |
改完即见 颜色、文字发光、字体粗细、阴影与图标按行应用,和展开状态一起经 dsh 客户端 store 持久化在当前浏览器。 |
![]() |
右键菜单 操作都收进右键:工作区行——重命名 / 删除 / 分叉 / 归档 / 自定义外观 / 修改工作区默认预设(v0.32.0 起,改写该工作区常驻新会话所用的 agent 预设,走官方同一通道;内置预设显示官方本地化名——标准模式 / PTC 模式 / 极简模式 / 创造模式,v0.33.0 起;工作区暂无待命新会话时,确认后会预备一个带所选预设的新会话作为该工作区默认);工作区分组行——重命名分组(同步更新组内所有工作区名称)/ 自定义外观;会话与会话分组行——重命名 / 分叉 / 归档 / 自定义外观;会话行另有复制 Session ID(v0.30.0 起,对齐 dsh 0.2.1-alpha.5 官方会话菜单第五项——写剪贴板走宿主原语,复制成功与否均有提示)。 v0.38.0 起接入官方统一右键菜单:会话/工作区行由宿主共享菜单渲染,官方条目与插件补充项(移动到分组 / 移出分组 / 自定义外观 / 修改默认预设,排在分隔线之后)同席,官方新增条目会自动出现;分组行仍用插件菜单。 |
![]() |
设置卡片 设置 → 插件 → 插件配置 里新增「更好的工作区」卡片(官方折叠卡片样式),提供单链分组合并开关(如 测试层1 下只有 AI交易 一个工作区时,合并显示为一行 测试层1/AI交易)、状态呼吸灯开关(被折叠藏起的状态灯沿层级向外冒泡呼吸发光,默认开)、行密度三档(紧凑 / 标准 / 宽松,默认=官方行高,v0.34.0 起)与显示会话数开关(行尾会话数角标,默认关=官方,v0.34.0 起);另有默认外观区——颜色 / 发光 / 字体粗细 / 字体阴影 / 字体描边开关 / 描边粗细一次配好,没有单独自定义过的行全部继承(描边新装默认关,其余同「无自定义」)。设置随当前 DSH profile 持久化;展开状态与外观自定义另经 dsh 客户端 store 持久化在当前浏览器。 |
其余亮点
- 文件夹式收起:点工作区行 = 收起/展开该工作区的全部会话(收起后行上保留会话数角标;角标 v0.34.0 起默认隐藏、对齐官方,设置卡「显示会话数」可开);会话分组同样可收起;搜索时自动全部展开。
- 拖拽还原原版能力:工作区行可拖拽——拖到另一工作区行上/下半即调整顺序(写回宿主 registry 序),拖到分组行中带则移动进该分组(改写名称前缀);工作区分组行同样可拖拽(v0.36.0 起,三带悬停)——拖到分组行时行分三个落区:上下 30% 边带=与该组排序(拖完立即重排、刷新后保留),中带=整组移入(组成员逐个改写名称前缀,与「重命名分组」同一语义;拖到自身/自己的子孙组上会被拒绝);组行与工作区行同处一条混合序列(v0.36.5 起):一个层级里的行顺序只有一份(组行与裸工作区行交错),工作区可以拖到分组行的边带插到该组前面/后面,分组也可以拖到工作区行前面/后面——不再有「组永远排在裸工作区之前」的限制;拖到另一层的边带是放置(v0.36.6):工作区离开原组(或进入目标层)并插到落点,「插到第一个」画哪落哪(跨磁盘层不放行——磁盘层是文件系统事实);拖入黑框统一(v0.36.7):工作区行拖到分组行中带 = 改名前缀进组(黑框反馈);组行拖到它所属的磁盘层工作区行 / 直接父级分组行中带 = 整组「放入」该容器、排到该层末尾(标题与磁盘位置都不动,同一套黑框视觉)——排序走边带、放入走中带,两类操作视觉上彻底分开;容器防环(v0.36.9):磁盘层的容器工作区不能被拖进它自己的名称组或子工作区——那会把容器改名成自己的子孙(如「工作/用户目录」甚至「/用户目录」),现在整行拒绝、不留任何落点反馈,排序与放入父容器(v0.36.7)不受影响;平级组嵌套与提升(v0.36.10):组行拖到平级组行的中带=变成它的子组(成员标题落到新组之下,
工作/平行帮→工作/Fis管理后台/平行帮,天然不撞名——旧的并入语义会在双方都有同名子工作区时报 name-conflict、整树不动);组行拖到另一层工作区行的边带(同磁盘、不在自己子树内)=整组提升到那行所在层并锚定在落点旁(「把平行帮拖到和用户目录、工作平级」);已打开的排序槽不再锁死判定——指针推回行中带即可翻成放入黑框,嵌套与排序随时互切;静止松手兜底:Chromium 把指针静止约一秒后的松手吞成 dragend 时,按最后悬停的落点补提交(Esc 取消不受影响),不再「松手没反应」;撑开让位(v0.36.4):进入排序边带立刻把目标行撑开一行(工作区行与分组行同一套视觉),判定按行未撑开时的原始位置算——指针停在槽空出的新区里保持当前方向不闪烁;槽已打开的行只按原始中线二选一(上半=插在前,下半=插在后,不会翻成「移入」),三带里的中带 INTO 只在首次进入时决定,随时可改主意;会话行可拖拽——同组内拖到另一会话上/下即调整顺序,拖到别组的会话行会把名字前缀改写到那个组(拖到根层的行 = 移出分组),拖到会话子分组行即移动进该分组,拖到自己的工作区行或树里任何组外的地方(含空白区域)同样移出分组 —— 拖拽期间工作区行整行高亮、树底部有一条淡虚线提示这个出口;带分组前缀的会话行右键还多一项「移出分组」。显示顺序 = 宿主手动序(分组行 = 父容器下的持久化组序),拖拽结果立即生效。磁盘层是文件系统事实,不随拖拽改变:跨磁盘层不放行(边带不接管光标、不画落点线),同磁盘层内按落点锚定。拖拽期间树形保持不变(v0.36.4):单链合并行不再临时展开、归组成功也不自动展开目标组——指针下的行不会突然换人,展开状态只在点击时改变。 - 不丢原生能力:会话行(打开/重命名/分叉/归档;双击标题重命名,v0.34.0 起;右键是唯一菜单入口——行内「⋯」已退役,悬停只留快捷钮,工作区行同样只留新会话钮,v0.35.1 起)、官方行样式逐项对齐(v0.34.0 起:恒定 16px 状态槽——运行转圈不再挤动标题、悬停 800ms 弹官方 HoverCard(标题/路径/时间/状态,可复制)、超长标题悬停匀速滚动、活动链工作区文件夹图标着蓝、拖放指示用官方斜纹图案)、每工作区「新会话」(点 + 总是先展开该工作区,让新会话立刻可见)、当前会话高亮、官方状态灯(蓝色运行环 / 琥珀待交互 / 绿色完成提醒)、状态呼吸灯(折叠藏起的状态灯向外冒泡:工作区/分组行图标按状态色呼吸发光——琥珀待交互/绿完成,自定义过发光的标题一起呼吸;运行中只在会话行本层蓝色呼吸,不外渗;可在设置关闭)、活跃定时任务角标(有活动 Schedule 的会话显示闹钟图标;v0.23.0 起直接渲染官方
sidebar.session.row.leading座位的占用者,与官方行同源)、未分组会话兜底、界面文案跟随 DSH 的语言设置(内置 21 种语言,含简繁中文)。 - 新增项自动配色 + 图标(v0.25.0,默认关闭):设置卡里一个开关,打开后新创建的会话自动分到一个内置色、新工作区再额外分到一个图标,懒得逐个设置的人直接开箱即用。颜色来自定死的 13 个槽位,每个槽位配两色——浅色主题用深色系、深色主题用亮色系——按「洗牌袋 + 近期回避窗口」抽取:一轮之内绝不重复,跨轮也不会立刻撞上刚出过的 3 个,连续新建几项肉眼可辨。可读性是真达标:每个色在对应主题背景下的对比度都 ≥4.5,即 WCAG 正文级 AA(对比度是脚本真算的,测试逐色断言;浅色主题按比纯白更暗的悬停面、深色主题按最亮的面这种保守取值)。行里存的是槽位 id(
auto:3)而不是色值,所以切换深浅主题时颜色自动换成同色系的另一套,既不用重新设置,也不会失配。只影响打开开关之后新建的项:你手动设置过外观的行(存的是 hex)永不被覆盖,关闭开关也不回收已分配的样式,同一项不会被二次随机。图标从既有图标候选集里取、按宿主实际导出过滤;图标只给工作区——会话行的那个位置是官方状态灯与日程角标,没有图标位。 - 官方新语义与快捷键都接上(v0.23.0,对齐 dsh 0.1.7-rc.2):① 归档筛选是官方新版三态直选(隐藏已归档 / 全部对话(显示已归档) / 仅显示已归档);选「仅显示已归档」时没有归档会话的工作区整行隐藏,空列表显示「暂无已归档会话」+「查看其他会话」一键回退;② 官方快捷键 ⌥⌘K 搜索 / ⌥⌘O 添加工作区 / ⌥⌘N 新会话(桌面端为 ⌘K / ⌘O / ⌘N)在本插件的自绘侧栏里真的生效——搜索键打开并聚焦本插件的搜索框、添加键走同一个官方目录流(原生宿主弹系统选择器,browse 宿主直接弹出官方应用内目录浏览器),按钮文案还会带上宿主当前的键位;③ 首次使用的工作区显示为本地化的「默认工作区」,不再露出磁盘目录名。
- URL/斜杠标题不拆层:宿主自动生成的会话标题落地时若含
/(如复述了 URL),整串自动包上“”原样显示,绝不解析成层级——只对本次启动后新建的会话生效,并等命名稳定(约 20 秒,让原生 AI 命名先落地)才处理;存量会话与你手动命名的/分组标题永不被改动。引号内(含手动添加)的/永不切分,孤立引号只当普通字符;无引号但含 URL 的旧标题也有平铺兜底。v0.37.2 起再加一道路径保护(issue #17):标题里引用绝对路径(/Users/...、C:/...这类含至少两个/的路径 token)时,整条标题作为一个会话行显示,绝不拆成伪目录——存量会话与首条消息回显的标题同样生效,web/前端这类正常的名称分组不受影响。v0.37.3 起路径标题不再被 20 秒稳定期改成带引号的用户标题:显示层已经平铺,原逻辑反而会把回显路径钉死并取消尚未落地的 AI 命名;现在直接放过,等 AI 总结名替换。会话分组仍默认开启,不需要的话可在视图菜单关掉。 - 新会话页的工作区选择器 = 侧栏那棵树(v0.22.0):会话空态页「工作区」按钮的弹层原本是官方的一层平铺标题列表(连磁盘目录嵌套都没有);本插件接管该座位后,弹层绘制与侧栏同一棵树——磁盘目录嵌套、「/」名称分组三态、单链合并全部读同一个视图 store,所以侧栏的视图选项一改,这边立刻跟着变;当前工作区带勾选标记,分组行可开合(选择器内本地记忆,默认全展开),标题按侧栏的层级叶子显示。底部「添加工作区」仍由官方目录拾取占用者承载(原生选择器 / 官方应用内浏览器),不是仿制品。
![]() |
同一棵树,两个入口 左图是「新会话」页工作区按钮的弹层:分组行带 chevron(可开合)、工作区行带文件夹图标与层级缩进、当前工作区带勾选,底部是官方目录流驱动的「添加工作区」。它和左侧栏共用同一份视图状态——在侧栏把「工作区分组」从「磁盘 + 名称」换成「磁盘目录」或「仅名称」,这里的分组结构立即跟着变,不需要刷新,也没有第二份需要同步的数据。 |
安装
dsh plugin --profile web add dsh-better-workspace # npm 公开包
# 源码与 Release: https://github.com/KannaKuron/dsh-better-workspace
纯 JS、零构建、零 npm 依赖(只依赖 dsh 客户端基线模块),安装不触发任何构建脚本。装完重启 DSH 即生效。
手动挂载(不用 CLI 时)
把包放进 profile 的 node_modules 后,在 profile 的 cordis.patch.yml 里加:
- insert:
- id: better-workspace
name: 'dsh-better-workspace'
工作原理
DSH 的侧边栏浏览区是一个公开插槽 sidebar.workspaces(single),官方工作区浏览器是它的占用者;本插件以更低优先级注册同一插槽,整区替换为层级树版本。数据全部来自插槽标准注入(useWorkspaces / useSessions 快照钩子),动作(打开会话、重命名/删除工作区、归档等)也走注入的宿主动作。唯一例外是关闭历史会话的重命名:rc.1 公开面只有 sessions.binding / sessions.using(using 会打开历史),不打开历史的快速路径仍要读 sessions.manager,代码里标为 PRIVATE BRIDGE;官方把这条路径公开后应立即删除该桥。
「添加工作区」完全交给官方:官方组合占用者(原生选择器 / 应用内浏览器)承载全部拾取交互;本插件作为 owner 只负责选完目录后的创建与新会话。两个 directoryFlow 子洞自 v0.16.0 起都不由本插件声明——子洞声明是独占的,接管座位的一方永远拿不到 renderSlot 授权(相关事故见 CHANGELOG)。侧栏添加动作先探测后端:native 直接调官方 pickDirectory();browse 从 slot ledger 读出官方占用者组件(连同它自己的注入面),由本插件补上 owner 对话(open / busy / onPicked / onCancel / onError)后直接渲染。空态页的添加动作使用同一套读法。原生与 browse 宿主各自保留出厂交互;ledger 读不到占用项时,少的只是「添加工作区」这一项,选择器照常工作。该机制要求 dsh >= 0.2.2-rc.1。
会话空态页的工作区座位(conversation.hero.workspace)与侧栏同理:本插件以更低优先级注册同一座位,弹层换成侧栏同源的树;该座位不声明任何子洞,所以官方 picker entry 的所有权不受影响。
视图状态(分组折叠、会话展开)、外观自定义与插件设置都通过 dsh 客户端 store 持久化在浏览器本地(dsh.betterWorkspace.view.v1)。注意:该 store 的 hydration 是整值替换、不合并默认值——升级后如果遇到状态字段缺失,重启前的旧状态按旧结构保留,缺的键自动回退默认。
与 dsh-better-sidebar 的关系
同属 dsh-better-* 家族,但互不重叠:dsh-better-sidebar 是右侧的 VSCode 式面板(资源管理器/终端/Git);本插件只接管左侧工作区列表。两者可同装。
版本兼容
- 运行时下限:dsh >= 0.2.2-rc.1,Node.js >= 24.9.0。本插件自 v0.39.0 起只维护这一代宿主,不再为 0.1.x / 0.2.0 / 0.2.1 / 0.2.2-rc.1 之前的预发布保留探测或回退。
- rc.1 契约:全局标准 hook 使用
useSessionStatus/useSessionAccess;会话/工作区行接入官方contextMenus;会话行渲染官方sidebar.session.row.trailing与sidebar.session.row.leading座位;设置只注册官方插件面板的plugins.bundle.config座位。 - 设置持久化:插件 Config 只公开
compactChains/statusPulse/styling/appearance四个 volatile 字段;其余视图偏好留在浏览器本地 store,不再尝试写宿主。跨端手动同步已随共享settings.yaml时代一起移除。 - 用户数据迁移:旧快照的
workspaceTitleSlash/ 缺省stroke键 / 旧图标名仍按读时分代解析,升级不会改变既有外观与分组;这类兼容只针对本插件自己的旧数据,不针对旧宿主。
限制与路线图
- 会话跨工作区拖拽仍被拒绝(会话归属工作区);同一工作区内的分组归属已随拖拽生效(v0.18.0:拖到别组的行改写前缀,拖到自己的工作区行移出分组,右键也有「移出分组」)。
- 搜索为本地标题过滤(两层扁平化后逐工作区匹配);宿主内容搜索(
session.search)计划接回。 - flat(平铺)视图未接管,层级树即视图。侧栏切到「单列表」时,新会话页的选择器退化为一层完整标题的工作区列表(仍可选,不再分组);切到「按工作区」时(v0.36.11 起),只要「工作区分组」开着(磁盘+名称 / 仅名称),侧栏与新会话页选择器都显示名称树挂顶层的结构(名称组与磁盘容器平级,切换即时生效);「工作区分组」设为「磁盘目录」时保持官方的散开平铺。
- 新会话页选择器里的分组开合是选择器本地状态(默认全展开):它不写侧栏的折叠状态,免得选工作区时被侧栏的折叠挡住目标。
开发
npm test # 冒烟测试:清单一致性 / 基线 require 白名单 / 21 门词典键集对齐 / 语法
npm pack # 出 tarball 后可本地安装验证
本地验证:把 npm pack 产出的 tarball 装进 web profile 并手动挂载(见上),重启 DSH,验证:层级树渲染、添加工作区弹窗、重命名即时重排、新建分组、卸载后回到原浏览器。
License
Plugins associés
dsh-web (dsh-task-board)
zhu1090093659/dsh-web
dsh-web (dsh-web-all)
zhu1090093659/dsh-web
dsh-TUI
ccch1mneyyy/dsh-tui
dsh-web-ui (dsh-task-board)
zhu1090093659/dsh-web-ui





