dsh-sidebar-row-menu 1.8.0 → 1.9.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/CHANGELOG.md CHANGED
@@ -1,7 +1,65 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.9.0 — 2026-11-06
4
+
5
+ ### 中文摘要
6
+
7
+ - **新增「会话正文右键菜单」**:在会话正文里(空白处、思考过程、回复和工具摘要,输入框、
8
+ 工具条和工具卡片本身以外)右键,会按顶部工具条的**视觉顺序**从左到右列出那排按钮,
9
+ 每项带原按钮的图标;「更多操作」一类的溢出入口默认固定在最后一项。装了
10
+ `dsh-sidebar-organizer` 且调整过「会话头部工具条」时,顺序跟随它的配置;没装时就是
11
+ DSH 的默认顺序。organizer 用 CSS `order` 排序,DOM 顺序不代表屏幕顺序,所以菜单按
12
+ `getBoundingClientRect()` 现算。点普通条目等于点原按钮:先关菜单再派发 `click`,
13
+ 宿主弹层仍锚在原按钮上;「更多操作」则不再打开右上角的「…」,而是像「打开方式」
14
+ 一样在本菜单里展开二级菜单,直接复刻宿主菜单的条目并执行,行序同样跟随
15
+ `dsh-sidebar-organizer`(它在「…」弹层里拖动后保存的 host-menu-order)。有选中
16
+ 文字时让位给浏览器的选区菜单,消息里的输入控件和链接也保留原生菜单;工具卡片、
17
+ 输入框、工具条本身和侧栏行同样保留各自的原生右键菜单;找不到可用按钮时不接管
18
+ 原生菜单。设置 →「行菜单」
19
+ 里可以关闭整个菜单,或取消「更多」固定最后。
20
+ - **空白菜单里的「打开方式」按工作区 / 会话右键的方式收纳**:置顶应用显示为一级行,
21
+ 其余应用收进「打开方式」二级菜单(悬浮或点击展开),设置里的总开关、逐应用开关和
22
+ 置顶全部生效;同时菜单的分组之间自动加淡色分隔线,行高、内边距、圆角、字号和图标
23
+ 尺寸都与 DSH 原生右键菜单对齐。
24
+
25
+ ### Added
26
+
27
+ - **Right-click menu in the conversation body.** Right-clicking in the conversation
28
+ body — blank space, thinking blocks, replies and tool summaries, but not the
29
+ composer, the header toolbar or tool cards themselves — now opens a vertical menu
30
+ that lists that toolbar in visual left-to-right order, each row reusing the
31
+ original button's icon; a "More actions" style overflow trigger is pinned to the
32
+ last row by default. With `dsh-sidebar-organizer` installed and a customised
33
+ "session header toolbar" layout the order follows the organizer; otherwise it is
34
+ DSH's default order. The organizer reorders with CSS `order`, so DOM order is not
35
+ screen order — the menu sorts by `getBoundingClientRect()` at right-click time.
36
+ Selecting an ordinary row closes the menu and dispatches a real `click` to the
37
+ original header button, so host popovers stay anchored to their trigger.
38
+ "More actions" no longer opens the header "…" popover: it expands in place like
39
+ the other submenus, mirrors the host menu's entries and runs the selected one;
40
+ its row order follows `dsh-sidebar-organizer`'s saved host-menu order as well.
41
+ A text selection wins and receives the browser's selection menu; inputs and links
42
+ inside messages also keep their native menu, as do tool cards, the composer, the
43
+ toolbar itself and sidebar rows. No usable button means the native menu is left
44
+ alone. The menu and the pin-More-last behaviour can both be switched off under
45
+ Settings → row menu.
46
+ - **"Open with" inside the blank-space menu is collapsed like the workspace and
47
+ session menus.** Pinned apps render as top-level rows and the remaining apps move
48
+ into an "Open with" submenu that expands on hover or click; the master switch,
49
+ per-app switches and pinning all apply. Sections are now separated by faint rules
50
+ automatically, and row height, padding, radius, type size and icon size match
51
+ DSH's native context menus.
52
+
3
53
  ## 1.8.0 — 2026-11-05
4
54
 
55
+ ### 中文摘要
56
+
57
+ - **DSH 0.2.2 起,设置页改用本插件自己的导航图标。** 设置分区现在通过宿主的
58
+ `settings.section.icon` slot 注册导航图标,不再退回默认的齿轮。图标造型是「三行
59
+ 条目 + 行尾子菜单箭头」,沿用宿主自绘图标的规范:16px 网格、1.5 描边、圆头,
60
+ 颜色取 `currentColor`,选中与未选中状态自动跟随。0.2.1 及更早的宿主没有这个
61
+ slot,注册会被跳过,设置页照常注册并保留宿主自己的图标。
62
+
5
63
  ### Added
6
64
 
7
65
  - **Custom settings icon on DSH 0.2.2 and later.** The settings section now
@@ -14,6 +72,16 @@
14
72
 
15
73
  ## 1.7.0 — 2026-11-05
16
74
 
