dsh-better-workspace 0.11.5 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,14 +4,14 @@
4
4
 
5
5
  简体中文 | [English](README_EN.md)
6
6
 
7
- > 给 [DeepSeek Harness (DSH)](https://www.npmjs.com/package/@deepseek-ai/dsh) 的侧边栏「工作区」列表装上一套**文件夹系统**——工作区还是那个工作区(一个目录),但名字里的 `/` 就是层级,让「网页前端」「网页后端」这类工作区可以归到同一个 `web` 分组下。
7
+ > 给 [DeepSeek Harness (DSH)](https://www.npmjs.com/package/@deepseek-ai/dsh) 的侧边栏「工作区」列表装上一套**两层文件夹系统**——**磁盘层**按目录路径嵌套(官方 workspace-tree 语义:子目录里的工作区挂在父目录工作区之下),**名称层**吃工作区名字里的 `/`(「网页前端」「网页后端」归到同一个 `web` 分组),两层正交组合。
8
8
 
9
9
  ```
10
- web/ ← 虚拟分组(不是真实目录,纯命名层级)
11
- ├─ 前端 ← 工作区「web/前端」
12
- └─ 后端 ← 工作区「web/后端」
13
- 测试/
14
- └─ 两个插件维护 原有的单层工作区照常工作
10
+ 磁盘层(目录路径,自动嵌套) 名称层(名字里的 /,虚拟分组)
11
+ ~/projects/ web/
12
+ ├─ web/ 工作区(目录) ├─ 前端 ← 工作区「web/前端」
13
+ │ └─ api/ ← 子目录工作区 └─ 后端 ← 工作区「web/后端」
14
+ └─ docs/ 同级工作区
15
15
  ```
16
16
 
17
17
  ## 功能与效果
@@ -23,15 +23,15 @@ web/ ← 虚拟分组(不是真实目录,纯命名层级)
23
23
  </tr>
24
24
  </table>
25
25
 
26
- ### 添加工作区:选完文件夹,再选「所属分组」
26
+ ### 添加工作区:官方目录流
27
27
 
28
- 点「添加工作区」并选完文件夹后,弹出一个小对话框,一行选择工作区所属分组——直接输入( `web`)、从下拉里选已有层级(datalist 原生补全),留空就是根分组。确认后插件创建工作区并把分组前缀写进名称,树上自然落位。
28
+ 点「添加工作区」走的是 **DSH 官方的目录拾取流**(v0.12.0 起):webserver 只绑本机 loopback 且有显示会话时,弹出宿主桌面上的**原生选择器**;绑到 `0.0.0.0`(局域网访问)、SSH 转发或宿主没有可用显示会话时,自动切换为官方**应用内目录浏览器**(多栏目录、从根开始的面包屑、可编辑路径、行内新建文件夹、隐藏文件开关)——这正是 0.11.x 自绘浏览器打磨的场景,官方补齐后整体让位。选完目录即创建工作区并开始一个新会话,与官方浏览器行为一致;对话空态页的「添加工作区」同样回归官方。
29
29
 
30
- **用哪种目录选择器,跟随宿主实际组装的后端**:webserver 只绑本机 loopback 时是宿主桌面上的**原生选择器**;绑到 `0.0.0.0`(局域网访问)、SSH 转发或宿主没有可用显示会话时,宿主只组装 `browse` 后端——它仅提供「列目录 / 新建目录」原语,`pick` 会被明确拒绝——插件这时改用**应用内目录浏览器**(Home 起点的面包屑、可编辑路径、行内新建文件夹、显示隐藏文件),选定目录后照样进同一个「所属分组」对话框。若确实想在这种绑定下走原生选择器,只能由用户显式钉死宿主的 native 后端包,而那会在**服务器桌面**上弹窗,局域网客户端根本够不着。
30
+ 分组不靠添加时弹窗——**改名即归组**:新建后重命名工作区(名称里的 `/` 就是分组),或直接拖拽进分组行。
31
31
 
32
- ### 分组的增删
32
+ ### 分组:名字的投影
33
33
 
34
- 右键任意分组行即可:**新增子分组**(路径自动带上父分组前缀)、**新增子工作区**(选完目录后所属分组输入框自动预填)、重命名分组、删除空分组;标题栏不再放独立按钮。空分组持久保存在浏览器本地;一旦有工作区落进去,分组就由名称自然派生。
34
+ 分组由工作区名称里的 `/` 自然派生,没有第二份需要同步的数据——右键分组行可**重命名分组**(批量改写组内所有工作区名称的前缀),分组树即时重排;根分组 = 名称不带 `/` 的工作区。
35
35
 
36
36
  ### 会话也吃这套规则
37
37
 
@@ -39,7 +39,7 @@ web/ ← 虚拟分组(不是真实目录,纯命名层级)
39
39
 
40
40
  **重启后标题不回退**:DSH 重启后的冷列表只为命中投影缓存的会话携带标题——分叉出的会话与从未写过检查点的会话会暂时回退成「工作区名」显示,真实的标题其实还在会话日志里。本插件把每个会话**最近一次的真实标题**持久化在浏览器里(带防抖的本地缓存,变更合并整写一次),回退窗口内直接用记忆标题渲染,`/` 分级分组照常成立;打开会话后官方数据到位即自动纠正。
41
41
 
42
- **跨端手动同步(Web ↔ 桌面客户端)**:外观自定义、默认外观、显式分组与开关默认保存在各设备自己的浏览器里;设置卡片新增「跨端同步」区——Web 上点「从客户端获取」、客户端上点「从 Web 获取」,可选**覆盖本设备**或**合并两端**(并集保留各自独有项),另一端的数据经宿主设置存储(~/.dsh/settings.yaml,两端共享)送达;旁边有「发送本设备数据」按钮,旧版本的历史数据首次同步推一次即可,之后每次修改都会自动写入宿主、对端随手可取。折叠状态仍保持每端独立。
42
+ **跨端手动同步(Web ↔ 桌面客户端)**:外观自定义、默认外观与开关默认保存在各设备自己的浏览器里;设置卡片新增「跨端同步」区——Web 上点「从客户端获取」、客户端上点「从 Web 获取」,可选**覆盖本设备**或**合并两端**(并集保留各自独有项),另一端的数据经宿主设置存储(~/.dsh/settings.yaml,两端共享)送达;旁边有「发送本设备数据」按钮,旧版本的历史数据首次同步推一次即可,之后每次修改都会自动写入宿主、对端随手可取。折叠状态仍保持每端独立。
43
43
 
44
44
  <table>
45
45
  <tr>
@@ -55,7 +55,7 @@ web/ ← 虚拟分组(不是真实目录,纯命名层级)
55
55
  <table>
56
56
  <tr>
57
57
  <td align="center" width="58%"><img src="docs/screenshots/5-context-menu.png" alt="右键菜单"/></td>
58
- <td valign="top"><b>右键菜单</b><br/>操作都收进右键:工作区行——重命名 / 删除 / 分叉 / 归档 / 自定义外观;工作区分组行——新增子分组 / 新增子工作区 / 重命名分组(同步更新组内所有工作区名称)/ 删除空分组 / 自定义外观;会话与会话分组行——重命名 / 分叉 / 归档 / 自定义外观。</td>
58
+ <td valign="top"><b>右键菜单</b><br/>操作都收进右键:工作区行——重命名 / 删除 / 分叉 / 归档 / 自定义外观;工作区分组行——重命名分组(同步更新组内所有工作区名称)/ 自定义外观;会话与会话分组行——重命名 / 分叉 / 归档 / 自定义外观。</td>
59
59
  </tr>
60
60
  </table>
61
61
 
@@ -69,10 +69,10 @@ web/ ← 虚拟分组(不是真实目录,纯命名层级)
69
69
  ### 其余亮点
70
70
 
71
71
  - **文件夹式收起**:点工作区行 = 收起/展开该工作区的全部会话(收起后行上保留会话数角标);会话分组同样可收起;搜索时自动全部展开。
72
- - **拖拽还原原版能力**:工作区行可拖拽——拖到另一工作区行上/下半即调整顺序(写回宿主 registry 序),拖到分组行则移动进该分组;会话行可拖拽——同工作区拖到另一会话上/下调整顺序,拖到会话子分组即移动进该分组。显示顺序 = 宿主手动序,拖拽结果立即生效。拖拽工作区期间,单链合并显示的行(如 工作/A)临时展开回文件夹树——路径里的每一级都是可投放的分组行,松手后自动合并回去。
72
+ - **拖拽还原原版能力**:工作区行可拖拽——拖到另一工作区行上/下半即调整顺序(写回宿主 registry 序),拖到分组行则移动进该分组(改写名称前缀);会话行可拖拽——同工作区拖到另一会话上/下调整顺序,拖到会话子分组即移动进该分组。显示顺序 = 宿主手动序,拖拽结果立即生效。**磁盘层是文件系统事实,不随拖拽改变**:跨磁盘层的放置只重组名称分组(工作区落回自身磁盘层的末尾),同层放置才走锚点序。拖拽工作区期间,单链合并显示的行(如 工作/A)临时展开回文件夹树——路径里的每一级都是可投放的分组行,松手后自动合并回去。
73
73
  - **不丢原生能力**:会话行(打开/重命名/分叉/归档)、每工作区「新会话」(点 + 总是先展开该工作区,让新会话立刻可见)、当前会话高亮、官方状态灯(蓝色运行环 / 琥珀待交互 / 绿色完成提醒)、**状态呼吸灯**(折叠藏起的状态灯向外冒泡:工作区/分组行图标按状态色呼吸发光——琥珀待交互/绿完成,自定义过发光的标题一起呼吸;运行中只在会话行本层蓝色呼吸,不外渗;可在设置关闭)、**活跃定时任务角标**(有活动 Schedule 的会话显示闹钟图标,与官方行一致)、未分组会话兜底、界面文案跟随 DSH 的语言设置(内置 21 种语言,含简繁中文)。
74
74
  - **URL/斜杠标题不拆层**:宿主自动生成的会话标题落地时若含 `/`(如复述了 URL),整串自动包上 `“”` 原样显示,绝不解析成层级——只对本次启动后**新建的会话**生效,并等命名稳定(约 20 秒,让原生 AI 命名先落地)才处理;存量会话与你手动命名的 `/` 分组标题永不被改动。引号内(含手动添加)的 `/` 永不切分,孤立引号只当普通字符;无引号但含 URL 的旧标题也有平铺兜底。
75
- - **对话空态页同样生效**:会话空态页的「添加工作区」菜单走的也是本插件的拾取交互,同样带所属分组弹窗。
75
+ - **对话空态页同样生效**:会话空态页的「添加工作区」菜单同样回归官方目录流(原生选择器 / 官方应用内浏览器)。
76
76
 
77
77
  ## 安装
78
78
 
@@ -100,9 +100,9 @@ dsh plugin --profile web add dsh-better-workspace # npm 公开包
100
100
 
101
101
  DSH 的侧边栏浏览区是一个公开插槽 `sidebar.workspaces`(single),官方工作区浏览器是它的占用者;本插件以更低优先级注册同一插槽,**整区替换**为层级树版本。数据全部来自插槽标准注入(`useWorkspaces` / `useSessions` 快照钩子),动作(打开会话、重命名/删除工作区、归档等)也走注入的宿主动作——不碰任何私有 API。
102
102
 
103
- 「添加工作区」则落在 dsh 专门为第三方设计的一条缝里:`sidebar.workspaces.directoryFlow` `conversation.hero.workspace.directoryFlow` 两个目录流插槽。触发按钮、忙碌语义、错误弹窗全由官方持有;本插件只拥有「触发之后、交付路径之前」的交互——正好用来塞进「选完文件夹 弹窗选分组 创建 改名加前缀」这条链。
103
+ 「添加工作区」完全交给官方:本插件为 `sidebar.workspaces` 注册**声明** directoryFlow 子洞并经 `renderSlot` 消费(官方 WorkspaceBrowser 同款 children 模式),官方组合占用者(原生选择器 / 应用内浏览器)承载全部拾取交互;本插件作为 owner 只负责选完目录后的创建与新会话。该机制 0.1.2+ 宿主即可用,升级先后都收敛。
104
104
 
105
- 视图状态(分组折叠、会话展开、显式空分组)、外观自定义与插件设置都通过 dsh 客户端 store 持久化在浏览器本地(`dsh.betterWorkspace.view.v1`)。注意:该 store 的 hydration 是整值替换、不合并默认值——升级后如果遇到状态字段缺失,重启前的旧状态按旧结构保留,缺的键自动回退默认。
105
+ 视图状态(分组折叠、会话展开)、外观自定义与插件设置都通过 dsh 客户端 store 持久化在浏览器本地(`dsh.betterWorkspace.view.v1`)。注意:该 store 的 hydration 是整值替换、不合并默认值——升级后如果遇到状态字段缺失,重启前的旧状态按旧结构保留,缺的键自动回退默认。
106
106
 
107
107
  ## 与 dsh-better-sidebar 的关系
108
108
 
@@ -111,13 +111,13 @@ DSH 的侧边栏浏览区是一个公开插槽 `sidebar.workspaces`(single),官
111
111
  ## 版本兼容
112
112
 
113
113
  - **dsh 0.1.6-alpha.1**:图标集与浏览器注入面都变了,本插件 **0.10.2 起自动适配**——图标网格只列本宿主真正导出的字形(退役的 `IconSendOutline16` 自动落到等价的 `IconSendOutline14`,已保存的旧选择不会变成空图标位),会话拖拽排序在宿主不再注入 `insertSessionBefore` 时改用浏览器本地顺序,**功能不丢**。升级 dsh 与升级插件谁先谁后都收敛。
114
- - **跨端**:web 与桌面共用同一套客户端资产;外观 / 分组 / 开关可经设置卡片手动跨端同步,**折叠状态与会话本地序每端本地**(设计如此)。
114
+ - **dsh 0.1.6-alpha.2**:设置页重组——本插件 **0.12.0 起双座位**注册设置卡片(旧宿主的 设置→插件 卡片 + 新宿主 插件面板 bundle 页,按包名挂载);工作区树新增**磁盘目录嵌套层**(官方 workspace-tree 语义),添加工作区回归官方目录流(原生选择器 / 官方应用内浏览器)
115
+ - **跨端**:web 与桌面共用同一套客户端资产;外观 / 开关可经设置卡片手动跨端同步,**折叠状态与会话本地序每端本地**(设计如此)。
115
116
 
116
117
  ## 限制与路线图
117
118
 
118
119
  - 会话拖到**另一分组内的会话行**仅做扁平重排(标题分组归属不变);要改分组请拖到分组行或走重命名。
119
- - 搜索为本地标题过滤;宿主内容搜索(`session.search`)计划接回。
120
- - 空分组持久在浏览器本地,不同浏览器/设备不共享(路线图:宿主侧分组登记 + 设置页)。
120
+ - 搜索为本地标题过滤(两层扁平化后逐工作区匹配);宿主内容搜索(`session.search`)计划接回。
121
121
  - flat(平铺)视图未接管,层级树即视图。
122
122
 
123
123
  ## 开发
package/README_EN.md CHANGED
@@ -4,12 +4,14 @@
4
4
 
5
5
  [简体中文](README.md) | English
6
6
 
7
- > A **folder system** for the DeepSeek Harness (DSH) sidebar workspace list — a workspace is still one directory, but every `/` in its name becomes hierarchy, so `web/frontend` and `web/backend` group under one virtual `web` folder.
7
+ > A **two-layer folder system** for the DeepSeek Harness (DSH) sidebar workspace list — a **disk layer** nests workspaces by their directory paths (the official workspace-tree semantics: a workspace inside another workspace's directory nests under it), and a **name layer** eats every `/` in workspace titles (`web/frontend` and `web/backend` under one virtual `web` folder). The two layers combine orthogonally.
8
8
 
9
9
  ```
10
- web/ <- virtual folder (naming only, not a real directory)
11
- |- frontend <- workspace "web/frontend"
12
- `- backend <- workspace "web/backend"
10
+ disk layer (paths, automatic) name layer (titles, virtual)
11
+ ~/projects/ web/
12
+ |- web/ <- workspace (dir) |- frontend <- workspace "web/frontend"
13
+ | `- api/ <- nested workspace `- backend <- workspace "web/backend"
14
+ `- docs/ <- sibling workspace
13
15
  ```
14
16
 
15
17
  ## Features & preview
@@ -21,15 +23,15 @@ web/ <- virtual folder (naming only, not a real directory)
21
23
  </tr>
22
24
  </table>
23
25
 
24
- ### Add flow: pick a folder, then pick a group
26
+ ### Add workspace: the official directory flow
25
27
 
26
- After you pick a directory for a new workspace, a small dialog asks for the parent group type one (`web`), pick an existing level from the datalist, or leave it empty for the root. The plugin creates the workspace and writes the prefix into its title, so it lands on the right branch of the tree.
28
+ "Add workspace" runs the **official DSH picking flow** (since v0.12.0): a loopback-only webserver bind with a display session opens the host's **native OS chooser**; an all-interfaces/LAN bind, an SSH launch, or a headless host switches to the official **in-app directory browser** (Miller columns, root-anchored breadcrumbs, editable path, inline new-folder row, hidden-file toggle) the exact scenario this plugin's hand-rolled browser polished until the official one landed. Picking a directory creates the workspace and starts a new session in it, exactly like the shipped browser; the conversation empty-state "Add workspace" returns to the official flow too.
27
29
 
28
- **Which picker you get follows the backend the host actually composes.** A loopback-only webserver bind gives you the host's **native OS chooser**; an all-interfaces/LAN bind, an SSH launch, or a host without a usable display session composes the `browse` backend instead — listing and directory creation only, with `pick` refused by design — and the plugin then uses an **in-app directory browser** (Home-rooted breadcrumbs, editable path, inline new-folder row, hidden-file toggle) before the very same parent-group dialog. Forcing the native chooser under such a bind means pinning the host's native backend package yourself, and that dialog opens on the **server's** desktop, out of reach for LAN clients.
30
+ Grouping happens by naming, not by a popup: rename the workspace after creation (every `/` in the title is a group) or drag it onto a folder row.
29
31
 
30
- ### Folder create/delete via context menu
32
+ ### Groups: a projection of names
31
33
 
32
- Right-click any folder row: new subfolder (parent prefix pre-filled), new workspace here (the add-flow group field pre-fills with this folder), rename folder, delete empty folder no standalone header button anymore. Explicit empty folders persist in the browser until workspaces live inside them.
34
+ Name groups derive from the `/` segments of workspace titles there is no second source of truth to keep in sync. Right-click a folder row to **rename the group** (rewrites the title prefix of every member); the tree re-flows instantly. The root level holds workspaces without a `/`.
33
35
 
34
36
  ### Sessions follow the same rule
35
37
 
@@ -37,7 +39,7 @@ Session titles nest on `/` too (e.g. `test1/plugin maintenance`). Session groups
37
39
 
38
40
  **No title regression after a restart**: the cold list right after a DSH restart only carries titles for sessions that hit the persisted projection cache — fork-born and never-checkpointed sessions temporarily fall back to the workspace *basename*, even though the real title still lives in the session log. This plugin remembers each session's **last real wire title** in the browser (a debounced local cache: real changes coalesce into one write) and renders from memory during that window, so `/` grouping keeps working; the moment a session opens, the official data takes over and self-heals.
39
41
 
40
- **Manual cross-device sync (web ↔ desktop app)**: appearance, the default appearance, explicit folders, and toggles live in each device's own browser by default. The settings card adds a "Cross-device sync" section — "Pull from desktop app" on the web / "Pull from web" in the desktop app, with an **overwrite-this-device** or **merge-both-sides** mode (the union keeps each side's unique entries); the other surface's data travels through the host settings store (~/.dsh/settings.yaml, shared by both surfaces). A "Send this device's data" button next to it covers history created before this version — push once, and afterwards every edit is written to the host automatically for the other surface to pull. Expansion state stays per-device.
42
+ **Manual cross-device sync (web ↔ desktop app)**: appearance, the default appearance, and toggles live in each device's own browser by default. The settings card adds a "Cross-device sync" section — "Pull from desktop app" on the web / "Pull from web" in the desktop app, with an **overwrite-this-device** or **merge-both-sides** mode (the union keeps each side's unique entries); the other surface's data travels through the host settings store (~/.dsh/settings.yaml, shared by both surfaces). A "Send this device's data" button next to it covers history created before this version — push once, and afterwards every edit is written to the host automatically for the other surface to pull. Expansion state stays per-device.
41
43
 
42
44
  <table>
43
45
  <tr>
@@ -53,7 +55,7 @@ Session titles nest on `/` too (e.g. `test1/plugin maintenance`). Session groups
53
55
  <table>
54
56
  <tr>
55
57
  <td align="center" width="58%"><img src="docs/screenshots/5-context-menu.png" alt="Context menu"/></td>
56
- <td valign="top"><b>Context menu everywhere</b><br/>Actions live in the right-click menu: workspace rows — rename / delete / fork / archive / customize; folder rows — new subfolder / new workspace here / rename group (updates all descendant workspaces) / delete empty group / customize; session &amp; session-group rows — rename / fork / archive / customize.</td>
58
+ <td valign="top"><b>Context menu everywhere</b><br/>Actions live in the right-click menu: workspace rows — rename / delete / fork / archive / customize; folder rows — rename group (updates all descendant workspaces) / customize; session &amp; session-group rows — rename / fork / archive / customize.</td>
57
59
  </tr>
58
60
  </table>
59
61
 
@@ -67,10 +69,10 @@ Session titles nest on `/` too (e.g. `test1/plugin maintenance`). Session groups
67
69
  ### More highlights
68
70
 
69
71
  - **Folder-style collapse**: clicking a workspace row collapses/expands all of its sessions (the row keeps a session counter when collapsed); session groups collapse too; search force-expands everything.
70
- - **Native drag restored**: drag a workspace row above/below another to reorder (writes back the host registry order) or onto a folder row to move it into that group; drag session rows to reorder within the same workspace or onto a session group to move. Display order = host manual order, drag results are visible immediately. While dragging a workspace, merged single-chain rows (e.g. work/A) temporarily re-expand into folder rows — every level of the path becomes a drop target, and chains merge back when the drag ends.
72
+ - **Native drag restored**: drag a workspace row above/below another to reorder (writes back the host registry order) or onto a folder row to move it into that group (rewrites the title prefix); drag session rows to reorder within the same workspace or onto a session group to move. Display order = host manual order, drag results are visible immediately. **The disk layer is a filesystem fact and never changes through dragging**: a cross-level drop only re-groups the name prefix (the workspace lands at the end of its own disk level), same-level drops take the anchor order. While dragging a workspace, merged single-chain rows (e.g. work/A) temporarily re-expand into folder rows — every level of the path becomes a drop target, and chains merge back when the drag ends.
71
73
  - **Native capabilities kept**: open/rename/fork/archive sessions, per-workspace new-session (the + button always expands the workspace first so the new session is immediately visible), current-session highlight, official status dots (blue running ring / amber pending / green done), **status breathing lights** (dots hidden by collapse bubble outward: workspace/folder rows breathe on their icon in the status color — amber pending / green done, custom-glow labels breathe along; running breathes blue only on the session row itself and never relays; off-able in settings), **active-schedule badge** (alarm clock icon for sessions with active Schedule records, matching the official rows), ungrouped-session fallback, UI copy in 21 languages following the DSH language preference (Simplified and Traditional Chinese included).
72
74
  - **Slash-bearing titles never nest from URLs**: when a host-generated session title lands containing `/` (e.g. echoing a pasted URL), it is auto-wrapped in `“”` and shown verbatim — only for sessions **created after this launch**, and only once the name stays stable for ~20s (letting the native AI naming land first); pre-existing sessions and your manually named `/` groupings are never touched. Quotes (manual ones too) never split on `/`, and a lone quote is just an ordinary character; unquoted URL tails still fall back flat.
73
- - **Conversation hero too**: the empty-state “Add workspace” menu uses the same picking interaction with the same group popup.
75
+ - **Conversation hero too**: the empty-state “Add workspace” menu returns to the official directory flow (native chooser / official in-app browser).
74
76
 
75
77
  ## Install
76
78
 
@@ -84,9 +86,9 @@ Plain JavaScript, zero build, zero npm dependencies (dsh client baseline modules
84
86
 
85
87
  The sidebar browsing region is the public `sidebar.workspaces` slot; this plugin registers the same slot with a lower priority and replaces the shipped browser with the tree. All data flows through the slot’s standard snapshot hooks and injected host actions — no private APIs.
86
88
 
87
- The add flow lands in the seam dsh designed for third parties: the two `directoryFlow` holes. The trigger, busy semantics, and error dialog stay official; this plugin owns everything between the trigger and the adopted path exactly enough room for pick group popup create prefixed rename.
89
+ The add flow is entirely official: this plugin's `sidebar.workspaces` registration **declares** the directory-flow child hole and consumes it through `renderSlot` (the same children pattern the official WorkspaceBrowser uses); the official composed occupant (native chooser / in-app browser) owns the whole picking interaction. This plugin, as the owner, just creates the workspace and starts a session after the pick. The mechanism works on dsh 0.1.2+ hosts — either upgrade order converges.
88
90
 
89
- View state (folder collapse, session expansion, explicit empty folders), custom styling and plugin settings persist browser-side via the dsh client store (`dsh.betterWorkspace.view.v1`).
91
+ View state (folder collapse, session expansion), custom styling and plugin settings persist browser-side via the dsh client store (`dsh.betterWorkspace.view.v1`).
90
92
 
91
93
  ## Relationship to dsh-better-sidebar
92
94
 
@@ -95,13 +97,13 @@ Same `dsh-better-*` family, zero overlap: [dsh-better-sidebar](https://github.co
95
97
  ## Version compatibility
96
98
 
97
99
  - **dsh 0.1.6-alpha.1**: both the primitives icon set and the browser injection face changed; this plugin **adapts automatically since 0.10.2**. The icon grid only lists glyphs this host actually exports (the retired `IconSendOutline16` resolves to the equivalent `IconSendOutline14`, so a previously saved choice never turns into an empty icon slot), and session drag-to-reorder falls back to a browser-local order when the host no longer injects `insertSessionBefore` — **no feature is lost**. Either upgrade order (plugin first or dsh first) converges.
98
- - **Across surfaces**: web and desktop share one set of client assets; appearance / groups / switches sync manually through the settings card, while **collapse state and the local session order stay per-browser** by design.
100
+ - **dsh 0.1.6-alpha.2**: the settings pages were reworked since **0.12.0** this plugin registers its settings card on **both seats** (the pre-alpha.2 Settings → Plugins card and the alpha.2+ Plugins panel's bundle page, keyed by package name); the tree gains the **disk-nesting layer** (official workspace-tree semantics) and add-workspace rides the official directory flow (native chooser / official in-app browser).
101
+ - **Across surfaces**: web and desktop share one set of client assets; appearance / switches sync manually through the settings card, while **collapse state and the local session order stay per-browser** by design.
99
102
 
100
103
  ## Limitations / roadmap
101
104
 
102
105
  - A session dragged onto a session row **inside another group** only gets reordered in the flat list (its title group stays); drag onto the group row or rename to move it.
103
- - Search is local title filtering; host content search (`session.search`) is planned.
104
- - Explicit empty folders persist per-browser (roadmap: host-side folder registry + settings page).
106
+ - Search is local title filtering (both layers flattened, per-workspace matching); host content search (`session.search`) is planned.
105
107
  - The flat view is not taken over; the hierarchical tree is the view.
106
108
 
107
109
  ## Develop
package/dsh.plugin.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "id": "dsh-external/dsh-better-workspace",
3
- "version": "0.11.5",
3
+ "version": "0.12.0",
4
4
  "main": "./src/index.js",
5
- "description": "侧边栏工作区层级树:名称中的 / 即虚拟分组(web/前端 · web/后端),添加工作区的目录流附所属分组弹窗,重命名即时重排层级,可新建空分组。Hierarchy tree for the DSH sidebar workspace list.",
5
+ "description": "侧边栏工作区两层层级树:工作区按磁盘目录嵌套(官方 workspace-tree 语义),名称中的 / 即虚拟分组(web/前端 · web/后端);添加工作区由官方目录流承载。Two-layer hierarchy tree for the DSH sidebar workspace list.",
6
6
  "engines": {
7
7
  "dsh": ">=0.0.1"
8
8
  },
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dsh-better-workspace",
3
- "version": "0.11.5",
4
- "description": "DSH web plugin: a hierarchical workspace tree for the sidebar. Workspace titles containing \"/\" group into virtual folders (web/前端 · web/后端); the add-workspace directory flow gains a parent-group popup; renames re-derive the tree; a new-folder button creates empty levels.",
3
+ "version": "0.12.0",
4
+ "description": "侧边栏工作区两层层级树:磁盘目录嵌套(官方 workspace-tree 语义)+ 名称 / 虚拟分组,添加工作区走官方目录流。Two-layer workspace tree for the DSH sidebar: disk-path nesting plus \"/\"-name groups; add-workspace rides the official directory flow.",
5
5
  "type": "module",
6
6
  "repository": {
7
7
  "type": "git",