dsh-conversation-navigator 0.1.17 → 0.1.19

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.
Files changed (3) hide show
  1. package/README.md +5 -2
  2. package/lib/client.js +163 -32
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -7,8 +7,11 @@ Codex 风格的 **DeepSeek Harness(DSH)Web 端会话导航面板**:在对话页*
7
7
  ## 功能
8
8
 
9
9
  - **按轮折叠大纲**:默认只显示"第 N 轮 + 你的问题"列表,长对话一目了然
10
- - **关键词过滤**:顶部搜索框只按「你的提问 + 助手实际回复文本」过滤(上下文、工具、命令、压缩、推理等不参与匹配),命中词高亮,列表文本自动定位到关键词处
11
- - **展开/折叠步次**:点击轮次行右侧的 `▸ N` / `▾` 展开或折叠该轮的步次明细(助手回复、工具调用、命令、压缩点等)
10
+ - **关键词过滤**:点击左上角搜索图标呼出输入框,只按「你的提问 + 助手实际回复文本」过滤(上下文、工具、命令、压缩、推理等不参与匹配),命中词高亮,列表文本自动定位到关键词处
11
+ - **展开/折叠步次**:点击轮次行右侧的箭头按钮(`▸ N`,展开时旋转为 `▾`)平滑展开/折叠该轮的步次明细(助手回复、工具调用、命令、压缩点等)
12
+ - **悬停查看全文**:鼠标在轮次行停留片刻,气泡显示该轮用户提问的完整原文,不再被单行截断
13
+ - **显示 / 隐藏轮次**:头部切换按钮一键切换两种风格——「显示轮次」为经典分组视图(压缩等系统事件与轮次同级加粗展示);「隐藏轮次」为极简视图,每一行统一为轨迹徽标 + 文本(用户 = 业务蓝、助手 = 紫罗兰、压缩 = 中性灰),搜索框展开时按钮自动让位
14
+ - **丝滑动效**:面板开合淡入淡出、步次展开/折叠高度过渡、过滤结果逐条级联淡入、折叠箭头旋转——全部纯 CSS 实现,零依赖
12
15
  - **点击定位**:点击轮次主体或步次条目,平滑滚动跳转到对话中对应位置(不改变折叠状态)
13
16
  - **加载更早 / 加载全部**:面板顶部两个按钮——「加载更早」向后翻一页、「加载全部」一键把所有历史轮次载入导航,之后可任意跳转(页面默认仍懒加载,只有点按钮才补载)
14
17
  - **位置跟踪**:手动滚动对话时,面板自动高亮并跟随当前正在阅读的轮次