75
+ ### 中文摘要
76
+
77
+ - **工作区菜单可以按工作区显示 / 隐藏已归档会话**:某个工作区的分组里存在已归档
78
+ 会话时,它的右键菜单(以及开启后的行尾「…」菜单)会出现「显示已归档会话」/
79
+ 「隐藏已归档会话」,沿用原生「查看」选项里的归档图标。DSH 只提供一套全局归档
80
+ 过滤,插件把它切到「全部会话」,并隐藏其他工作区(含「未分组」)的已归档行,
81
+ 这样每个工作区都能独立展开自己的归档;选择跨刷新保留,宿主全局过滤一旦被改动
82
+ 就清掉该状态,让原生的全局选择保持权威。该条目可在 设置 → 行菜单 里关掉,且只在
83
+ 工作区确实有已归档会话时出现。
84
+
17
85
  ### Added
18
86
 
19
87
  - **Per-workspace archived-session toggle in the workspace menu.** A workspace
@@ -30,6 +98,26 @@
30
98
 
31
99
  ## 1.6.0 — 2026-11-05
32
100
 
101
+ ### 中文摘要
102
+
103
+ - **0.2.2 上工作区条目默认只出现在右键菜单**:工作区 provider 解析时检查同一枚
104
+ 右键手势标记,行尾「…」的 `pointerdown` 会先清标,所以「…」菜单保持原生内容。
105
+ - **工作区行可以在设置里「同时放进「…」菜单」**:逐项开启后 provider 跳过手势判断,
106
+ 对应条目也会进入宿主的「…」菜单;0.2.2 上这组开关不再隐藏,说明文字改成描述
107
+ 共用菜单 + 手势区分的真实行为。0.2.1 仍由插件接管「…」按钮自绘。
108
+ - **0.2.2 的「打开方式」恢复图标**:数据贡献的条目本身没有图标,现在注册
109
+ `contextMenu.icon`(`sidebar-row-menu.open-with`)并由动作引用,与 0.2.1 自绘
110
+ 菜单一致。
111
+ - **125%–150% 缩放下菜单分隔线可见**:宿主用的是 0.5px 细线,在分数像素比下会被
112
+ 摊成约 0.4px 而像「消失」;现在该区间内分隔线(含 0.2.1 的 `.dsrm-sep`)补到
113
+ 1px,1x 与 2x 显示不变。
114
+ - **工作区菜单改用会话菜单的分组规则**:原来「打开方式」组夹在复制路径之前,分隔线
115
+ 落点与会话菜单不一致;现在顺序为行内动作 → 复制路径/在文件夹显示 → 打开方式组 →
116
+ 删除,两份菜单都分成同样三块。
117
+ - **「打开方式」恢复子菜单箭头**:宿主不给子菜单父项画箭头,但 label 是当元素渲染的,
118
+ 所以工作区条目改成「文字 + 右对齐箭头」的 label,与会话菜单的箭头位置一致(不再是
119
+ 贴在文字后面的「›」);0.2.1 自绘菜单仍用自己的箭头图标。
120
+
33
121
  ### Added
34
122
 
35
123
  - **Workspace entries can opt into the native "…" menu on DSH 0.2.2.** The
@@ -71,27 +159,20 @@
71
159
  individual entries into that shared menu. This reverses the 1.5.0 decision to hide
72
160
  the group.
73
161
 
74
- ### 中文摘要
162
+ ## 1.5.1 — 2026-11-05
75
163
 
76
- - **0.2.2 上工作区条目默认只出现在右键菜单**:工作区 provider 解析时检查同一枚
77
- 右键手势标记,行尾「…」的 `pointerdown` 会先清标,所以「…」菜单保持原生内容。
78
- - **工作区行可以在设置里「同时放进「…」菜单」**:逐项开启后 provider 跳过手势判断,
79
- 对应条目也会进入宿主的「…」菜单;0.2.2 上这组开关不再隐藏,说明文字改成描述
80
- 共用菜单 + 手势区分的真实行为。0.2.1 仍由插件接管「…」按钮自绘。
81
- - **0.2.2 的「打开方式」恢复图标**:数据贡献的条目本身没有图标,现在注册
82
- `contextMenu.icon`(`sidebar-row-menu.open-with`)并由动作引用,与 0.2.1 自绘
83
- 菜单一致。
84
- - **125%–150% 缩放下菜单分隔线可见**:宿主用的是 0.5px 细线,在分数像素比下会被
85
- 摊成约 0.4px 而像「消失」;现在该区间内分隔线(含 0.2.1 的 `.dsrm-sep`)补到
86
- 1px,1x 与 2x 显示不变。
87
- - **工作区菜单改用会话菜单的分组规则**:原来「打开方式」组夹在复制路径之前,分隔线
88
- 落点与会话菜单不一致;现在顺序为行内动作 → 复制路径/在文件夹显示 → 打开方式组 →
89
- 删除,两份菜单都分成同样三块。
90
- - **「打开方式」恢复子菜单箭头**:宿主不给子菜单父项画箭头,但 label 是当元素渲染的,
91
- 所以工作区条目改成「文字 + 右对齐箭头」的 label,与会话菜单的箭头位置一致(不再是
92
- 贴在文字后面的「›」);0.2.1 自绘菜单仍用自己的箭头图标。
164
+ ### 中文摘要
93
165
 
