dsh-conversation-navigator 0.2.2 → 0.2.4

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.en.md CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  [![npm](https://img.shields.io/npm/v/dsh-conversation-navigator?style=flat-square&color=blue)](https://www.npmjs.com/package/dsh-conversation-navigator)
6
6
  [![downloads](https://img.shields.io/npm/dm/dsh-conversation-navigator?style=flat-square&color=blue)](https://www.npmjs.com/package/dsh-conversation-navigator)
7
+ [![downloads-total](https://img.shields.io/npm/dt/dsh-conversation-navigator?style=flat-square&color=blue)](https://www.npmjs.com/package/dsh-conversation-navigator)
7
8
  [![stars](https://img.shields.io/github/stars/gjj-star/dsh-conversation-navigator?style=flat-square&color=green)](https://github.com/gjj-star/dsh-conversation-navigator)
8
9
  [![license](https://img.shields.io/github/license/gjj-star/dsh-conversation-navigator?style=flat-square&color=teal)](https://github.com/gjj-star/dsh-conversation-navigator)
9
10
  [![dependencies](https://img.shields.io/badge/dependencies-0-brightgreen?style=flat-square)](https://www.npmjs.com/package/dsh-conversation-navigator)
@@ -36,6 +37,7 @@ Browser-only (no host behavior), plain JavaScript, zero build step, zero npm dep
36
37
  - **Minimal-left**: the same strip pinned to the left edge of the conversation area (at the right border of the DSH sidebar), leaving the right side for dsh-better-sidebar
37
38
  - The minimal strip collapses to the in-row indicator bars (current = solid brand color, others = 40% foreground-color mix); hovering expands a fixed 7-row positioning panel (click to jump, hover bubble for the full question, thumb-only scrollbar beyond 7 rows; right-aligned expands from right to left, left-aligned from left to right); a floating button above the bars keeps cycling forward (minimal-right → minimal-left → Full); the toggle yields while the search input is open
38
39
  - **Draggable panel**: in Full / Hidden mode, grab the header to drag the panel anywhere in the viewport (auto-clamped to the edges; the expanded height is capped at half the viewport with the top edge fixed and the panel growing downward — expanding a huge turn scrolls the list internally while the "Back to latest / Collapse all" footer stays reachable); the pin button in the header toggles between the default right-dock and the last dragged position; the dragged position and the minimal left/right alignment survive page reloads via localStorage
40
+ - **Resizable panel**: drag from the bottom-left rounded corner (Full / Hidden modes only) — width 240–560 px, height vertical. Height follows a content-adaptive + cap model: actual height = min(turn content, the cap you drag to), tracking the number of turns with no blank space under the footer; floor ~3 turns, ceiling within the conversation viewport. The drag tracks the pointer 1:1 and is fully reversible; width/height persist in localStorage
39
41
  - **Silky motion**: panel fade, step expand/collapse height transitions, staggered fade-in of filter results, rotating collapse arrow — all pure CSS, zero dependencies
40
42
  - **Click to locate**: click a turn or a step to smooth-scroll the conversation to that exact position (fold state is preserved)
41
43
  - **Load earlier / Load all**: two buttons on top — "Load earlier" pages one batch back, "Load all" loads every historical turn into the navigator for arbitrary jumps (the page itself stays lazily loaded until you click)
@@ -68,7 +70,9 @@ dsh plugin --profile web add ./dsh-conversation-navigator-<version>.tgz
68
70
 
69
71
  ## Updates
70
72
 
71
- Edit `lib/client.js` and restart `dsh web`. Only the panel position, docked state and minimal alignment persist (localStorage `dsh-cnvnav:ui:v1`); expand/collapse, mode selection and search keywords still live only within the page session.
73
+ Edit `lib/client.js` and restart `dsh web`. Docked state, dragged position, minimal alignment and the panel width/height persist (localStorage `dsh-cnvnav:ui:v1`); expand/collapse, mode selection and search keywords still live only within the page session.
74
+
75
+ > Published to npm as `dsh-conversation-navigator` (the version badge above always shows the latest release); to upgrade an installed copy, update from the marketplace or run `dsh plugin --profile web add dsh-conversation-navigator` again, then restart.
72
76
 
73
77
  ## How it works
74
78
 
@@ -81,6 +85,7 @@ Edit `lib/client.js` and restart `dsh web`. Only the panel position, docked stat
81
85
  - Hover full text: the turn-row bubble reads `fullDialogueText` (all text blocks of the user node joined), shown via `Tooltip` with a 340px width cap
82
86
  - Modes: the header button cycles `viewMode` (full/hidden/minimal/minimal-left); hidden replaces the turn head title with a trajectory badge (`titleNode` strategy); minimal-right is docked by CSS `right`, minimal-left is pinned to `scrollport.left + 12` (the placement key includes `r.left` and a ResizeObserver on the chat area re-anchors it whenever the left sidebar expands or collapses); the toggle yields while the search input is open
83
87
  - Drag & persistence: the full-panel header is draggable (pointer events, clamped to the viewport); dragging or the pin toggles `docked`; `place()` only clamps a freely-placed panel into the viewport instead of re-docking it; the position, docked state and alignment choice persist in localStorage (`dsh-cnvnav:ui:v1`)
88
+ - Resize: a transparent bottom-left corner grip captures pointer events; width writes `style.width` directly (240–560), height only adjusts `maxHeight` while `height` stays `auto`, so the actual height is always min(content, cap) with no blank space; dragging follows the start point linearly (`base + delta`) and shares the same container/viewport clamps as `place()` so nothing snaps on release; width/height persist as `panelWidth`/`panelHeight`
84
89
  - Styling: `Button`/`Tooltip`/search & close icons reuse `@deepseek-ai/dsh-client-ui-primitives`, the rest are inline Lucide SVGs (ISC License); the panel injects its own `<style>` element, colors use `--dsw-*` theme tokens; everything is cleaned up with the fiber on unload
85
90
 
86
91
  ## Compatibility
package/README.md CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  [![npm](https://img.shields.io/npm/v/dsh-conversation-navigator?style=flat-square&color=blue)](https://www.npmjs.com/package/dsh-conversation-navigator)
6
6
  [![downloads](https://img.shields.io/npm/dm/dsh-conversation-navigator?style=flat-square&color=blue)](https://www.npmjs.com/package/dsh-conversation-navigator)
7
+ [![downloads-total](https://img.shields.io/npm/dt/dsh-conversation-navigator?style=flat-square&color=blue)](https://www.npmjs.com/package/dsh-conversation-navigator)
7
8
  [![stars](https://img.shields.io/github/stars/gjj-star/dsh-conversation-navigator?style=flat-square&color=green)](https://github.com/gjj-star/dsh-conversation-navigator)
8
9
  [![license](https://img.shields.io/github/license/gjj-star/dsh-conversation-navigator?style=flat-square&color=teal)](https://github.com/gjj-star/dsh-conversation-navigator)
9
10
  [![dependencies](https://img.shields.io/badge/dependencies-0-brightgreen?style=flat-square)](https://www.npmjs.com/package/dsh-conversation-navigator)
@@ -32,6 +33,7 @@
32
33
  - **显示 / 隐藏 / 极简四种形态**:头部切换按钮四态循环——「显示轮次」为经典分组视图(压缩等系统事件与轮次同级加粗展示)→「隐藏轮次」每行统一为轨迹徽标 + 文本(用户 = 业务蓝、助手 = 紫罗兰、压缩 = 中性灰)→「极简·右」视口右缘指示条→「极简·左」锚定对话区左缘(为 dsh-better-sidebar 让出右侧),再回到「显示轮次」;
33
34
  - 「极简」形态收起时只露行内指示条(当前 = 品牌色实色、非当前 = 主题前景色掺 40%),悬停展开 7 行画幅的定位面板(点击跳转、悬停全文气泡、超 7 条仅滑块滚动;右对齐从右向左展开、左对齐向右展开),外置悬浮按钮继续循环(极简·右→极简·左→显示轮次),搜索框展开时按钮自动让位
34
35
  - **面板可拖动**:显示轮次 / 隐藏轮次面板按住头部即可拖到视口任意位置(自动夹边;展开高度至多半屏,上边缘固定、下边缘展开,超长轮次时列表内部滚动,底部「回到最新/全部折叠」始终可达),头部图钉按钮在「默认右侧停靠」与「上次拖动位置」间切换;拖动位置与极简左/右对齐选择持久化于 localStorage,刷新页面原样恢复
36
+ - **面板尺寸可调**:左下角圆角处拖拽缩放(仅显示轮次 / 隐藏轮次)——横向拖宽(240–560px),纵向拖高/拖矮;高度采用「内容自适应 + 上限」模型:实际高度 = min(轮次内容, 你拖到的上限),随轮数变化、不会在底部产生空白,下限约 3 轮,上限不超过会话可视区;拖拽 1:1 线性跟随、可逆,尺寸持久化于 localStorage
35
37
  - **丝滑动效**:面板开合淡入淡出、步次展开/折叠高度过渡、过滤结果逐条级联淡入、折叠箭头旋转——全部纯 CSS 实现,零依赖
36
38
  - **点击定位**:点击轮次主体或步次条目,平滑滚动跳转到对话中对应位置(不改变折叠状态)
37
39
  - **加载更早 / 加载全部**:面板顶部两个按钮——「加载更早」向后翻一页、「加载全部」一键把所有历史轮次载入导航,之后可任意跳转(页面默认仍懒加载,只有点按钮才补载)
@@ -64,7 +66,9 @@ dsh plugin --profile web add ./dsh-conversation-navigator-<version>.tgz
64
66
 
65
67
  ## 更新
66
68
 
67
- 修改 `lib/client.js` 后重启 `dsh web` 即可;仅面板位置、停靠状态与极简左/右对齐持久化于 localStorage(`dsh-cnvnav:ui:v1`),展开/折叠、模式、搜索关键词等界面状态仍只存于页面会话内。
69
+ 修改 `lib/client.js` 后重启 `dsh web` 即可;停靠状态、拖动位置、极简左/右对齐与面板宽高持久化于 localStorage(`dsh-cnvnav:ui:v1`),展开/折叠、模式、搜索关键词等界面状态仍只存于页面会话内。
70
+
71
+ > 已发布到 npm(`dsh-conversation-navigator`,徽章实时显示最新版本);升级已安装副本:市场更新或 `dsh plugin --profile web add dsh-conversation-navigator` 后重启。
68
72
 
69
73
  ## 工作原理
70
74
 
@@ -77,6 +81,7 @@ dsh plugin --profile web add ./dsh-conversation-navigator-<version>.tgz
77
81
  - 悬停全文:轮次头气泡读取 `fullDialogueText`(用户节点全部文本块拼接),用 `Tooltip` 展示并限宽 340px
78
82
  - 显示/隐藏/极简模式:`viewMode` 四态循环(full/hidden/minimal/minimal-left),隐藏时仅把轮次头标题替换为轨迹徽标(`titleNode` 策略);极简右对齐由 CSS `right` 锚定视口右缘、左对齐以 `scrollport.left + 12` 钉在对话区左缘(定位 key 含 `r.left`,并用 ResizeObserver 监听对话区宽度变化,左侧栏展开/折叠时紧贴跟随);搜索框展开时按钮让位
79
83
  - 拖动定位与持久化:面板头部拖拽(pointer events,视口夹边),拖动或图钉切换 `docked` 状态;`place()` 对自由放置的面板只做视口夹边、不再自动停靠;位置、停靠状态与对齐选择存于 localStorage(`dsh-cnvnav:ui:v1`)
84
+ - 拖拽缩放:左下角透明热区捕获 pointer 事件;宽度直接写 `style.width`(240–560),高度只调 `maxHeight` 并保持 `height:auto`,使实际高度恒为 min(内容, 上限) 而不产生空白;拖动以起点为基准线性跟随(`base + 位移`),上限与 `place()` 的容器/视口钳制同源,松手零回弹;宽高随 `panelWidth`/`panelHeight` 持久化
80
85
  - 样式:`Button`/`Tooltip`/搜索与关闭图标复用 `@deepseek-ai/dsh-client-ui-primitives`,其余图标为 Lucide 内联 SVG(ISC License);面板容器自建 `<style>` 注入,颜色使用 `--dsw-*` 主题 token;插件卸载时随 fiber 清理
81
86
 
82
87
  ## 兼容性说明
package/lib/client.js CHANGED
@@ -116,6 +116,15 @@ window.__ModuleLoader__.load({
116
116
  border-bottom: 1px solid var(--dsw-alias-border-l1, rgba(128,128,128,.35));
117
117
  }
118
118
  .cnvnav-count { color: var(--dsw-alias-label-secondary, #888); font-size: 11px; }
119
+ /* 左下角拖拽缩放热区(普通面板): 仅圆角区域可拖, 无可见手柄 */
120
+ .cnvnav-resize-grip {
121
+ position: absolute; left: 0; bottom: 0;
122
+ width: 14px; height: 14px;
123
+ cursor: nesw-resize;
124
+ border-bottom-left-radius: 12px;
125
+ touch-action: none;
126
+ background: transparent;
127
+ }
119
128
  .cnvnav-search { flex: none; display: flex; }
120
129
  .cnvnav-turns-toggle { flex: none; display: flex; }
121
130
  .cnvnav-close { margin-left: auto; }
@@ -361,6 +370,8 @@ window.__ModuleLoader__.load({
361
370
  const out = {};
362
371
  if (VIEW_MODES.indexOf(o.viewMode) !== -1) out.viewMode = o.viewMode;
363
372
  if (o.docked === true || o.docked === false) out.docked = o.docked;
373
+ if (typeof o.panelWidth === "number" && o.panelWidth >= 240 && o.panelWidth <= 560) out.panelWidth = o.panelWidth;
374
+ if (typeof o.panelHeight === "number" && o.panelHeight >= 90 && o.panelHeight <= 2000) out.panelHeight = o.panelHeight;
364
375
  if (o.userPos && typeof o.userPos.left === "number" && typeof o.userPos.top === "number"
365
376
  && Number.isFinite(o.userPos.left) && Number.isFinite(o.userPos.top)) {
366
377
  out.userPos = { left: o.userPos.left, top: o.userPos.top };
@@ -373,7 +384,7 @@ window.__ModuleLoader__.load({
373
384
  function persistUi() {
374
385
  try {
375
386
  window.localStorage.setItem(UI_KEY, JSON.stringify({
376
- viewMode: state.viewMode, docked: state.docked, userPos: state.userPos,
387
+ viewMode: state.viewMode, docked: state.docked, userPos: state.userPos, panelWidth: state.panelWidth, panelHeight: state.panelHeight,
377
388
  }));
378
389
  } catch (err) { /* 隐私模式等场景忽略 */ }
379
390
  }
@@ -381,7 +392,7 @@ window.__ModuleLoader__.load({
381
392
  let state = Object.assign({
382
393
  open: true, sessionId: null, outline: null, activeKey: null, expanded: {},
383
394
  hasMore: false, loadingOlder: false, loadingAll: false,
384
- viewMode: "full", docked: true, userPos: null,
395
+ viewMode: "full", docked: true, userPos: null, panelWidth: 288, panelHeight: null,
385
396
  }, savedUi);
386
397
  const listeners = new Set();
387
398
  function setState(patch) {
@@ -665,6 +676,7 @@ window.__ModuleLoader__.load({
665
676
  let panelEl = null;
666
677
  let listEl = null;
667
678
  let dragMove = null;
679
+ let resizeStart = null; /* { x, y, w, h, docked } for the corner grip */
668
680
  const itemEls = {};
669
681
  const groupEls = {};
670
682
 
@@ -759,6 +771,82 @@ window.__ModuleLoader__.load({
759
771
  setState({ docked: false, userPos: { left: Math.round(r.left), top: Math.round(r.top) } });
760
772
  persistUi();
761
773
  }
774
+ /* ---------- 左下角拖拽缩放(仅普通面板) ---------- */
775
+ /* 语义化最小高度: 固定区(头部/顶部按钮栏/底部栏) + 至少 3 行轮次 + 内边距余量,
776
+ 不用固定 px, 任何主题/字号下都能看到对话内容 */
777
+ function minPanelH() {
778
+ const p = panelEl;
779
+ if (p === null) return 240;
780
+ let fixed = 0;
781
+ const head = p.querySelector(".cnvnav-head");
782
+ const topbar = p.querySelector(".cnvnav-topbar");
783
+ const footer = p.querySelector(".cnvnav-footer");
784
+ if (head !== null) fixed += head.offsetHeight;
785
+ if (topbar !== null) fixed += topbar.offsetHeight;
786
+ if (footer !== null) fixed += footer.offsetHeight;
787
+ const row = p.querySelector(".cnvnav-group-row") || p.querySelector(".cnvnav-item");
788
+ const rowH = row !== null ? row.offsetHeight : 34;
789
+ return Math.ceil(fixed + rowH * 3 + 26);
790
+ }
791
+ function startResize(e) {
792
+ if (e.button !== 0) return;
793
+ if (resizeStart !== null) return;
794
+ const el = panelEl;
795
+ if (el === null) return;
796
+ resizeStart = {
797
+ startX: e.clientX, startY: e.clientY,
798
+ baseW: el.offsetWidth || 288,
799
+ baseH: el.offsetHeight || 200,
800
+ baseMaxH: (function () { const v = parseInt(el.style.maxHeight, 10); return Number.isFinite(v) && v > 0 ? v : (el.offsetHeight || 200); })(),
801
+ el: el,
802
+ };
803
+ try { e.currentTarget.setPointerCapture(e.pointerId); } catch (err) { /* 忽略 */ }
804
+ }
805
+ function moveResize(e) {
806
+ const d = resizeStart;
807
+ if (d === null) return;
808
+ const vh = document.documentElement.clientHeight || 800;
809
+ const dx = e.clientX - d.startX;
810
+ const dy = e.clientY - d.startY;
811
+ /* 高度用 maxHeight + height:auto: 实际高度 = min(内容, 上限)。
812
+ 以拖拽起点为基准线性跟随鼠标(无漂移/无状态跳变):
813
+ 拖小立即压缩出滚动, 拖大在内容充足时线性恢复更多行;
814
+ 内容不足时面板保持内容高(拖动无感, 属预期)。 */
815
+ const r = d.el.getBoundingClientRect();
816
+ const sp = document.querySelector("[data-conversation-scroll]");
817
+ /* 上限必须与 place() 各分支一致, 否则松手后会被 place 压回造成跳变:
818
+ docked/常规 = min(容器高-24, vh-40); 自由位置 = vh-顶-8 */
819
+ const sr = sp !== null ? sp.getBoundingClientRect() : null;
820
+ const cap = Math.max(minPanelH(), Math.round(
821
+ state.docked && sr !== null
822
+ ? Math.min(sr.height - 24, vh - 40)
823
+ : vh - r.top - 8
824
+ ));
825
+ const nw = Math.min(Math.max(240, d.baseW - dx), 560);
826
+ /* 目标上限 = 起点可见高 + 总位移, 线性且可逆 */
827
+ const nMaxH = Math.min(Math.max(minPanelH(), d.baseH + dy), cap);
828
+ const left = Math.max(8, r.right - nw);
829
+ d.el.style.width = Math.round(nw) + "px";
830
+ d.el.style.left = Math.round(left) + "px";
831
+ d.el.style.height = "";
832
+ d.el.style.maxHeight = Math.round(nMaxH) + "px";
833
+ }
834
+ function endResize() {
835
+ const d = resizeStart;
836
+ resizeStart = null;
837
+ if (d === null) return;
838
+ const el = d.el;
839
+ const rect = el.getBoundingClientRect();
840
+ const nw = el.offsetWidth;
841
+ const parsed = parseInt(el.style.maxHeight, 10);
842
+ const nh = Number.isFinite(parsed) && parsed > 0 ? parsed : null;
843
+ if (state.docked) {
844
+ setState({ panelWidth: Math.round(nw), panelHeight: nh });
845
+ } else {
846
+ setState({ panelWidth: Math.round(nw), panelHeight: nh, userPos: { left: Math.round(rect.left), top: Math.round(rect.top) } });
847
+ }
848
+ persistUi();
849
+ }
762
850
 
763
851
  React.useEffect(() => {
764
852
  if (!snap.open) return;
@@ -773,20 +861,26 @@ window.__ModuleLoader__.load({
773
861
  const vh = document.documentElement.clientHeight || 800;
774
862
  const mini = viewMode === "minimal" || viewMode === "minimal-left";
775
863
  const alignLeft = viewMode === "minimal-left";
864
+ const width = (state.panelWidth || 288);
865
+ /* 面板宽度对非极简模式统一生效, 确保拖动(未停靠)状态下也能实时刷新 */
866
+ if (!mini) panel.style.width = width + "px";
776
867
  /* 面板被拖走后不再自动停靠: 夹进视口、上边缘固定, 展开高度至多半屏以便下方留白 */
777
868
  if (!mini && !state.docked && state.userPos !== null) {
778
869
  const w = panel.offsetWidth || 288;
779
870
  const h = panel.offsetHeight || 200;
780
871
  const left = Math.min(Math.max(8, Math.round(state.userPos.left)), Math.max(8, vw - w - 8));
781
872
  const top = Math.min(Math.max(8, Math.round(state.userPos.top)), Math.max(8, vh - h - 8));
782
- panel.style.maxHeight = Math.max(160, Math.round(Math.min(vh / 2, vh - top - 8))) + "px";
873
+ const fh = state.panelHeight;
874
+ const cap = Math.max(minPanelH(), Math.round(vh - top - 8));
875
+ const def = Math.max(minPanelH(), Math.round(Math.min(vh / 2, vh - top - 8)));
876
+ panel.style.height = "";
877
+ panel.style.maxHeight = Math.max(minPanelH(), Math.min(typeof fh === "number" && fh > 0 ? fh : def, cap)) + "px";
783
878
  panel.style.left = left + "px";
784
879
  panel.style.top = top + "px";
785
880
  panel.classList.remove("cnvnav-panel-unplaced");
786
881
  return true;
787
882
  }
788
883
  const sp = document.querySelector("[data-conversation-scroll]");
789
- const width = 288;
790
884
  const MINI_H = 220;
791
885
  if (sp === null) {
792
886
  /* 会话视图可能尚未挂载(刷新/重启/切会话时面板先就位);
@@ -808,7 +902,11 @@ window.__ModuleLoader__.load({
808
902
  } else {
809
903
  panel.style.left = Math.max(8, vw - width - 12) + "px";
810
904
  panel.style.top = Math.max(8, 60) + "px";
811
- panel.style.maxHeight = Math.round(vh - 90) + "px";
905
+ const fh = state.panelHeight;
906
+ const cap = Math.round(vh - 90);
907
+ const def = cap;
908
+ panel.style.height = "";
909
+ panel.style.maxHeight = Math.max(minPanelH(), Math.min(typeof fh === "number" && fh > 0 ? fh : def, cap)) + "px";
812
910
  }
813
911
  panel.classList.remove("cnvnav-panel-unplaced");
814
912
  return true;
@@ -835,7 +933,11 @@ window.__ModuleLoader__.load({
835
933
  } else {
836
934
  panel.style.left = Math.max(8, vw - width - 12) + "px";
837
935
  panel.style.top = Math.max(8, Math.round(r.top + 8)) + "px";
838
- panel.style.maxHeight = Math.round(Math.min(r.height - 24, vh - 40)) + "px";
936
+ const fh = state.panelHeight;
937
+ const cap = Math.max(minPanelH(), Math.round(Math.min(r.height - 24, vh - 40)));
938
+ const def = cap;
939
+ panel.style.height = "";
940
+ panel.style.maxHeight = Math.max(minPanelH(), Math.min(typeof fh === "number" && fh > 0 ? fh : def, cap)) + "px";
839
941
  }
840
942
  }
841
943
  panel.classList.remove("cnvnav-panel-unplaced");
@@ -866,7 +968,7 @@ window.__ModuleLoader__.load({
866
968
  window.removeEventListener("resize", place);
867
969
  if (ro !== null) ro.disconnect();
868
970
  };
869
- }, [snap.open, snap.sessionId, viewMode, state.docked, state.userPos]);
971
+ }, [snap.open, snap.sessionId, viewMode, state.docked, state.userPos, state.panelWidth, state.panelHeight]);
870
972
 
871
973
  React.useEffect(() => {
872
974
  if (!snap.open) return;
@@ -1343,6 +1445,14 @@ window.__ModuleLoader__.load({
1343
1445
  ),
1344
1446
  ),
1345
1447
  ),
1448
+ React.createElement("span", {
1449
+ className: "cnvnav-resize-grip",
1450
+ onPointerDown: startResize,
1451
+ onPointerMove: moveResize,
1452
+ onPointerUp: endResize,
1453
+ onPointerCancel: endResize,
1454
+ "aria-hidden": true,
1455
+ }),
1346
1456
  );
1347
1457
  }
1348
1458
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-conversation-navigator",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "DSH(DeepSeek Harness)会话导航插件:按轮折叠的对话大纲面板,支持节点点击跳转、滚动位置高亮与轨迹视图同款配色。",
5
5
  "keywords": [
6
6
  "dsh",