dsh-sidebar-row-menu 1.3.4 → 1.3.5

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/AI_USAGE.en.md CHANGED
@@ -70,10 +70,10 @@ Not fully verified:
70
70
 
71
71
  - The plugin runs locally and contains **no telemetry, analytics or remote requests**.
72
72
  - The client reads workspace/session objects already in DSH's memory (title, `cwd`,
73
- archived/pinned state) to build menus and copy paths/links.
73
+ archived/pinned state) to build menus and copy paths.
74
74
  - The host route accepts loopback requests only and opens **existing absolute
75
75
  directories** only.
76
- - Clipboard writes happen only when you click "Copy path / Copy link / Copy ID".
76
+ - Clipboard writes happen only when you click "Copy workspace path / Copy Session ID".
77
77
 
78
78
  ## 7. Recommendations
79
79
 
package/AI_USAGE.md CHANGED
@@ -61,9 +61,9 @@
61
61
 
62
62
  - 插件在本地运行,**不包含遥测、统计上报或远程请求**。
63
63
  - 客户端只读取 DSH 已渲染到内存中的工作区/会话对象(标题、`cwd`、归档/置顶状态),
64
- 用于生成菜单与复制路径/链接。
64
+ 用于生成菜单与复制路径。
65
65
  - 宿主路由只接受本机(loopback)请求,且只打开**已存在的绝对目录**。
66
- - 剪贴板写入仅发生在你点击“复制路径 / 复制链接 / 复制 ID”时。
66
+ - 剪贴板写入仅发生在你点击“复制工作区路径 / 复制 Session ID”时。
67
67
 
68
68
  ## 7. 使用建议
69
69
 
package/README.en.md CHANGED
@@ -48,17 +48,16 @@ Right-click does not build a second menu; it opens the row's own "…" menu:
48
48
  | --- | --- |
49
49
  | DSH built-ins | Rename, Fork session, Pin / Unpin, Archive / Unarchive, Copy Session ID |
50
50
  | Other plugins | Whatever they register into `sidebar.workspaces.session.menu.item` |
51
- | This plugin | Open in VS Code, Open in Explorer, Copy session link |
51
+ | This plugin | Open in VS Code, Open in Explorer |
52
52
 
53
- The three entries added by this plugin:
53
+ The two entries added by this plugin:
54
54
 
55
55
  | Item | Behavior |
56
56
  | --- | --- |
57
57
  | Open in VS Code | Uses the session's `cwd`, falling back to its workspace directory |
58
58
  | Open in Explorer | Same as above |
59
- | Copy session link | Copies the `?session=<id>` deep link |
60
59
 
61
- These three are **right-click only**: they do not mount when the "…" button opens
60
+ These two are **right-click only**: they do not mount when the "…" button opens
62
61
  the menu. A short-lived window flag is set before opening; outside that window the
63
62
  entries render `null`.
64
63
 
@@ -90,13 +89,13 @@ resolve it directly by name:
90
89
  Pin a version by appending it to the name:
91
90
 
92
91
  ```
93
- dsh-sidebar-row-menu@1.3.4
92
+ dsh-sidebar-row-menu@1.3.5
94
93
  ```
95
94
 
96
95
  Equivalent command line:
97
96
 
98
97
  ```powershell
99
- dsh plugin --profile desktop add dsh-sidebar-row-menu@1.3.4
98
+ dsh plugin --profile desktop add dsh-sidebar-row-menu@1.3.5
100
99
  ```
101
100
 
102
101
  ### Install from GitHub
@@ -116,13 +115,13 @@ repository is already runnable, so **no local build is required**.
116
115
  That URL tracks the latest commit on `main`. Pin a tag for a stable version:
117
116
 
118
117
  ```
119
- https://github.com/TLEWA/dsh-sidebar-row-menu#v1.3.4
118
+ https://github.com/TLEWA/dsh-sidebar-row-menu#v1.3.5
120
119
  ```
121
120
 
122
121
  Or install the tarball built by Actions directly, without Git:
123
122
 
124
123
  ```
125
- https://github.com/TLEWA/dsh-sidebar-row-menu/releases/download/v1.3.4/dsh-sidebar-row-menu-1.3.4.tgz
124
+ https://github.com/TLEWA/dsh-sidebar-row-menu/releases/download/v1.3.5/dsh-sidebar-row-menu-1.3.5.tgz
126
125
  ```
127
126
 
128
127
  Equivalent command line:
@@ -244,8 +243,8 @@ loopback checks, route status codes) and the client module (module id, exports,
244
243
  dependency whitelist, listener install/uninstall, slot registry). Integration