94
- ## 1.5.1 — 2026-11-05
166
+ - **修复 0.2.2 上会话行右键菜单「有时没有插件条目」**:条目原来用 `contextmenu`
167
+ 之后 400 ms 的时间窗口判断,而 0.2.2 的菜单是异步挂载的,替换已有菜单时还会
168
+ 先卸载旧面板再挂新面板,这次卸载会把窗口清掉,于是下一次菜单可能不带插件条目。
169
+ 改为「右键手势标记」:只有菜单面板真正挂载后才收尾,右键稳定带条目,行尾「…」
170
+ 打开的菜单仍然保持原生内容。
171
+ 0.2.2 上也不再拦截 `contextmenu` 后转成「…」点击:行本身已带宿主触发器,直接
172
+ 由宿主把菜单开在指针处(不改锚点、不补发点击)。
173
+ - **文档与市场文案改为描述 0.2.2 的真实行为**:README(中英)、npm 描述与市场条目
174
+ 不再写成「插件自绘侧栏菜单」,而是说明 0.2.2 由宿主渲染菜单、插件按 `order` 贡献
175
+ 条目(工作区项混排、会话行扩展宿主开在指针处的菜单),0.2.1 上保留自绘工作区菜单。
95
176
 
96
177
  ### Fixed
97
178
 
@@ -116,20 +197,18 @@
116
197
  extended in the host menu opened at the pointer), and that 0.2.1 keeps the
117
198
  self-drawn workspace menu.
118
199
 
119
- ### 中文摘要
200
+ ## 1.5.0 — 2026-11-05
120
201
 
121
- - **修复 0.2.2 上会话行右键菜单「有时没有插件条目」**:条目原来用 `contextmenu`
122
- 之后 400 ms 的时间窗口判断,而 0.2.2 的菜单是异步挂载的,替换已有菜单时还会
123
- 先卸载旧面板再挂新面板,这次卸载会把窗口清掉,于是下一次菜单可能不带插件条目。
124
- 改为「右键手势标记」:只有菜单面板真正挂载后才收尾,右键稳定带条目,行尾「…」
125
- 打开的菜单仍然保持原生内容。
126
- 0.2.2 上也不再拦截 `contextmenu` 后转成「…」点击:行本身已带宿主触发器,直接
127
- 由宿主把菜单开在指针处(不改锚点、不补发点击)。
128
- - **文档与市场文案改为描述 0.2.2 的真实行为**:README(中英)、npm 描述与市场条目
129
- 不再写成「插件自绘侧栏菜单」,而是说明 0.2.2 由宿主渲染菜单、插件按 `order` 贡献
130
- 条目(工作区项混排、会话行扩展宿主开在指针处的菜单),0.2.1 上保留自绘工作区菜单。
202
+ ### 中文摘要
131
203
 
132
- ## 1.5.0 — 2026-11-05
204
+ - **支持 DSH 0.2.2 的原生右键菜单**:宿主提供 `ctx.contextMenus` 时,工作区行条目改为
205
+ 数据贡献注册,按 order 与原生项交错排列(新会话 90、置顶应用 150、打开方式 180、
206
+ 复制工作区路径 250、在新标签打开 260、删除工作区及所有会话 310;原生为重命名 100、
207
+ 在文件夹显示 200、删除工作区 300)。右键与行尾「…」共用宿主同一份菜单。0.2.1 上仍
208
+ 走自绘工作区菜单;会话行条目继续通过 `sidebar.workspaces.session.menu.item` 扩展点渲染。
209
+ - 修复未命名会话「永久删除」确认框显示空标题的问题,回退为「未命名会话」。
210
+ - 0.2.2 的设置页隐藏工作区行「同时放进「…」菜单」开关(该版本右键与「…」共用同一份
211
+ 菜单,开关无从生效);会话行的同类开关保留且仍然有效。
133
212
 
134
213
  ### Added
135
214
 
@@ -152,18 +231,12 @@
152
231
  so those per-entry toggles could never take effect there. The session-row switches
153
232
  still work and stay visible.
154
233
 
155
- ### 中文摘要
234
+ ## 1.4.3 — 2026-11-04
156
235
 
157
- - **支持 DSH 0.2.2 的原生右键菜单**:宿主提供 `ctx.contextMenus` 时,工作区行条目改为
158
- 数据贡献注册,按 order 与原生项交错排列(新会话 90、置顶应用 150、打开方式 180、
159
- 复制工作区路径 250、在新标签打开 260、删除工作区及所有会话 310;原生为重命名 100、
160
- 在文件夹显示 200、删除工作区 300)。右键与行尾「…」共用宿主同一份菜单。0.2.1 上仍
161
- 走自绘工作区菜单;会话行条目继续通过 `sidebar.workspaces.session.menu.item` 扩展点渲染。
162
- - 修复未命名会话「永久删除」确认框显示空标题的问题,回退为「未命名会话」。
163
- - 0.2.2 的设置页隐藏工作区行「同时放进「…」菜单」开关(该版本右键与「…」共用同一份
164
- 菜单,开关无从生效);会话行的同类开关保留且仍然有效。
236
+ ### 中文摘要
165
237
 
166
- ## 1.4.3 — 2026-11-04
238
+ - 在 `package.json` 中声明 `engines.dsh: ">=0.2.1-rc.5 <0.3.0-0"`:范围外的 DSH 会拒绝
239
+ 安装/激活,插件市场会显示支持版本,不再当作“未声明”。运行代码无改动。
167
240
 
168
241
  ### Changed
169
242
 
@@ -172,12 +245,16 @@
172
245
  plugin on a host outside that range, and the plugin market lists the range on the
173
246
  card instead of treating the plugin as undeclared. No runtime code changed.
174
247
 
175
- ### 中文摘要
248
+ ## 1.4.2 — 2026-11-03
176
249
 