package/lib/client.js CHANGED
@@ -5,7 +5,7 @@ window.__ModuleLoader__.load({
5
5
  var exports = module.exports;
6
6
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
7
  const React = require("react");
8
- const { Button, Tooltip, IconCloseOutline16 } = require("@deepseek-ai/dsh-client-ui-primitives");
8
+ const { Button, Tooltip, IconCloseOutline16, IconSearchOutline16 } = require("@deepseek-ai/dsh-client-ui-primitives");
9
9
 
10
10
  /* ---------- custom icons (DSH outline style, unique to this panel) ---------- */
11
11
  function ToggleIcon() {
@@ -65,6 +65,16 @@ window.__ModuleLoader__.load({
65
65
  );
66
66
  }
67
67
 
68
+ function SwitchTurnsIcon() {
69
+ return React.createElement("svg", {
70
+ viewBox: "0 0 1024 1024", width: 14, height: 14, fill: "currentColor",
71
+ "aria-hidden": true,
72
+ },
73
+ React.createElement("path", { d: "M168 454c-8.837 0-16-7.163-16-16v-48c0-8.837 7.163-16 16-16h531.572L519.63 191.225c-9.858-10.014-2.934-26.883 10.978-27.22l0.424-0.005h70a16 16 0 0 1 11.402 4.775l254 258C876.392 436.89 869.226 454 855.032 454H168z m642-61.741v0.032L855 438h0.032L810 392.259zM601.032 180H601l190.992 194h0.032L601.032 180z" }),
74
+ React.createElement("path", { d: "M855.064 570c8.837 0 16 7.163 16 16l0 48c0 8.837-7.163 16-16 16l-531.572 0L503.434 832.775c9.858 10.014 2.934 26.884-10.978 27.22l-0.424 0.005-70 0a16 16 0 0 1-11.402-4.775l-254-258C146.672 587.11 153.838 570 168.032 570L855.064 570z m-642 61.741l0-0.032L168.064 586l-0.032 0L213.064 631.741zM422.032 844H422.064l-190.992-194-0.032 0L422.032 844z" }),
75
+ );
76
+ }
77
+
68
78
  /* ---------- own stylesheet (static packages have no styles builtin) ---------- */
69
79
  const CSS = `
70
80
  .cnvnav-panel {
@@ -79,24 +89,28 @@ window.__ModuleLoader__.load({
79
89
  font-size: 12px;
80
90
  color: var(--dsw-alias-label-primary, #222);
81
91
  overflow: hidden;
92
+ transition: opacity .18s ease, transform .18s ease;
82
93
  }
94
+ .cnvnav-panel-hidden { opacity: 0; transform: translateY(-6px) scale(.985); pointer-events: none; }
83
95
  .cnvnav-head {
84
96
  display: flex; align-items: center; gap: 8px;
85
97
  padding: 10px 12px;
86
98
  border-bottom: 1px solid var(--dsw-alias-border-l1, rgba(128,128,128,.35));
87
99
  }
88
- .cnvnav-title { font-family: var(--dsw-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', sans-serif); font-size: 16px; font-weight: 700; line-height: 22px; }
89
100
  .cnvnav-count { color: var(--dsw-alias-label-secondary, #888); font-size: 11px; }
101
+ .cnvnav-search { flex: none; display: flex; }
102
+ .cnvnav-turns-toggle { flex: none; display: flex; }
90
103
  .cnvnav-close { margin-left: auto; }
91
104
  .cnvnav-list {
92
105
  overflow-y: auto; padding: 6px; min-height: 0;
93
106
  display: flex; flex-direction: column; gap: 2px;
94
107
  scrollbar-width: thin;
95
108
  }
96
- .cnvnav-group { display: flex; flex-direction: column; gap: 2px; margin-bottom: 2px; }
109
+ .cnvnav-group { display: flex; flex-direction: column; margin-bottom: 2px; }
97
110
  .cnvnav-group-row {
98
111
  display: flex; align-items: stretch;
99
112
  border-radius: 8px; overflow: hidden;
113
+ transition: background .16s ease;
100
114
  }
101
115
  .cnvnav-group-row:hover { background: var(--dsw-alias-bg-layer-2, rgba(128,128,128,.12)); }
102
116
  .cnvnav-group-row-active { background: var(--dsw-alias-bg-layer-2, rgba(128,128,128,.12)); }
@@ -109,7 +123,8 @@ window.__ModuleLoader__.load({
109
123
  padding: 5px 0 5px 8px;
110
124
  color: var(--dsw-alias-label-primary, #222);
111
125
  }
112
- .cnvnav-group-title { font-family: var(--dsw-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', sans-serif); font-size: 14px; font-weight: 700; line-height: 20px; white-space: nowrap; }
126
+ .cnvnav-group-title { font-family: var(--dsw-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', sans-serif); font-size: 14px; font-weight: 700; line-height: 20px; white-space: nowrap; transition: color .16s ease; }
127
+ .cnvnav-group-head .cnvnav-badge { align-self: center; }
113
128
  .cnvnav-group-sub {
114
129
  color: var(--dsw-alias-label-secondary, #888);
115
130
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
@@ -118,18 +133,28 @@ window.__ModuleLoader__.load({
118
133
  .cnvnav-chevron-wrap { flex: none; display: flex; }
119
134
  .cnvnav-chevron {
120
135
  min-width: 30px; align-self: stretch;
121
- display: flex; align-items: center; justify-content: center;
136
+ display: flex; align-items: center; justify-content: center; gap: 3px;
122
137
  border: none; background: transparent; cursor: pointer;
123
138
  color: var(--dsw-alias-label-secondary, #888);
124
139
  font-size: 11px; line-height: 1; padding: 0 8px;
125
140
  white-space: nowrap;
141
+ transition: color .16s ease, background .16s ease;
126
142
  }
127
143
  .cnvnav-chevron:hover { color: var(--dsw-alias-brand-primary, #4f46e5); background: var(--dsw-alias-bg-layer-2, rgba(128,128,128,.12)); }
144
+ .cnvnav-chevron-icon { flex: none; display: block; transition: transform .2s cubic-bezier(.4, 0, .2, 1); }
145
+ .cnvnav-chevron[aria-expanded="true"] .cnvnav-chevron-icon { transform: rotate(90deg); }
146
+ .cnvnav-chevron-count { font-size: 11px; line-height: 1; }
147
+ .cnvnav-steps { display: grid; grid-template-rows: 1fr; margin-top: 2px; transition: grid-template-rows .24s cubic-bezier(.4, 0, .2, 1), margin-top .24s cubic-bezier(.4, 0, .2, 1); }
148
+ .cnvnav-steps-collapsed { grid-template-rows: 0fr; margin-top: 0; }
149
+ .cnvnav-steps-inner { overflow: hidden; min-height: 0; display: flex; flex-direction: column; gap: 2px; }
150
+ .cnvnav-fade-item { animation: cnvnav-fade-up .2s ease-out backwards; }
151
+ @keyframes cnvnav-fade-up { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }
128
152
  .cnvnav-item {
129
153
  display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
130
154
  border: none; background: transparent; cursor: pointer;
131
155
  padding: 5px 8px 5px 22px; border-radius: 8px; position: relative;
132
156
  color: var(--dsw-alias-label-primary, #222);
157
+ transition: background .16s ease;
133
158
  }
134
159
  .cnvnav-item:hover { background: var(--dsw-alias-bg-layer-2, rgba(128,128,128,.12)); }
135
160
  .cnvnav-item-active { background: var(--dsw-alias-bg-layer-2, rgba(128,128,128,.12)); }
@@ -167,9 +192,8 @@ window.__ModuleLoader__.load({
167
192
  color: inherit; border-radius: 2px; padding: 0 1px; font-weight: 600;
168
193
  }
169
194
  .cnvnav-empty { padding: 18px 10px; text-align: center; color: var(--dsw-alias-label-secondary, #888); }
170
- .cnvnav-filter-row { padding: 6px 6px 0; }
171
195
  .cnvnav-filter {
172
- width: 100%; box-sizing: border-box;
196
+ flex: 1; min-width: 0; box-sizing: border-box;
173
197
  height: 28px; padding: 0 8px;
174
198
  border: 1px solid var(--dsw-alias-border-l1, rgba(128,128,128,.35));
175
199
  border-radius: 8px;
@@ -177,9 +201,14 @@ window.__ModuleLoader__.load({
177
201
  color: var(--dsw-alias-label-primary, #222);
178
202
  font-family: var(--dsw-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', sans-serif);
179
203
  font-size: 12px; outline: none;
204
+ animation: cnvnav-search-in .16s ease-out;
180
205
  }
181
206
  .cnvnav-filter::placeholder { color: var(--dsw-alias-label-secondary, #888); }
182
207
  .cnvnav-filter:focus { border-color: var(--dsw-alias-brand-primary, #4f46e5); }
208
+ @keyframes cnvnav-search-in {
209
+ from { opacity: 0; transform: translateX(4px); }
210
+ to { opacity: 1; transform: translateX(0); }
211
+ }
183
212
  .cnvnav-topbar { display: flex; gap: 6px; margin: 6px 6px 0; }
184
213
  .cnvnav-footer { display: flex; gap: 6px; margin: 0 6px 6px; }
185
214
  .cnvnav-bar-btn { flex: 1; display: block; }
@@ -286,7 +315,24 @@ window.__ModuleLoader__.load({
286
315
  }
287
316
  return null;
288
317
  }
289
- function previewFor(node) {
318
+ /* Full user question text (all text blocks) for the hover bubble. */
319
+ function fullDialogueText(node) {
320
+ const d = node && node.data;
321
+ if (!d || typeof d !== "object") return null;
322
+ if (node.kind !== "user") return null;
323
+ if (typeof d.content === "string") {
324
+ const t = d.content.trim();
325
+ return t === "" ? null : t;
326
+ }
327
+ if (!Array.isArray(d.content)) return null;
328
+ const parts = [];
329
+ for (const b of d.content) {
330
+ if (!b || typeof b !== "object") continue;
331
+ if ((b.type === "text" || b.kind === "text") && typeof b.text === "string" && b.text.trim() !== "") parts.push(b.text.trim());
332
+ }
333
+ return parts.length > 0 ? parts.join("\n") : null;
334
+ }
335
+ function previewFor(node) {
290
336
  const d = node && node.data;
291
337
  if (!d || typeof d !== "object") return null;
292
338
  switch (node.kind) {
@@ -377,6 +423,7 @@ window.__ModuleLoader__.load({
377
423
  cls: meta.cls,
378
424
  preview: previewFor(node),
379
425
  search: dialogueText(node),
426
+ full: fullDialogueText(node),
380
427
  time: fmtTime(timeOf(node)),
381
428
  };
382
429
  const turn = turnOf(node);
@@ -503,6 +550,12 @@ window.__ModuleLoader__.load({
503
550
  function Panel() {
504
551
  const snap = useStore();
505
552
  const [filter, setFilter] = React.useState("");
553
+ const [searchOpen, setSearchOpen] = React.useState(false);
554
+ const [turnsHidden, setTurnsHidden] = React.useState(false);
555
+ function toggleSearch() {
556
+ if (searchOpen) setFilter("");
557
+ setSearchOpen(!searchOpen);
558
+ }
506
559
 
507
560
  React.useEffect(() => {
508
561
  if (!snap.open) return;
@@ -547,7 +600,7 @@ window.__ModuleLoader__.load({
547
600
  React.useEffect(() => {
548
601
  if (!snap.open || snap.activeKey === null) return;
549
602
  let target = itemEls[snap.activeKey];
550
- if (target === undefined || target === null) {
603
+ if (target === undefined || target === null || (typeof target.closest === "function" && target.closest(".cnvnav-steps-collapsed") !== null)) {
551
604
  const gid = snap.outline !== null ? snap.outline.byKey[snap.activeKey] : undefined;
552
605
  if (gid !== undefined) target = groupEls[gid];
553
606
  }
@@ -557,13 +610,11 @@ window.__ModuleLoader__.load({
557
610
  const er = target.getBoundingClientRect();
558
611
  const rel = er.top - lr.top + list.scrollTop;
559
612
  if (rel < list.scrollTop || rel + er.height > list.scrollTop + list.clientHeight) {
560
- list.scrollTop = Math.max(0, rel - list.clientHeight / 2);
613
+ list.scrollTo({ top: Math.max(0, rel - list.clientHeight / 2), behavior: "smooth" });
561
614
  }
562
615
  }
563
616
  }, [snap.open, snap.activeKey]);
564
617
 
565
- if (!snap.open) return null;
566
-
567
618
  const groups = snap.outline !== null ? snap.outline.groups : [];
568
619
  const count = snap.outline !== null ? snap.outline.count : 0;
569
620
 
@@ -603,7 +654,7 @@ window.__ModuleLoader__.load({
603
654
  if (end < text.length) parts.push("…");
604
655
  return parts;
605
656
  }
606
- function renderItem(item) {
657
+ function renderItem(item, staggerMs) {
607
658
  const useSnippet = filtering && hit(item.search);
608
659
  const preview = useSnippet ? snippetNodes(item.search, kw, 20, 50) : item.preview;
609
660
  const hasPreview = preview !== null && preview !== "" && (!Array.isArray(preview) || preview.length > 0);
@@ -611,7 +662,8 @@ window.__ModuleLoader__.load({
611
662
  key: item.key,
612
663
  type: "button",
613
664
  ref: (el) => { itemEls[item.key] = el; },
614
- className: "cnvnav-item" + (item.key === snap.activeKey ? " cnvnav-item-active" : ""),
665
+ className: "cnvnav-item" + (item.key === snap.activeKey ? " cnvnav-item-active" : "") + (staggerMs !== undefined ? " cnvnav-fade-item" : ""),
666
+ style: staggerMs !== undefined ? { animationDelay: staggerMs + "ms" } : undefined,
615
667
  onClick: () => jumpTo(item.key),
616
668
  },
617
669
  React.createElement("span", { className: "cnvnav-badge cnvnav-badge-" + item.cls }, item.label),
@@ -625,15 +677,37 @@ window.__ModuleLoader__.load({
625
677
  }
626
678
  function renderGroupHead(g, groupActive, chevron) {
627
679
  const headSearch = g.items.length > 0 ? g.items[0].search : null;
680
+ const headFull = g.headIsUser && g.items.length > 0 ? g.items[0].full : null;
628
681
  const useSnippet = filtering && hit(headSearch);
629
682
  const sub = useSnippet ? snippetNodes(headSearch, kw, 15, 40) : g.subtitle;
630
683
  const hasSub = sub !== "" && (!Array.isArray(sub) || sub.length > 0);
684
+ /* 标题策略:
685
+ 显示轮次: 轮次行 = 加粗「第 N 轮」; 压缩等非轮次行 = 加粗类型标签, 视作轮次同级
686
+ 隐藏轮次: 每行统一轨迹徽标 — 轮次头 = 「用户」业务蓝(助手开头则助手紫), 非轮次行 = 各自徽标(压缩=中性灰) */
687
+ let titleNode = null;
688
+ if (g.turn === null) {
689
+ if (turnsHidden && g.items.length > 0) {
690
+ const headItem = g.items[0];
691
+ titleNode = React.createElement("span", {
692
+ className: "cnvnav-badge cnvnav-badge-" + headItem.cls,
693
+ }, headItem.label);
694
+ } else {
695
+ titleNode = React.createElement("span", { className: "cnvnav-group-title" }, g.title);
696
+ }
697
+ } else if (!turnsHidden) {
698
+ titleNode = React.createElement("span", { className: "cnvnav-group-title" }, g.title);
699
+ } else if (g.items.length > 0) {
700
+ const headItem = g.items[0];
701
+ titleNode = React.createElement("span", {
702
+ className: "cnvnav-badge cnvnav-badge-" + headItem.cls,
703
+ }, headItem.kind === "user" ? "用户" : headItem.label);
704
+ }
631
705
  return React.createElement("div", {
632
706
  ref: (el) => { groupEls[g.gid] = el; },
633
707
  className: "cnvnav-group-row" + (groupActive ? " cnvnav-group-row-active" : ""),
634
708
  },
635
709
  React.createElement(Tooltip, {
636
- label: "跳转到此位置",
710
+ label: headFull !== null ? headFull : "跳转到此位置", maxWidth: 340,
637
711
  side: "top",
638
712
  delayMs: 500,
639
713
  },
@@ -643,7 +717,7 @@ window.__ModuleLoader__.load({
643
717
  className: "cnvnav-group-head",
644
718
  onClick: () => jumpTo(g.headKey),
645
719
  },
646
- React.createElement("span", { className: "cnvnav-group-title" }, g.title),
720
+ titleNode,
647
721
  hasSub
648
722
  ? React.createElement("span", { className: "cnvnav-group-sub" }, sub)
649
723
  : null,
@@ -666,9 +740,19 @@ window.__ModuleLoader__.load({
666
740
  );
667
741
  if (!headHit && hits.length === 0) continue;
668
742
  const groupActive = g.items.some((it) => it.key === snap.activeKey);
669
- groupNodes.push(React.createElement("div", { key: g.gid, className: "cnvnav-group" },
743
+ groupNodes.push(React.createElement("div", {
744
+ key: g.gid,
745
+ className: "cnvnav-group cnvnav-fade-item",
746
+ style: { animationDelay: (groupNodes.length * 18) + "ms" },
747
+ },
670
748
  renderGroupHead(g, groupActive, null),
671
- hits.map(renderItem),
749
+ hits.length > 0
750
+ ? React.createElement("div", { className: "cnvnav-steps" },
751
+ React.createElement("div", { className: "cnvnav-steps-inner" },
752
+ hits.map((it, i) => renderItem(it, i * 20)),
753
+ ),
754
+ )
755
+ : null,
672
756
  ));
673
757
  }
674
758
  } else {
@@ -694,15 +778,30 @@ window.__ModuleLoader__.load({
694
778
  setState({ expanded: Object.assign({}, state.expanded, { [g.gid]: !expanded }) });
695
779
  },
696
780
  },
697
- expanded ? "▾" : "▸ " + stepItems.length,
781
+ React.createElement("svg", {
782
+ className: "cnvnav-chevron-icon",
783
+ viewBox: "0 0 12 12", width: 12, height: 12, fill: "none",
784
+ stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round",
785
+ "aria-hidden": true,
786
+ },
787
+ React.createElement("path", { d: "M4.5 2.5 8 6l-3.5 3.5" }),
788
+ ),
789
+ expanded ? null : React.createElement("span", { className: "cnvnav-chevron-count" }, String(stepItems.length)),
698
790
  ),
699
791
  ),
700
792
  )
701
793
  : null;
702
794
  return React.createElement("div", { key: g.gid, className: "cnvnav-group" },
703
795
  renderGroupHead(g, groupActive, chevron),
704
- expanded && hasSteps
705
- ? stepItems.map(renderItem)
796
+ hasSteps
797
+ ? React.createElement("div", {
798
+ className: "cnvnav-steps" + (expanded ? "" : " cnvnav-steps-collapsed"),
799
+ "aria-hidden": !expanded,
800
+ },
801
+ React.createElement("div", { className: "cnvnav-steps-inner" },
802
+ stepItems.map(renderItem),
803
+ ),
804
+ )
706
805
  : null,
707
806
  );
708
807
  });
@@ -710,12 +809,53 @@ window.__ModuleLoader__.load({
710
809
 
711
810
  return React.createElement("div", {
712
811
  ref: (el) => { panelEl = el; },
713
- className: "cnvnav-panel",
812
+ className: "cnvnav-panel" + (snap.open ? "" : " cnvnav-panel-hidden"),
714
813
  role: "complementary",
715
814
  "aria-label": "会话导航",
815
+ "aria-hidden": !snap.open,
716
816
  },
717
817
  React.createElement("div", { className: "cnvnav-head" },
718
- React.createElement("span", { className: "cnvnav-title" }, "会话导航"),
818
+ React.createElement(Tooltip, {
819
+ label: searchOpen ? "收起搜索" : "搜索关键词",
820
+ side: "bottom",
821
+ delayMs: 500,
822
+ },
823
+ React.createElement("span", { className: "cnvnav-search" },
824
+ React.createElement(Button, {
825
+ variant: "ghost",
826
+ size: "sm",
827
+ icon: React.createElement(IconSearchOutline16, { size: 14 }),
828
+ onClick: () => toggleSearch(),
829
+ }),
830
+ ),
831
+ ),
832
+ searchOpen
833
+ ? null
834
+ : React.createElement(Tooltip, {
835
+ label: turnsHidden ? "显示轮次" : "隐藏轮次",
836
+ side: "bottom",
837
+ delayMs: 500,
838
+ },
839
+ React.createElement("span", { className: "cnvnav-turns-toggle" },
840
+ React.createElement(Button, {
841
+ variant: turnsHidden ? "primary" : "ghost",
842
+ size: "sm",
843
+ icon: React.createElement(SwitchTurnsIcon),
844
+ "aria-pressed": turnsHidden,
845
+ onClick: () => setTurnsHidden(!turnsHidden),
846
+ }),
847
+ ),
848
+ ),
849
+ searchOpen
850
+ ? React.createElement("input", {
851
+ type: "text",
852
+ className: "cnvnav-filter",
853
+ placeholder: "请输入关键词",
854
+ value: filter,
855
+ autoFocus: true,
856
+ onChange: (e) => setFilter(e.target.value),
857
+ })
858
+ : null,
719
859
  React.createElement("span", { className: "cnvnav-count" }, (filtering ? groupNodes.length + " / " : "") + String(count) + " 条"),
720
860
  React.createElement(Tooltip, {
721
861
  label: "收起面板",
@@ -732,15 +872,6 @@ window.__ModuleLoader__.load({
732
872
  ),
733
873
  ),
734
874
  ),
735
- React.createElement("div", { className: "cnvnav-filter-row" },
736
- React.createElement("input", {
737
- type: "text",
738
- className: "cnvnav-filter",
739
- placeholder: "过滤提问 / 回复…",
740
- value: filter,
741
- onChange: (e) => setFilter(e.target.value),
742
- }),
743
- ),
744
875
  React.createElement("div", { className: "cnvnav-topbar" },
745
876
  React.createElement(Tooltip, {
746
877
  label: "加载更早的一批轮次",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-conversation-navigator",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "description": "Codex 风格的 DSH(DeepSeek Harness)会话导航插件:按轮折叠的对话大纲面板,支持节点点击跳转、滚动位置高亮与轨迹视图同款配色。",
5
5
  "keywords": [
6
6
  "dsh",