@huanlin/dsh-plugin-ya-workspace-sidebar 0.7.0 → 0.8.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
@@ -8,7 +8,7 @@
8
8
 
9
9
  ![cover](assets/cover.webp)
10
10
 
11
- DSH Web 工作区侧栏替代插件。顶部以虚拟滚动展示全局最近会话(完整列表,不限于 5 条),与下方 Workspace → Session 二级菜单之间有一条可拖拽分隔条(也支持方向键微调、双击复位),面包屑导航与选中工作区的会话按本地日历日期分组(今天/昨天/更早);搜索、添加工作区、重命名、删除、Fork 与归档继续使用 DSH 原生 Host 能力。会话行支持右键菜单(与 … 按钮菜单一致):置顶(本地,置顶行浮于日期分组之上)、重命名、标记未读(本地蓝点,打开会话自动清除)、在资源管理器中打开工作目录、复制路径 / 任务路径 / 日志路径 / 会话 ID。任务路径与日志路径仅文件型(jsonl)持久化部署可用;sqlite 型部署(如 @morlay/better-session)对应菜单项自动禁用。
11
+ DSH Web 工作区侧栏替代插件。顶部以虚拟滚动展示全局最近会话(完整列表,不限于 5 条),与下方 Workspace → Session 二级菜单之间有一条可拖拽分隔条(也支持方向键微调、双击复位),面包屑导航与选中工作区的会话按本地日历日期分组(今天/昨天/更早);搜索、添加工作区、重命名、删除、Fork 与归档继续使用 DSH 原生 Host 能力。会话行支持右键菜单(与 … 按钮菜单一致):置顶(本地,置顶行浮于日期分组之上)、重命名、标记未读(本地蓝点,打开会话自动清除)、在资源管理器中打开工作目录、复制路径 / 任务路径 / 日志路径 / 会话 ID。任务路径与日志路径仅文件型(jsonl)持久化部署可用;sqlite 型部署(如 @morlay/better-session)对应菜单项自动禁用。工作区行不设悬停按钮,右键直接弹出菜单(新建会话 / 在资源管理器中打开 / 复制路径 / 重命名 / 删除);标题超宽时以渐隐(mask 渐变)截断、不显示省略号,路径保持左对齐省略号硬截断。
12
12
 
13
13
  ## 运行
14
14
 