177
- - 在 `package.json` 中声明 `engines.dsh: ">=0.2.1-rc.5 <0.3.0-0"`:范围外的 DSH 会拒绝
178
- 安装/激活,插件市场会显示支持版本,不再当作“未声明”。运行代码无改动。
250
+ ### 中文摘要
179
251
 
180
- ## 1.4.2 — 2026-11-03
252
+ - 工作区右键新增「删除工作区及所有会话」:先逐个永久删除会话日志,全部成功后再删除
253
+ 工作区登记;任一会话失败则保留工作区便于重试。内置「删除工作区」行为不变(会话归入
254
+ 「未分组」)。新增宿主路由 `POST /dsh-sidebar-row-menu/workspace/delete`。
255
+ - 设置 →「行菜单」新增「同时放进「…」菜单」:可逐项把插件右键条目加进行尾「…」菜单。
256
+ 会话条目走原生 slot;工作区开启任意一项后由插件接管「…」按钮,保留官方「重命名 /
257
+ 删除工作区」。全部默认关闭,未开启时「…」菜单与 DSH 原样一致。
181
258
 
182
259
  ### Added
183
260
 
@@ -194,16 +271,13 @@
194
271
  Rename / Delete workspace items plus the enabled entries. All switches are off by
195
272
  default, so the native menu is untouched until opted in.
196
273
 
197
- ### 中文摘要
274
+ ## 1.4.1 — 2026-11-03
198
275
 
199
- - 工作区右键新增「删除工作区及所有会话」:先逐个永久删除会话日志,全部成功后再删除
200
- 工作区登记;任一会话失败则保留工作区便于重试。内置「删除工作区」行为不变(会话归入
201
- 「未分组」)。新增宿主路由 `POST /dsh-sidebar-row-menu/workspace/delete`。
202
- - 设置 →「行菜单」新增「同时放进「…」菜单」:可逐项把插件右键条目加进行尾「…」菜单。
203
- 会话条目走原生 slot;工作区开启任意一项后由插件接管「…」按钮,保留官方「重命名 /
204
- 删除工作区」。全部默认关闭,未开启时「…」菜单与 DSH 原样一致。
276
+ ### 中文摘要
205
277
 
206
- ## 1.4.1 — 2026-11-03
278
+ - 设置 →「行菜单」新增「允许删除未归档会话」开关(默认关闭)。开启后,未归档会话的
279
+ 右键菜单也会出现「永久删除会话」,确认后按原有宿主路由删除日志;关闭时维持仅已归档
280
+ 会话可见。
207
281
 
208
282
  ### Added
209
283
 
@@ -212,13 +286,17 @@
212
286
  unarchived session rows. The confirmation dialog, host route and transcript
213
287
  cleanup are unchanged; without the switch the entry stays archived-only.
214
288
 
215
- ### 中文摘要
289
+ ## 1.4.0 — 2026-11-03
216
290
 
217
- - 设置 →「行菜单」新增「允许删除未归档会话」开关(默认关闭)。开启后,未归档会话的
218
- 右键菜单也会出现「永久删除会话」,确认后按原有宿主路由删除日志;关闭时维持仅已归档
219
- 会话可见。
291
+ ### 中文摘要
220
292
 
221
- ## 1.4.0 — 2026-11-03
293
+ - 工作区 / 会话右键菜单新增「打开方式」二级菜单(复用 DSH 内置 `open-in-app` 应用列表),
294
+ 常用应用可置顶到一级菜单,默认自动置顶第一个编辑器。
295
+ - 已归档会话新增「永久删除会话」和「删除所有已归档会话」,由本插件宿主路由完成,
296
+ 不级联删除 fork 子会话,无回收站。
297
+ - 设置 →「行菜单」新增各项开关、应用逐个显隐与置顶。
298
+ - 与 `dsh-session-menu` 共存时自动隐藏重复条目,并在设置里说明冲突。
299
+ - 工作区菜单改为 `MenuSurface` + `MenuItemButton` 自绘以支持子菜单,恢复分组分隔线。
222
300
 
223
301
  ### Added
224
302
 
@@ -264,24 +342,17 @@
264
342
  - The open-with feature needs DSH with the built-in `open-in-app` routes; on hosts
265
343
  without them the submenu shows an "apps unavailable" hint.
266
344
 
267
- ### 中文摘要
268
-
269
- - 工作区 / 会话右键菜单新增「打开方式」二级菜单(复用 DSH 内置 `open-in-app` 应用列表),
270
- 常用应用可置顶到一级菜单,默认自动置顶第一个编辑器。
271
- - 已归档会话新增「永久删除会话」和「删除所有已归档会话」,由本插件宿主路由完成,
272
- 不级联删除 fork 子会话,无回收站。
273
- - 设置 →「行菜单」新增各项开关、应用逐个显隐与置顶。
274
- - 与 `dsh-session-menu` 共存时自动隐藏重复条目,并在设置里说明冲突。
275
- - 工作区菜单改为 `MenuSurface` + `MenuItemButton` 自绘以支持子菜单,恢复分组分隔线。
276
-
277
345
  ## 1.3.5
278
346
 
347
+ - 1.3.5 发布,详见 GitHub Release 说明。
279
348
  - Release 1.3.5. See the GitHub release notes for details.
280
349
 
281
350
  ## 1.3.4
282
351
 
352
+ - 复制反馈改用宿主自带的 Toast,并删除与内置重复的会话链接条目。
283
353
  - Use the official toast for copy feedback and remove the redundant session-link item.
284
354
 
285
355
  ## 1.3.3
286
356
 
