dsh-quick-toc 0.8.0 → 0.8.2

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.en.md CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  All notable changes to **dsh-quick-toc** are documented here. Chinese version: [CHANGELOG.md](CHANGELOG.md).
4
4
 
5
+ ## [0.8.2] - 2026-09-29
6
+
7
+ ### Changed
8
+ - **DSH 0.2.0-rc.2 support**: no code changed; the new prerelease is registered in the compatibility declaration. An isolated environment was exercised point by point (the host starts without a warning, the Plugins page entry and its configuration card, the card's write landing in the settings document, the outline panel's hover and pin, a clean console).
9
+
10
+ ## [0.8.1] - 2026-09-29
11
+
12
+ ### Fixed
13
+ - **The pin on the hover preview could not be clicked**: moving from an outline row towards the card started the fade first, so the card was gone before the pin was reached. Leaving a row now only arms the close, and reaching the card cancels it.
14
+
15
+ ### Changed
16
+ - **The collapsed handle took room from the text in a narrow window**: below a 760-pixel conversation column the collapsed side handle slides back into the divider; the droplet above stays as the way into the outline, and the side handle returns when the window widens.
17
+
5
18
  ## [0.8.0] - 2026-09-29
6
19
 
7
20
  ### Changed
package/CHANGELOG.md CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  **dsh-quick-toc** 的重要变更都记录在这里。英文版见 [CHANGELOG.en.md](CHANGELOG.en.md)。
4
4
 
5
+ ## [0.8.2] - 2026-09-29
6
+
7
+ ### 变更
8
+ - **支持 DSH 0.2.0-rc.2**:插件代码未改动,兼容性声明里登记了新的预发布版本;隔离环境里逐项实测通过(宿主启动无告警、插件页条目与配置卡片、卡片写入落到设置文档、大纲面板的悬停与钉住、控制台无错误)。
9
+
10
+ ## [0.8.1] - 2026-09-29
11
+
12
+ ### 修复
13
+ - **悬停预览卡上的图钉无法点击**:鼠标从大纲行移向卡片时会先开始淡出,卡片在图钉被点到之前就已经消失。现在离开行只是预备关闭,指针落到卡片上即取消。
14
+
15
+ ### 变更
16
+ - **窄窗口下折叠把手占用正文**:对话区域宽度不足 760 像素时,折叠态的侧边把手滑回分隔线内;顶部的水滴把手保留,作为打开大纲的入口,窗口变宽后侧边把手自动回来。
17
+
5
18
  ## [0.8.0] - 2026-09-29
6
19
 
7
20
  ### 变更