245
244
  tests use a fake `__reactFiber$`, DOM and `Menu` host to assert workspace menu
246
245
  ordering, session right-click delegating to the native menu, blank rows being
247
- skipped, and clipboard content for copy-link. Real fibers and services still need
248
- a manual check in a running GUI.
246
+ skipped, and the success toast shown when copying a workspace path. Real fibers and
247
+ services still need a manual check in a running GUI.
249
248
 
250
249
  Layout:
251
250
 
package/README.md CHANGED
@@ -42,17 +42,16 @@
42
42
  | --- | --- |
43
43
  | DSH 内置 | 重命名、分叉会话、置顶 / 取消置顶、归档 / 取消归档、复制 Session ID |
44
44
  | 其他插件 | 它们注册进 `sidebar.workspaces.session.menu.item` 的条目 |
45
- | 本插件 | 使用 VS Code 打开、在资源管理器中打开、复制会话链接 |
45
+ | 本插件 | 使用 VS Code 打开、在资源管理器中打开 |
46
46
 
47
- 本插件追加的三个条目:
47
+ 本插件追加的两个条目:
48
48
 
49
49
  | 菜单项 | 行为 |
50
50
  | --- | --- |
51
51
  | 使用 VS Code 打开 | 优先用会话自己的 `cwd`,取不到则用所属工作区目录 |
52
52
  | 在资源管理器中打开 | 同上 |
53
- | 复制会话链接 | 复制 `?session=<id>` 深链接 |
54
53
 
55
- 这三条是**右键专属**:点行尾「…」按钮时它们不挂载。实现上使用一个只在右键展开瞬间
54
+ 这两条是**右键专属**:点行尾「…」按钮时它们不挂载。实现上使用一个只在右键展开瞬间
56
55
  有效的窗口标记,窗口外的渲染直接返回 `null`。
57
56
 
58
57
  草稿会话(还没有任何消息的空白会话)没有内置「…」菜单,本插件同样不接管。
@@ -82,13 +81,13 @@
82
81
  要固定版本,在包名后加版本号:
83
82
 
84
83
  ```
85
- dsh-sidebar-row-menu@1.3.4
84
+ dsh-sidebar-row-menu@1.3.5
86
85
  ```
87
86
 
88
87
  命令行等价写法:
89
88
 
90
89
  ```powershell
91
- dsh plugin --profile desktop add dsh-sidebar-row-menu@1.3.4
90
+ dsh plugin --profile desktop add dsh-sidebar-row-menu@1.3.5
92
91
  ```
93
92
 
94
93
  ### 从 GitHub 安装
@@ -108,13 +107,13 @@ DSH 桌面端通过 pnpm 安装 Git 依赖;本仓库的 `lib/` 已是可直接
108
107
  该地址跟随 `main` 的最新提交。要固定版本,在地址后加标签:
109
108
 
110
109
  ```
111
- https://github.com/TLEWA/dsh-sidebar-row-menu#v1.3.4
110
+ https://github.com/TLEWA/dsh-sidebar-row-menu#v1.3.5
112
111
  ```
113
112
 
114
113
  也可以直接安装 Actions 打出的压缩包(不经过 Git):
115
114
 
116
115
  ```
117
- https://github.com/TLEWA/dsh-sidebar-row-menu/releases/download/v1.3.4/dsh-sidebar-row-menu-1.3.4.tgz
116
+ https://github.com/TLEWA/dsh-sidebar-row-menu/releases/download/v1.3.5/dsh-sidebar-row-menu-1.3.5.tgz
118
117
  ```
119
118
 
120
119
  命令行等价写法:
@@ -219,7 +218,7 @@ npm run build # npm pack(prepack 会先跑 check),产出 .tgz
219
218
  测试覆盖宿主侧纯函数(路径校验、`vscode://file` 编码、loopback 判定、路由状态码)
220
219
  和客户端模块(模块 id、导出、依赖白名单、监听器安装/卸载、slot 注册表),并用伪造的
221
220
  `__reactFiber$`、DOM 与 `Menu` 宿主做集成测试:工作区右键的菜单项顺序、会话右键是否
222
- 展开内置菜单而不是自建菜单、草稿行是否被放过、复制链接的剪贴板内容都在断言里。
221
+ 展开内置菜单而不是自建菜单、草稿行是否被放过、复制工作区路径的 Toast 反馈都在断言里。
223
222
  真实 fiber 与服务仍需在运行中的 GUI 里做人工验证。
224
223
 
225
224
  目录:
package/lib/client.js CHANGED
@@ -10,7 +10,7 @@
10
10
  * 会话行:直接展开该行内置的「…」菜单
11
11
  * 重命名、分叉、置顶、归档、复制 Session ID 等条目由各自注册进
12
12
  * `sidebar.workspaces.session.menu.item` 的插件提供,本插件不复制、不硬编码。
13
- * 本插件只往这个 slot 里追加自己的条目(VS Code / 资源管理器 / 复制会话链接),
13
+ * 本插件只往这个 slot 里追加自己的条目(VS Code / 资源管理器),
14
14
  * 所以它们既出现在「…」菜单里,也自动出现在右键菜单里。
15
15
  *
16
16
  * 设计要点:
@@ -50,6 +50,7 @@ window.__ModuleLoader__.load({
50
50
  const {
51
51
  Menu,
52
52
  MenuItemButton,
53
+ Toast,
53
54
  writeClipboard,
54
55
  IconEditOutlineRegular,
55
56
  IconTrashOutlineRegular,
@@ -57,7 +58,7 @@ window.__ModuleLoader__.load({
57
58
  IconFolderOpenRegular,
58
59
  IconProjectAddOutlineRegular,
59
60
  IconNewChatOutlineRegular,
60
- IconLinkOutlineRegular,
61
+ IconWarningOutlineRegular,
61
62
  IconCopyOutlineRegular,
62
63
  } = require('@deepseek-ai/dsh-client-ui-primitives');
63
64
 
@@ -65,6 +66,8 @@ window.__ModuleLoader__.load({
65
66
  const OPEN_ENDPOINT = '/dsh-sidebar-row-menu/open';
66
67
  /** 运行时探测用标记属性(也是离线冒烟测试的抓手)。 */
67
68
  const MENU_ATTR = 'data-dsh-sidebar-row-menu';
69
+ /** 复制反馈的官方 Toast 挂载点。 */
70
+ const TOAST_ATTR = 'data-dsh-sidebar-row-menu-toast';
68
71
  /** 本地化命名空间。 */
69
72
  const NS = 'sidebar-row-menu';
70
73
  /** 内置「…」菜单的扩展点;条目由各插件自行注册。 */
@@ -78,7 +81,6 @@ window.__ModuleLoader__.load({
78
81
  vscode: '使用 VS Code 打开',
79
82
  explorer: '在资源管理器中打开',
80
83
  copyPath: '复制工作区路径',
81
- copyLink: '复制会话链接',
82
84
  openInTab: '在新标签中打开',
83
85
  deleteWorkspace: '删除工作区',
84
86
  copied: '已复制',
@@ -93,7 +95,6 @@ window.__ModuleLoader__.load({
93
95
  vscode: 'Open in VS Code',
94
96
  explorer: 'Reveal in File Explorer',
95
97
  copyPath: 'Copy workspace path',
96
- copyLink: 'Copy session link',
97
98
  openInTab: 'Open in new tab',
98
99
  deleteWorkspace: 'Delete workspace',
99
100
  copied: 'Copied',
@@ -205,29 +206,48 @@ window.__ModuleLoader__.load({
205
206
 
206
207
  /* ------------------------------------------------------------ 小工具 */
207
208
 
208
- /** 小提示条:复制 / 打开失败之类给一句反馈。 */
209
- function toast(message) {
209
+ /**
210
+ * 轻提示:直接用官方 Toast primitive(与内置「复制 Session ID」同款、
211
+ * 同一个底部居中 portal),不再自绘 DOM 气泡。
212
+ */
213
+ let toastHost = null;
214
+ let toastRoot = null;
215
+
216
+ function closeToast() {
217
+ const host = toastHost;
218
+ const root = toastRoot;
219
+ toastHost = null;
220
+ toastRoot = null;
221
+ if (root !== null) {
222
+ try {
223
+ root.unmount();
224
+ } catch {
225
+ }
226
+ }
227
+ if (host !== null) host.remove();
228
+ }
229
+
230
+ function toast(message, tone) {
210
231
  if (document.body === null) return;
211
- const el = document.createElement('div');
212
- el.textContent = message;
213
- el.style.cssText = [
214
- 'position:fixed',
215
- 'left:50%',
216
- 'bottom:28px',
217
- 'transform:translateX(-50%)',
218
- 'z-index:2147483647',
219
- 'padding:8px 14px',
220
- 'border-radius:8px',
221
- 'font-size:13px',
222
- 'font-family:inherit',
223
- 'background:var(--dsw-alias-button-elevated-fill,#2f2f31)',
224
- 'color:var(--dsw-alias-label-primary,#ececec)',
225
- 'box-shadow:0 6px 20px rgba(0,0,0,.35)',
226
- 'pointer-events:none',
227
- 'white-space:nowrap',
228
- ].join(';');
229
- document.body.appendChild(el);
230
- window.setTimeout(() => el.remove(), 2600);
232
+ closeToast();
233
+ const host = document.createElement('div');
234
+ host.setAttribute(TOAST_ATTR, '');
235
+ host.style.cssText =
236
+ 'position:fixed;left:0;top:0;width:0;height:0;z-index:2147483647;pointer-events:none';
237
+ document.body.appendChild(host);
238
+ const root = createRoot(host);
239
+ toastHost = host;
240
+ toastRoot = root;
241
+ const props = {
242
+ text: message,
243
+ onDone: () => window.setTimeout(closeToast, 0),
244
+ };
245
+ if (tone === 'success') props.tone = 'success';
246
+ if (tone === 'warning') {
247
+ props.tone = 'warning';
248
+ props.icon = jsx(IconWarningOutlineRegular, {});
249
+ }
250
+ root.render(jsx(Toast, props));
231
251
  }
232
252
 
233
253
  /** 取客户端服务;cordis 对未 inject 的服务在属性访问时也会抛错,全部兜住。 */
@@ -277,20 +297,13 @@ window.__ModuleLoader__.load({
277
297
  async function copyText(text, t) {
278
298
  try {
279
299
  const ok = await writeClipboard(text);
280
- toast(ok ? t('copied') : t('copyFailed'));
300
+ toast(ok ? t('copied') : t('copyFailed'), ok ? 'success' : 'warning');
281
301
  } catch (error) {
282
302
  console.warn('[dsh-sidebar-row-menu] clipboard failed:', error);
283
- toast(t('copyFailed'));
303
+ toast(t('copyFailed'), 'warning');
284
304
  }
285
305
  }
286
306
 
287
- /** ?session=<id> 深链接(与 dsh-workspace-menu / 内置 toast 的格式一致)。 */
288
- function deepLink(sessionId) {
289
- const url = new URL(window.location.href);
290
- url.searchParams.set('session', sessionId);
291
- return url.toString();
292
- }
293
-
294
307
  function workspaceCwd(ctx, group) {
295
308
  if (typeof group?.cwd === 'string' && group.cwd !== '') return group.cwd;
296
309
  const workspaces = serviceOf(ctx, 'workspaces');
@@ -487,21 +500,6 @@ window.__ModuleLoader__.load({
487
500
  });
488
501
  }
489
502
 
490
- /** 会话菜单条目:复制会话链接。 */
491
- function SessionCopyLinkMenuItem({ sessionId, useMenuOpenState, t }) {
492
- const visible = useRightClickEntry();
493
- const [, setMenuOpen] = useMenuOpenState();
494
- if (!visible) return null;
495
- return jsx(MenuItemButton, {
496
- icon: jsx(IconLinkOutlineRegular, { size: 14 }),
497
- onSelect: () => {
498
- setMenuOpen(false);
499
- copyText(deepLink(sessionId), t);
500
- },
501
- children: t('copyLink'),
502
- });
503
- }
504
-
505
503
  /**
506
504
  * 把本插件自己的会话动作注册进内置「…」菜单的 slot。
507
505
  * 排序放在内置条目之后(pin 100 / rename 200 / fork 300 / archive 400 /
@@ -511,7 +509,6 @@ window.__ModuleLoader__.load({
511
509
  const entries = [
512
510
  { id: 'row-menu-vscode', order: 500, Component: SessionVscodeMenuItem },
513
511
  { id: 'row-menu-explorer', order: 510, Component: SessionExplorerMenuItem },
514
- { id: 'row-menu-copy-link', order: 520, Component: SessionCopyLinkMenuItem },
515
512
  ];
516
513
  return ctx.slots.inject(SESSION_MENU_SLOT, function* () {
517
514
  for (const entry of entries) {
@@ -747,6 +744,7 @@ window.__ModuleLoader__.load({
747
744
  return () => {
748
745
  window.removeEventListener('contextmenu', onContextMenu, true);
749
746
  closeMenu();
747
+ closeToast();
750
748
  };
751
749
  }
752
750
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-sidebar-row-menu",
3
- "version": "1.3.4",
3
+ "version": "1.3.5",
4
4
  "type": "module",
5
5
  "description": "DSH sidebar right-click menus: a self-composed menu for workspace rows, and the native slot menu opened at the pointer for session rows.",
6
6
  "keywords": [