357
+ - 预热行操作指针,让菜单扩展在第一帧就渲染出来。
287
358
  - Prime the row action pointer so menu extensions render in the first frame.
package/README.en.md CHANGED
@@ -114,13 +114,49 @@ With everything off, the "…" button behaves exactly like DSH's own.
114
114
  Blank draft sessions have no right-click menu and are left alone. Rows that are
115
115
  neither a workspace nor a session (e.g. "Show more") are not intercepted.
116
116
 
117
+ ### Right-click in the conversation body
118
+
119
+ Right-clicking in the conversation body — blank space, thinking blocks, replies and tool
120
+ summaries (but not the composer, the header toolbar or tool cards themselves) — opens a
121
+ vertical menu that lists that toolbar in **visual** left-to-right order, each row carrying
122
+ the original button's icon:
123
+
124
+ - with `dsh-sidebar-organizer` installed and a customised "session header toolbar"
125
+ layout, the menu follows its order; otherwise it is DSH's default order. The
126
+ organizer reorders with CSS `order`, so DOM order is not screen order — the menu
127
+ sorts by `getBoundingClientRect()` at right-click time;
128
+ - "Open with" is collapsed exactly like the workspace and session menus: pinned apps
129
+ become top-level rows (e.g. "Open with Visual Studio Code") and the remaining apps
130
+ move into an "Open with ›" submenu that expands on hover or click. The "Open with"
131
+ master switch, per-app switches and pinning all apply; turning the master switch off
132
+ removes the whole group;
133
+ - "More actions" no longer opens the header "…" popover: it expands in place like the
134
+ other submenus and mirrors the host menu's entries (Copy session as Markdown, Download
135
+ session log, Feedback, …), and picking one runs it immediately. Its row order follows
136
+ `dsh-sidebar-organizer` too: dragging rows inside the "…" popover saves the order to
137
+ `dsh.sidebar-organizer.host-menu-order.v1`, and this submenu re-sorts with it;
138
+ - sections are separated by faint rules automatically, and row height, padding,
139
+ radius, 13px type and 14px icons match DSH's native context menus;
140
+ - a "More" style overflow trigger is pinned to the last row (can be switched off in
141
+ Settings); buttons the organizer tucked into "More actions" do not show up on their
142
+ own;
143
+ - selecting an ordinary row is a real click: the menu closes, then a `click` is
144
+ dispatched to the original header button, so "Find", "Toggle bottom panel" and
145
+ friends still open their native popovers;
146
+ - a text selection wins: the plugin stays out of the way and lets the browser's
147
+ selection menu appear; inputs and links inside messages also keep their native menu;
148
+ tool cards, the composer, the toolbar itself and sidebar rows keep their own native
149
+ context menus;
150
+ - when no usable toolbar button can be found (a draft session, or every button
151
+ hidden), the plugin leaves the native menu alone.
152
+
117
153
  ### Settings
118
154
 
119
155
  Settings → "Row menu" toggles every new entry:
120
156
 
121
157
  | Switch | Effect |
122
158
  | --- | --- |
123
- | Open with | Hides "Open with" and every pinned app from workspace and session menus |
159
+ | Open with | Hides "Open with" and every pinned app from workspace, session and conversation-body menus |
124
160
  | Open with → applications | Hides individual applications; the adjacent "Pin" button promotes an app to the top level |
125
161
  | Delete session | Hides the single-session delete entry in session menus |
126
162
  | Allow deleting unarchived sessions | Off by default; also shows "Delete session permanently" on unarchived rows. Requires the previous switch |
@@ -128,6 +164,8 @@ Settings → "Row menu" toggles every new entry:
128
164
  | Show archived sessions | Hides the workspace "Show / hide archived sessions" entry (on by default; the entry itself only appears when that workspace has archived sessions) |
129
165
  | Also show in the "…" menu → workspace | Adds workspace right-click entries one by one to the row's "…" menu: New session, Open with, Copy workspace path, Open in new tab, archived-session toggle, Delete workspace and all sessions. On 0.2.1 enabling any of them makes this plugin render the "…" menu |
130
166
  | Also show in the "…" menu → session | Adds session right-click entries one by one to the native "…" menu: Open with, Delete session, Delete all archived sessions |
167
+ | Enable blank-space context menu | Master switch for the conversation-body right-click menu (blank space, thinking blocks, replies; on by default); when off, that area keeps the browser/host native menu |
168
+ | Pin "More" to the far right | On by default; keeps a "More actions" style overflow trigger as the last row regardless of its current toolbar position |
131
169
 
132
170
  The "Also show in the "…" menu" switches are all off by default; until one is
133
171
  enabled the "…" menu is exactly DSH's own.
@@ -138,8 +176,8 @@ entry into the "…" menu. On 0.2.1 workspace rows have no host menu to contribu
138
176
  so the plugin takes over the "…" button and draws the menu itself.
139
177
 
140
178
  Switches live in browser `localStorage` (`dsh.sidebar-row-menu.items.v1`,
141
- `dsh.sidebar-row-menu.open-with.v1`, `dsh.sidebar-row-menu.open-with.pinned.v1` and
142
- `dsh.sidebar-row-menu.ellipsis.v1`)
179
+ `dsh.sidebar-row-menu.open-with.v1`, `dsh.sidebar-row-menu.open-with.pinned.v1`,
180
+ `dsh.sidebar-row-menu.ellipsis.v1` and `dsh.sidebar-row-menu.blank-menu.v1`)
143
181
  and apply immediately. Before the first explicit pin, the plugin derives one: the