package/lib/client.js CHANGED
@@ -1402,14 +1402,14 @@ button.ya-crumb:hover { background:var(--dsw-alias-interactive-bg-hover); color:
1402
1402
  .ya-workspace-row { min-height:40px; }
1403
1403
  .ya-row-main { flex:1; min-width:0; display:flex; flex-direction:column; justify-content:center; }
1404
1404
  .ya-row-line { display:flex; align-items:center; min-width:0; gap:6px; }
1405
- .ya-row-title { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:13px; line-height:18px; }
1405
+ .ya-row-title { flex:1; min-width:0; overflow:hidden; white-space:nowrap; font-size:13px; line-height:18px; -webkit-mask-image:linear-gradient(to right,#000 calc(100% - 24px),transparent 100%); mask-image:linear-gradient(to right,#000 calc(100% - 24px),transparent 100%); }
1406
1406
  .ya-row-meta { flex:none; color:var(--dsw-alias-label-tertiary); font-size:11px; white-space:nowrap; }
1407
1407
  .ya-workspace-path { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--dsw-alias-label-tertiary); font-size:11px; line-height:15px; }
1408
1408
  .ya-row-actions { flex:none; display:flex; align-items:center; gap:2px; opacity:0; pointer-events:none; transition:opacity 120ms ease-out; }
1409
1409
  .ya-row:hover .ya-row-actions, .ya-menu-open .ya-row-actions { opacity:1; pointer-events:auto; }
1410
1410
  .ya-status-slot { flex:none; width:16px; height:16px; display:inline-flex; align-items:center; justify-content:center; color:var(--dsw-alias-label-tertiary); }
1411
1411
  .ya-recent .ya-row { min-height:31px; }
1412
- .ya-search-workspace { color:var(--dsw-alias-label-tertiary); font-size:11px; line-height:15px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
1412
+ .ya-search-workspace { color:var(--dsw-alias-label-tertiary); font-size:11px; line-height:15px; overflow:hidden; white-space:nowrap; -webkit-mask-image:linear-gradient(to right,#000 calc(100% - 24px),transparent 100%); mask-image:linear-gradient(to right,#000 calc(100% - 24px),transparent 100%); }
1413
1413
  .ya-empty, .ya-status { padding:18px 10px; color:var(--dsw-alias-label-tertiary); text-align:center; font-size:13px; }
1414
1414
  .ya-warning { color:var(--dsw-alias-status-warning); }
1415
1415
  .ya-rename-input { width:100%; height:38px; box-sizing:border-box; border:1px solid var(--dsw-alias-border-l2); border-radius:9px; padding:0 11px; background:transparent; color:var(--dsw-alias-label-primary); outline:none; }
@@ -2299,13 +2299,22 @@ button.ya-crumb:hover { background:var(--dsw-alias-interactive-bg-hover); color:
2299
2299
  ]
2300
2300
  });
2301
2301
  }
2302
- function WorkspaceItem({ row, enter, create, rename, remove, now, t }) {
2303
- const [menuOpen, setMenuOpen] = (0, react.useState)(false);
2302
+ function WorkspaceItem({ row, enter, create, reveal, copy, rename, remove, now, t }) {
2303
+ const [menuAt, setMenuAt] = (0, react.useState)(null);
2304
+ const hasPath = row.path !== void 0;
2304
2305
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2305
- className: `ya-row ya-workspace-row${menuOpen ? " ya-menu-open" : ""}`,
2306
+ className: `ya-row ya-workspace-row${menuAt !== null ? " ya-menu-open" : ""}`,
2306
2307
  role: "treeitem",
2307
2308
  onClick: enter,
2308
2309
  title: row.path,
2310
+ onContextMenu: (event) => {
2311
+ if (!row.real) return;
2312
+ event.preventDefault();
2313
+ setMenuAt({
2314
+ x: event.clientX,
2315
+ y: event.clientY
2316
+ });
2317
+ },
2309
2318
  children: [
2310
2319
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2311
2320
  className: "ya-status-slot",
@@ -2327,50 +2336,68 @@ button.ya-crumb:hover { background:var(--dsw-alias-interactive-bg-hover); color:
2327
2336
  children: row.path
2328
2337
  })]
2329
2338
  }),
2330
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2331
- className: "ya-row-actions",
2332
- children: [row.real && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
2333
- open: menuOpen,
2334
- onClose: () => {
2335
- setMenuOpen(false);
2339
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutline14, {}),
2340
+ row.real && menuAt !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
2341
+ open: true,
2342
+ onClose: () => {
2343
+ setMenuAt(null);
2344
+ },
2345
+ items: [
2346
+ {
2347
+ id: "create",
2348
+ label: t("newSession"),
2349
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutline16, {})
2350
+ },
2351
+ {
2352
+ type: "separator",
2353
+ id: "sep-ws-paths"
2354
+ },
2355
+ {
2356
+ id: "reveal",
2357
+ label: t("revealInExplorer"),
2358
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconFolderOpenOutline16, {}),
2359
+ disabled: !hasPath
2336
2360
  },
2337
- items: [{
2361
+ {
2362
+ id: "copy-path",
2363
+ label: t("copyPath"),
2364
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCopyOutline16, {}),
2365
+ disabled: !hasPath
2366
+ },
2367
+ {
2368
+ type: "separator",
2369
+ id: "sep-ws-manage"
2370
+ },
2371
+ {
2338
2372
  id: "rename",
2339
2373
  label: t("rename"),
2340
2374
  icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutline16, {})
2341
- }, {
2375
+ },
2376
+ {
2342
2377
  id: "delete",
2343
2378
  label: t("deleteWorkspace"),
2344
2379
  icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutline16, {}),
2345
2380
  danger: true
2346
- }],
2347
- onSelect: (id) => {
2348
- setMenuOpen(false);
2349
- if (id === "rename") rename();
2350
- if (id === "delete") remove();
2351
- },
2352
- portal: true,
2353
- closeOnPointerLeave: true,
2354
- anchor: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2355
- type: "button",
2356
- className: "ya-icon-button",
2357
- onClick: (event) => {
2358
- event.stopPropagation();
2359
- setMenuOpen((value) => !value);
2360
- },
2361
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEllipsisOutline16, {})
2362
- })
2363
- }), row.real && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2364
- type: "button",
2365
- className: "ya-icon-button",
2366
- onClick: (event) => {
2367
- event.stopPropagation();
2368
- create();
2369
- },
2370
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutline16, {})
2371
- })]
2372
- }),
2373
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutline14, {})
2381
+ }
2382
+ ],
2383
+ onSelect: (id) => {
2384
+ setMenuAt(null);
2385
+ if (id === "create") create();
2386
+ if (id === "reveal" && row.path !== void 0) {
2387
+ reveal(row.path);
2388
+ return;
2389
+ }
2390
+ if (id === "copy-path" && row.path !== void 0) {
2391
+ copy(row.path);
2392
+ return;
2393
+ }
2394
+ if (id === "rename") rename();
2395
+ if (id === "delete") remove();
2396
+ },
2397
+ portal: true,
2398
+ getAnchorRect: () => new DOMRect(menuAt.x, menuAt.y, 0, 0),
2399
+ anchor: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { "aria-hidden": "true" })
2400
+ })
2374
2401
  ]
2375
2402
  });
2376
2403
  }
@@ -2932,6 +2959,8 @@ button.ya-crumb:hover { background:var(--dsw-alias-interactive-bg-hover); color:
2932
2959
  create: () => {
2933
2960
  if (row.key !== "__ya_ungrouped__") startSession(row.key);
2934
2961
  },
2962
+ reveal,
2963
+ copy,
2935
2964
  rename: () => {
2936
2965
  beginWorkspaceRename(row);
2937
2966
  },