package/README.en.md CHANGED
@@ -42,8 +42,8 @@ A conversation TOC plugin for [DeepSeek Harness](https://github.com/deepseek-ai/
42
42
 
43
43
  | Plugin | Supported DSH |
44
44
  | --- | --- |
45
- | **0.8.x** (latest, 0.8.0) | 0.1.5-rc.3, 0.1.7-alpha.1, 0.1.7-alpha.2, 0.1.7-rc.1, 0.1.7-rc.2, 0.2.0-rc.1 |
46
- | 0.7.x (0.7.14) | 0.1.5-rc.3, 0.1.7-alpha.1, 0.1.7-alpha.2, 0.1.7-rc.1, 0.1.7-rc.2, 0.2.0-rc.1 |
45
+ | **0.8.x** (latest, 0.8.2) | 0.1.5-rc.3, 0.1.7-alpha.1, 0.1.7-alpha.2, 0.1.7-rc.1, 0.1.7-rc.2, 0.2.0-rc.1, 0.2.0-rc.2 |
46
+ | 0.7.x (0.7.14) | 0.1.5-rc.3, 0.1.7-alpha.1, 0.1.7-alpha.2, 0.1.7-rc.1, 0.1.7-rc.2, 0.2.0-rc.1, 0.2.0-rc.2 |
47
47
  | 0.6.x (0.6.3) | 0.1.5-rc.1, 0.1.5-rc.2 |
48
48
  | 0.5.x (0.5.1) | 0.1.5-rc.1, 0.1.5-rc.2 |
49
49
  | 0.4.x (0.4.1) | 0.1.5-rc.1, 0.1.5-rc.2 |
package/README.md CHANGED
@@ -42,8 +42,8 @@
42
42
 
43
43
  | 插件版本 | 支持的 DSH 版本 |
44
44
  | --- | --- |
45
- | **0.8.x**(最新,0.8.0) | 0.1.5-rc.3、0.1.7-alpha.1、0.1.7-alpha.2、0.1.7-rc.1、0.1.7-rc.2、0.2.0-rc.1 |
46
- | 0.7.x(0.7.14) | 0.1.5-rc.3、0.1.7-alpha.1、0.1.7-alpha.2、0.1.7-rc.1、0.1.7-rc.2、0.2.0-rc.1 |
45
+ | **0.8.x**(最新,0.8.2) | 0.1.5-rc.3、0.1.7-alpha.1、0.1.7-alpha.2、0.1.7-rc.1、0.1.7-rc.2、0.2.0-rc.1、0.2.0-rc.2 |
46
+ | 0.7.x(0.7.14) | 0.1.5-rc.3、0.1.7-alpha.1、0.1.7-alpha.2、0.1.7-rc.1、0.1.7-rc.2、0.2.0-rc.1、0.2.0-rc.2 |
47
47
  | 0.6.x(0.6.3) | 0.1.5-rc.1、0.1.5-rc.2 |
48
48
  | 0.5.x(0.5.1) | 0.1.5-rc.1、0.1.5-rc.2 |
49
49
  | 0.4.x(0.4.1) | 0.1.5-rc.1、0.1.5-rc.2 |
package/lib/client.js CHANGED
@@ -44,6 +44,11 @@ window.__ModuleLoader__.load({
44
44
  var Z_PANEL = 14; // the docked panel
45
45
  var Z_SHEET = 16; // the curtain, which replaces the docked panel while it is up
46
46
  var Z_HOVER = 18; // hover preview card: above both, still inside the free band
47
+ // A narrow conversation column has no room for a handle floating over the text: below
48
+ // NARROW_CONV_W the collapsed-panel handle slides back into the divider (its usual
49
+ // motion) while the droplet above the conversation stays as the way in. Nothing opens
50
+ // by itself — a resize never overrides the reader's own choice of surface.
51
+ var NARROW_CONV_W = 760;
47
52
  var Z_ERROR = 32; // crash banner: above our layers and the app's chrome, below
48
53
  // DSH's popovers (100) and modals (1000)
49
54
  var EASE = "cubic-bezier(0.22, 0.9, 0.3, 1)"; // smooth non-linear slide
@@ -1574,6 +1579,10 @@ window.__ModuleLoader__.load({
1574
1579
  var _s2 = react.useState(null);
1575
1580
  var viewport = _s2[0];
1576
1581
  var setViewport = _s2[1];
1582
+ // how much room the conversation column itself has (the thing a docked panel
1583
+ // squeezes); 0 while it has not been measured yet, which never counts as narrow
1584
+ var convWidth = viewport ? Math.max(0, window.innerWidth - viewport.left - viewport.right) : 0;
1585
+ var narrowWindow = convWidth > 0 && convWidth < NARROW_CONV_W;
1577
1586
  react.useEffect(function () {
1578
1587
  // Self-healing, because the layout AROUND the conversation can change without
1579
1588
  // a resize: the host's own controls move that column about (measured in a real
@@ -1818,7 +1827,7 @@ window.__ModuleLoader__.load({
1818
1827
  var scrollToBottom = function (e) {
1819
1828
  if (e && e.stopPropagation) e.stopPropagation();
1820
1829
  outlineTouchRef.current = Date.now();
1821
- hoverEnd();
1830
+ hoverEnd(true);
1822
1831
  var el = listRef.current;
1823
1832
  if (!el) return;
1824
1833
  // optimistic: the list is on its way to the newest row, so the button starts
@@ -1904,7 +1913,7 @@ window.__ModuleLoader__.load({
1904
1913
  var backToBrowse = function (e) {
1905
1914
  if (e && e.stopPropagation) e.stopPropagation();
1906
1915
  outlineTouchRef.current = Date.now();
1907
- hoverEnd();
1916
+ hoverEnd(true);
1908
1917
  var el = listRef.current;
1909
1918
  var tgt = liveTgt();
1910
1919
  if (!el || !tgt) return;
@@ -1970,6 +1979,17 @@ window.__ModuleLoader__.load({
1970
1979
  var setHoverClosing = _sHovOut[1];
1971
1980
  var hoverTimerRef = react.useRef(null);
1972
1981
  var hoverCloseTimerRef = react.useRef(null);
1982
+ // The card carries the pin button, so the pointer has to be able to travel from the
1983
+ // row onto the card without the card fading on the way. Leaving a row therefore only
1984
+ // ARMS the close; the card's own mouseenter disarms it, and the fade starts after a
1985
+ // grace period that a crossing pointer fits into.
1986
+ var HOVER_GRACE_MS = 260;
1987
+ var hoverGraceTimerRef = react.useRef(null);
1988
+ var disarmHoverClose = function () {
1989
+ if (hoverGraceTimerRef.current) { clearTimeout(hoverGraceTimerRef.current); hoverGraceTimerRef.current = null; }
1990
+ if (hoverCloseTimerRef.current) { clearTimeout(hoverCloseTimerRef.current); hoverCloseTimerRef.current = null; }
1991
+ setHoverClosing(false);
1992
+ };
1973
1993
  var hoverStart = function (info, el) {
1974
1994
  // the hover card is a preference: off means it never opens (the outline rows
1975
1995
  // themselves keep their hover tint)
@@ -1978,11 +1998,7 @@ window.__ModuleLoader__.load({
1978
1998
  hoverTimerRef.current = setTimeout(function () {
1979
1999
  var r = el && el.getBoundingClientRect ? el.getBoundingClientRect() : null;
1980
2000
  if (!r || r.width <= 0) return;
1981
- if (hoverCloseTimerRef.current) {
1982
- clearTimeout(hoverCloseTimerRef.current);
1983
- hoverCloseTimerRef.current = null;
1984
- }
1985
- setHoverClosing(false);
2001
+ disarmHoverClose();
1986
2002
  setHoverCard({
1987
2003
  title: info.title,
1988
2004
  sub: info.sub,
@@ -1998,16 +2014,23 @@ window.__ModuleLoader__.load({
1998
2014
  });
1999
2015
  }, 260);
2000
2016
  };
2001
- // leaving fades the card out instead of dropping it on the next frame
2002
- var hoverEnd = function () {
2017
+ // leaving fades the card out instead of dropping it on the next frame — but only
2018
+ // after a grace period, because the card carries the pin and the pointer has to be
2019
+ // able to travel from the row onto it (an immediate fade made the pin unreachable).
2020
+ var hoverEnd = function (immediate) {
2003
2021
  if (hoverTimerRef.current) clearTimeout(hoverTimerRef.current);
2022
+ if (hoverGraceTimerRef.current) clearTimeout(hoverGraceTimerRef.current);
2004
2023
  if (hoverCloseTimerRef.current) clearTimeout(hoverCloseTimerRef.current);
2005
- setHoverClosing(true);
2006
- hoverCloseTimerRef.current = setTimeout(function () {
2007
- hoverCloseTimerRef.current = null;
2008
- setHoverCard(null);
2009
- setHoverClosing(false);
2010
- }, 240);
2024
+ var grace = immediate ? 0 : HOVER_GRACE_MS;
2025
+ hoverGraceTimerRef.current = setTimeout(function () {
2026
+ hoverGraceTimerRef.current = null;
2027
+ setHoverClosing(true);
2028
+ hoverCloseTimerRef.current = setTimeout(function () {
2029
+ hoverCloseTimerRef.current = null;
2030
+ setHoverCard(null);
2031
+ setHoverClosing(false);
2032
+ }, 240);
2033
+ }, grace);
2011
2034
  };
2012
2035
 
2013
2036
  // ---- pinned preview + the row menu (0.8.0) --------------------------------
@@ -3128,7 +3151,7 @@ window.__ModuleLoader__.load({
3128
3151
  autoGestureRef.current = Date.now(); // a wheel tick is a reader gesture
3129
3152
  var el = listRef.current;
3130
3153
  if (!el) return;
3131
- hoverEnd();
3154
+ hoverEnd(true);
3132
3155
  if (e.deltaY >= 0) {
3133
3156
  // still scrolling down at the very end of the outline: say so. Outline
3134
3157
  // mode only — the search list has its own persistent hint line.
@@ -3165,7 +3188,7 @@ window.__ModuleLoader__.load({
3165
3188
  var upward = el.scrollTop < lastScrollTopRef.current - 2;
3166
3189
  if (upward) {
3167
3190
  if (hint === "more") setHint("");
3168
- if (hoverCard) hoverEnd();
3191
+ if (hoverCard) hoverEnd(true);
3169
3192
  }
3170
3193
  lastScrollTopRef.current = el.scrollTop;
3171
3194
  syncBackBtn(el); // reached the remembered place by hand? the button is done
@@ -6170,7 +6193,10 @@ window.__ModuleLoader__.load({
6170
6193
  // vanishing ON the divider line. `open` also drives it (fade + slide home) and
6171
6194
  // `edgeGone` keeps the element in the tree until that motion has played.
6172
6195
  var EDGE_W = 26;
6173
- var edgeShown = !open && handleShown && chatViewActive;
6196
+ // a narrow conversation column leaves no room for a handle floating over the text:
6197
+ // below the threshold it slides back into the divider (its usual motion), while the
6198
+ // droplet above the conversation stays put as the way in
6199
+ var edgeShown = !open && handleShown && chatViewActive && !narrowWindow;
6174
6200
  var edgeLineLeft = viewport ? viewport.left : 0;
6175
6201
  var edgeLineRight = viewport ? viewport.right + 52 : 60; // clear of the milestone rail
6176
6202
  var edgeEl = (!open || !edgeGone) ? react_jsx_runtime.jsx("div", {
@@ -6455,8 +6481,7 @@ window.__ModuleLoader__.load({
6455
6481
  ref: opts.pinned ? pinnedRef : undefined,
6456
6482
  onMouseEnter: opts.pinned ? undefined : function () {
6457
6483
  // the pointer reached the card: keep it open so its pin can be clicked
6458
- if (hoverCloseTimerRef.current) { clearTimeout(hoverCloseTimerRef.current); hoverCloseTimerRef.current = null; }
6459
- setHoverClosing(false);
6484
+ disarmHoverClose();
6460
6485
  },
6461
6486
  onMouseLeave: opts.pinned ? undefined : function () { hoverEnd(); },
6462
6487
  style: {
@@ -6474,9 +6499,10 @@ window.__ModuleLoader__.load({
6474
6499
  // above the panel and the curtain — it is a sibling of both in this
6475
6500
  // portal, and both sit below it in the layer band we claim
6476
6501
  zIndex: Z_HOVER + (opts.pinned ? 1 : 0),
6477
- // a fading card is inert: it must not swallow the click that dismissed it
6478
- // (and the pinned card is the only clickable one while it is up)
6479
- pointerEvents: opts.closing ? "none" : (opts.pinned ? "auto" : "none"),
6502
+ // a fading card is inert: it must not swallow the click that dismissed it.
6503
+ // While it is up the card IS clickable — it carries the pin, and the pointer
6504
+ // has to be able to get there from the row.
6505
+ pointerEvents: opts.closing ? "none" : "auto",
6480
6506
  userSelect: opts.pinned ? "text" : "none"
6481
6507
  },
6482
6508
  children: kids
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-quick-toc",
3
- "version": "0.8.0",
3
+ "version": "0.8.2",
4
4
  "description": "Conversation TOC for DeepSeek Harness (DSH): a whole-session, turn-grouped Markdown outline with hover previews, a level filter, a full-width curtain, jump-to-end buttons, title/full-text/cross-session search and a Chinese/English interface.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -43,7 +43,8 @@
43
43
  "0.1.7-alpha.2": "compatible",
44
44
  "0.1.7-rc.1": "compatible",
45
45
  "0.1.7-rc.2": "compatible",
46
- "0.2.0-rc.1": "compatible"
46
+ "0.2.0-rc.1": "compatible",
47
+ "0.2.0-rc.2": "compatible"
47
48
  }
48
49
  }
49
50
  },