144
182
  first detected editor (usually VS Code), or the first catalog app when no editor
145
183
  exists.
@@ -445,6 +483,46 @@ mark, so the provider checks the same mark while resolving. The "…" pointerdow
445
483
  clears it before the host resolves, hence the entries show on right-click only; the
446
484
  "Also show in the "…" menu → workspace" switches make the provider skip that check.
447
485
 
486
+ ### Why the conversation-body menu sorts by screen position
487
+
488
+ Toolbar order is not in the DOM: `dsh-sidebar-organizer` reorders with
489
+ `element.style.order`, and tucking an icon into "More actions" changes DOM
490
+ visibility. The conversation-body menu therefore caches nothing; at right-click time
491
+ it walks the `conversation.session.header` actions / utilities / corner slots, takes
492
+ each slot's direct children, flattens the buttons inside them (a split control
493
+ becomes its main button and its chevron), sorts by
494
+ `getBoundingClientRect().left`, and finally moves "More" to the end when that
495
+ switch is on. Organizer layouts, width-driven collapsing and temporarily hidden
496
+ buttons are all reflected automatically.
497
+
498
+ Selecting a row does not duplicate the action: it closes the plugin menu, waits one
499
+ tick, then dispatches `click` to the original header button, so host popovers stay
500
+ anchored to their real trigger. "More actions" is the exception — its button only
501
+ opens a host popover, so the menu walks the React fiber upwards (up to 8 levels) to
502
+ the host Menu's `items` / `onSelect`, renders the second level itself and calls
503
+ `onSelect(id)` directly.
504
+
505
+ Hit testing only accepts targets inside `conversation.session` that are outside the
506
+ header, composer, tool cards and interactive elements; inside a message node,
507
+ right-clicks are allowed (thinking blocks, replies, tool summaries) and only inputs,
508
+ links and `contenteditable` yield. A non-empty `window.getSelection()` also yields,
509
+ leaving the selection menu to the browser. When nothing matches, the event is left
510
+ untouched and the native menu opens as before.
511
+
512
+ "Open with" is a split control in the toolbar (main button plus chevron), so
513
+ flattening it would produce two rows. Collection therefore detects the split first
514
+ (two or more buttons, a split-ish container class, or a chevron labelled "More open
515
+ with"), tags that unit as the open-with group, and rendering reuses the workspace /
516
+ session menu treatment: the app catalog comes from `useApps` / `usePinned` /
517
+ `useChildren`, pinned apps render as top-level rows and the rest go into the
518
+ "Open with" submenu positioned by `submenuGeometry`. The session's `cwd` comes from
519
+ the selected row (`[data-row-key^="session:"][aria-selected="true"]`, falling back to
520
+ the sessions store row with `retainedBy.mainView > 0`); if the catalog or `cwd` is not
521
+ ready yet, the original split buttons are shown instead. When the logical section
522
+ changes (open-with / actions / utilities / corner / More), the next row gets
523
+ `separatorBefore`; the rule matches native menus (0.5px, 3px 8px margins, 12% white)
524
+ along with row height, padding and 14px icons.
525
+
448
526
  ### Why the 0.2.1 menu is mounted imperatively
449
527
 
450
528
  On 0.2.2 the host mounts every menu and the plugin creates no container. On 0.2.1 a
@@ -547,6 +625,12 @@ If a DSH upgrade changes those row components or the menu positioning:
547
625
  - The open-with directory for a session comes from `sessions.list`'s `cwd`,
548
626
  falling back to the workspace directory. Ungrouped sessions may have no
549
627
  directory; in that case a "no directory available" toast is shown.
628
+ - The conversation-body menu depends on the DOM of the three session-header slots
629
+ (`conversation.session.header.actions` / `.utilities` / `.corner`) and on the
630
+ host Menu's React fiber behind "More actions" (the second-level menu reads its
631
+ items / onSelect). If DSH changes those extension points or the fiber shape, the
632
+ affected menu silently falls back to native behaviour and still does not affect
633
+ messages, the composer or the toolbar's own menus.
550
634
 
551
635
  ## License and notices
552
636
 
package/README.md CHANGED
@@ -92,13 +92,40 @@ DSH 0.2.2 把侧栏右键改成数据驱动:工作区菜单由宿主统一渲
92
92
  草稿会话(还没有任何消息的空白会话)没有右键菜单,本插件同样不接管。
93
93
  非工作区 / 非会话的侧边栏行(如“显示更多”)也不会被拦截。
94
94
 
95
+ ### 会话正文右键
96
+
97
+ 在会话正文里右键——空白处、思考过程、回复和工具摘要都可以(输入框、工具条和工具卡片
98
+ 本身以外)——会弹出一份纵向菜单,把这排按钮按**屏幕视觉顺序**从左到右列出来,每项带
99
+ 原按钮的图标:
100
+
101
+ - 装了 `dsh-sidebar-organizer` 且调整过「会话头部工具条」时,菜单顺序跟随它的排序;
102
+ 没装或没调整时就是 DSH 的默认顺序。organizer 用 CSS `order` 排序,DOM 顺序不等于
103
+ 屏幕顺序,所以菜单是按 `getBoundingClientRect()` 的横坐标现算的;
104
+ - 「打开方式」按工作区 / 会话右键菜单的同一套规则收纳:置顶的应用直接显示成一级行
105
+ (如「用 Visual Studio Code 打开」),其余应用收进「打开方式 ›」二级菜单,悬浮或
106
+ 点击展开;设置里的「打开方式」总开关、逐应用开关和置顶都对它生效,总开关关闭时这
107
+ 一组整体不出现;
108
+ - 「更多操作」也不再点开右上角的「…」:和其它二级菜单一样在本菜单里展开,直接复刻
109
+ 宿主那份菜单的条目(复制会话为 Markdown、下载 Session 日志、反馈……),选中即执行;
110
+ 子菜单的行序同样跟随 `dsh-sidebar-organizer`——在「…」弹层里拖动过的顺序会写进
111
+ `dsh.sidebar-organizer.host-menu-order.v1`,这里按同一份顺序重排;
112
+ - 不同分组之间自动加淡色分隔线,菜单项的高度、内边距、圆角、13px 字号和 14px 图标
113
+ 都与 DSH 原生右键菜单对齐;
114
+ - 「更多操作」一类的溢出入口固定放在最后一项(可在设置里关掉);被 organizer 收进
115
+ 「更多操作」的按钮不会单独出现;
116
+ - 点普通条目就是点原按钮:先关菜单,再把 `click` 派发给宿主工具条里的那个按钮,所以
117
+ 「查找」「展开底部面板」等弹出的仍是原生面板;
118
+ - 有选中文字时让位给浏览器的选区菜单;消息里的输入控件和链接也保留原生菜单;工具卡片、
119
+ 输入框、工具条本身以及侧栏行同样保留各自的原生菜单;
120
+ - 找不到任何可用的工具条按钮(比如草稿会话或按钮全被隐藏)时,不接管原生菜单。
121
+
95
122
  ### 设置
96
123
 
97
124
  设置 →「行菜单」里可以开关本插件的每个新增项:
98
125
 
99
126
  | 开关 | 作用 |
100
127
  | --- | --- |
101
- | 打开方式 | 关闭后工作区 / 会话菜单里不再出现「打开方式」和置顶应用 |
128
+ | 打开方式 | 关闭后工作区 / 会话菜单以及正文右键菜单里不再出现「打开方式」和置顶应用 |
102
129
  | 打开方式 → 应用 | 逐个隐藏应用;旁边的「置顶」按钮把应用移到一级菜单 |
103
130
  | 永久删除会话 | 关闭后会话菜单里不再出现单条删除入口 |
104
131
  | 允许删除未归档会话 | 默认关闭;开启后未归档会话的右键菜单也会出现「永久删除会话」,需先开启上一项 |
@@ -106,6 +133,8 @@ DSH 0.2.2 把侧栏右键改成数据驱动:工作区菜单由宿主统一渲
106
133
  | 显示已归档会话 | 关闭后工作区菜单里不再出现「显示 / 隐藏已归档会话」(默认开启;该项只在当前工作区存在已归档会话时出现) |
107
134
  | 同时放进「…」菜单 → 工作区 | 逐项把工作区行右键条目也放进行尾「…」菜单:新会话、打开方式、复制工作区路径、在新标签中打开、归档会话开关、删除工作区及所有会话。0.2.1 上开启任意一项后「…」按钮改由本插件渲染 |
108
135
  | 同时放进「…」菜单 → 会话 | 逐项把会话行右键条目加进原生「…」菜单:打开方式、永久删除会话、删除所有已归档会话 |
136
+ | 启用空白处右键菜单 | 会话正文(空白处、思考过程、回复)的右键菜单总开关(默认开启);关闭后该区域恢复浏览器 / 宿主的原生菜单 |
137
+ | 「更多」固定在最右 | 默认开启;把「更多操作」一类的溢出入口固定在菜单最后一项,不受工具条当前顺序影响 |
109
138
 
110
139
  「同时放进「…」菜单」下的开关默认全部关闭,`…` 菜单在未开启时与 DSH 完全一致。
111
140
 
@@ -114,8 +143,8 @@ DSH 0.2.2 起行尾「…」与右键共用同一份宿主菜单,但插件条
114
143
  改由插件接管「…」按钮自绘。
115
144
 
116
145
  开关存在浏览器 `localStorage`(`dsh.sidebar-row-menu.items.v1`、
117
- `dsh.sidebar-row-menu.open-with.v1`、`dsh.sidebar-row-menu.open-with.pinned.v1` 与
118
- `dsh.sidebar-row-menu.ellipsis.v1`),
146
+ `dsh.sidebar-row-menu.open-with.v1`、`dsh.sidebar-row-menu.open-with.pinned.v1`、
147
+ `dsh.sidebar-row-menu.ellipsis.v1` 与 `dsh.sidebar-row-menu.blank-menu.v1`),
119
148
  改完立即生效,不需要重启。置顶项在第一次配置前是自动推导的:优先置顶检测到的第一个
120
149
  编辑器(通常是 VS Code),没有编辑器时置顶应用列表里的第一个。
121
150
 
@@ -382,6 +411,48 @@ DSH 的归档可见性只有一个全局筛选(`archivedFilter`:隐藏已归
382
411
  并且行尾「…」的 `pointerdown` 清标发生在宿主解析之前 —— 右键时条目进菜单,点「…」时
383
412
  不进。「同时放进「…」菜单 → 工作区」的开关则让 provider 跳过手势判断,条目不依赖右键。
384
413
 
414
+ ### 会话正文右键为什么按视觉顺序
415
+
416
+ 工具条的顺序不体现在 DOM 里:`dsh-sidebar-organizer` 用 `element.style.order` 重排,
417
+ 把图标收进「更多操作」时也是改 DOM 的可见性。所以会话正文右键不做任何缓存,而是在事件
418
+ 发生的那一刻遍历 `conversation.session.header` 的 actions / utilities / corner 三组
419
+ slot:先取槽位的直接子节点,再把子节点里的按钮(分段按钮会拆成主按钮和箭头两个)摊平,
420
+ 按 `getBoundingClientRect().left` 排序,最后按开关把「更多」压到末尾。这样 organizer
421
+ 的配置、窗口宽度导致的折叠、插件临时隐藏按钮,全都自动反映到菜单里。
422
+
423
+ 点条目不是复制动作,而是把 `click` 派发回工具条上的那个按钮(先关本插件菜单,等一帧
424
+ 再点):宿主弹出层仍以原按钮为锚点,菜单也不用手动同步任何状态。「更多操作」是例外:
425
+ 它的按钮只负责打开宿主弹出层,所以改为顺着 React fiber 找到宿主 Menu 的 `items` /
426
+ `onSelect`(最多向上 8 层,取第一个同时有数组 items 和函数 onSelect 的 props),在本
427
+ 菜单里自绘二级菜单并直接调用 `onSelect(id)`。
428
+
429
+ 命中区域只认 `conversation.session` 内、且不在 header / composer / 工具卡片 / 可交互
430
+ 元素里的目标;消息节点内部允许右键(思考过程、回复、工具摘要),只有输入控件、链接和
431
+ `contenteditable` 会让位。`window.getSelection()` 有非空选中文本时也直接放行,把选区
432
+ 菜单留给浏览器。命中不了就完全不 `preventDefault`,原生菜单照旧。
433
+
434
+ 「打开方式」在工具条里是一对分段按钮(主按钮 + 箭头),摊平后会把一组动作拆成两行。
435
+ 所以收集阶段先认出这组分段按钮(两个以上按钮、容器类名带 split、或箭头按钮的
436
+ `aria-label` 是「更多打开方式」),把它标记成 open-with 组;渲染时不再照抄这两个按钮,
437
+ 而是复用工作区 / 会话菜单的那套渲染:从 `useApps` / `usePinned` / `useChildren` 取宿主
438
+ 应用列表,置顶应用画成一级行,其余收进「打开方式」二级菜单(`submenuGeometry` 负责翻转
439
+ 和夹边)。会话目录取当前选中会话的 `cwd`(`[data-row-key^="session:"][aria-selected="true"]`,
440
+ 取不到时退回会话 store 里 `retainedBy.mainView > 0` 的那一行);应用列表或目录还没就绪时
441
+ 才退回原来的两个分段按钮。分组切换(打开方式 / actions / utilities / corner / 更多)时给
442
+ 下一行加 `separatorBefore`,分隔线、行高、图标尺寸都用原生菜单同一组数值,0.5px 线画在
443
+ `dsrm-sep` 上。
444
+
445
+ 「打开方式」在工具条里是一对分段按钮(主按钮 + 箭头),摊平后会把一组动作拆成两行。
446
+ 所以收集阶段先认出这组分段按钮(两个以上按钮、容器类名带 split、或箭头按钮的
447
+ `aria-label` 是「更多打开方式」),把它标记成 open-with 组;渲染时不再照抄这两个按钮,
448
+ 而是复用工作区 / 会话菜单的那套渲染:从 `useApps` / `usePinned` / `useChildren` 取宿主
449
+ 应用列表,置顶应用画成一级行,其余收进「打开方式」二级菜单(`submenuGeometry` 负责翻转
450
+ 和夹边)。会话目录取当前选中会话的 `cwd`(`[data-row-key^="session:"][aria-selected="true"]`,
451
+ 取不到时退回会话 store 里 `retainedBy.mainView > 0` 的那一行);应用列表或目录还没就绪时
452
+ 才退回原来的两个分段按钮。分组切换(打开方式 / actions / utilities / corner / 更多)时给
453
+ 下一行加 `separatorBefore`,分隔线、行高、图标尺寸都用原生菜单同一组数值,0.5px 线画在
454
+ `dsrm-sep` 上。
455
+
385
456
  ### 为什么 0.2.1 的菜单是命令式挂载
386
457
 
387
458
  0.2.2 的菜单全部由宿主挂载,插件不创建任何容器。0.2.1 上右键事件不是 React 渲染流的一部分,
@@ -463,6 +534,10 @@ DSH 升级若改动行组件或菜单定位实现:
463
534
  - 删除操作直接作用于会话日志目录,宿主没有回收站;确认框里已明确提示不可恢复。
464
535
  - 会话行「打开方式」的目录来自 `sessions.list` 的 `cwd`,取不到时退回
465
536
  所属工作区目录;未分组会话可能没有目录,此时会提示“没有可用的目录路径”。
537
+ - 正文右键依赖会话头部三组 slot(`conversation.session.header.actions` /
538
+ `.utilities` / `.corner`)的 DOM,以及宿主工具条里那个 Menu 的 React fiber
539
+ (「更多操作」二级菜单从这里读 items / onSelect);宿主若改掉这些扩展点或 fiber
540
+ 结构,对应菜单会静默退回原生行为,不会影响消息、输入框和工具条自己的右键。
466
541
 
467
542
  ## 许可与声明
468
543