dsh-conversation-navigator 0.2.7 → 0.2.9
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 +25 -5
- package/README.md +25 -5
- package/lib/client.js +39 -5
- package/package.json +2 -2
package/README.en.md
CHANGED
|
@@ -17,12 +17,11 @@ A **DeepSeek Harness (DSH) Web conversation navigator panel**: a turn-folded out
|
|
|
17
17
|
|
|
18
18
|
Browser-only (no host behavior), plain JavaScript, zero build step, zero npm dependencies (buttons/tooltips reuse the official primitives from the DSH kernel seed).
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-

|
|
20
|
+
| Dark mode | Light mode |
|
|
21
|
+
| :---: | :---: |
|
|
22
|
+
|  |  |
|
|
24
23
|
|
|
25
|
-
> Three forms: full, hidden, and minimal-left (minimal-right is shelved as of 0.2.6, code retained). The minimal strips collapse to the in-row indicator bars; hover expands the positioning panel. More screenshots in [assets/screenshots](./assets/screenshots).
|
|
24
|
+
> The conversation navigator in dark and light mode. Three forms: full, hidden, and minimal-left (minimal-right is shelved as of 0.2.6, code retained). The minimal strips collapse to the in-row indicator bars; hover expands the positioning panel. More screenshots in [assets/screenshots](./assets/screenshots).
|
|
26
25
|
|
|
27
26
|
## Features
|
|
28
27
|
|
|
@@ -96,6 +95,19 @@ Edit `lib/client.js` and restart `dsh web`. Docked state, dragged position, mini
|
|
|
96
95
|
- **Version-sensitive points**: `[data-chat-anchor-key]` / `[data-conversation-scroll]` are the current DOM anchor conventions of the DSH chat view (verified still present in official v0.1.2-rc.1); if they change after a DSH upgrade, only `findAnchor` / `computeActiveKey` in `lib/client.js` need adjusting
|
|
97
96
|
- No hard `timer` dependency: the client timer service is used for throttling when present, and degrades to unthrottled otherwise
|
|
98
97
|
|
|
98
|
+
## Host ↔ plugin version
|
|
99
|
+
|
|
100
|
+
Official v0.1.2-rc.1 made a breaking change to the conversation data layer (conversation nodes moved from the `session.chat` snapshot to the `uiConversation` chat target snapshot), so the plugin forks by host version:
|
|
101
|
+
|
|
102
|
+
| Host `dsh-client-ui-conversation` | Matching plugin version | npm tag |
|
|
103
|
+
|---|---|---|
|
|
104
|
+
| **≥ 0.1.2-rc.1** (has the `uiConversation` service) | **0.2.6 and later** (currently 0.2.9) | `latest` (default) |
|
|
105
|
+
| **≤ 0.1.1-rc.2** (no `uiConversation`, legacy `session.chat` snapshot) | **0.2.5 and earlier** | `legacy` |
|
|
106
|
+
|
|
107
|
+
- New hosts can install the latest normally (`dsh plugin --profile web add dsh-conversation-navigator`).
|
|
108
|
+
- Legacy hosts should pin the legacy tag: `npm i dsh-conversation-navigator@legacy` (= 0.2.5).
|
|
109
|
+
- From 0.2.6 the `peerDependencies` range is `>=0.1.2-rc.1 <0.2.0` (new host only); 0.2.5 and earlier declare no such range.
|
|
110
|
+
|
|
99
111
|
## Structure
|
|
100
112
|
|
|
101
113
|
```
|
|
@@ -108,6 +120,14 @@ cordis.patch.yml # bundle patch layer (inserts the plugin row)
|
|
|
108
120
|
example.patch.yml # patch example for manual installs
|
|
109
121
|
```
|
|
110
122
|
|
|
123
|
+
## Traffic
|
|
124
|
+
|
|
125
|
+

|
|
126
|
+
|
|
127
|
+
- Refreshed daily by GitHub Actions (top: GitHub unique visitors / unique cloners; bottom: npm daily downloads; orange dashed lines mark releases).
|
|
128
|
+
- Details: [traffic-report.md](./docs/traffic/traffic-report.md) | raw archive: [traffic-archive.json](./docs/traffic/traffic-archive.json) | docs & manual refresh: [docs/traffic](./docs/traffic/README.md)
|
|
129
|
+
- Why an archive: GitHub's traffic API only keeps a rolling 14-day window, and older data is lost forever — this repo merges every fetch into a durable, append-mostly daily series.
|
|
130
|
+
|
|
111
131
|
## License
|
|
112
132
|
|
|
113
133
|
MIT
|
package/README.md
CHANGED
|
@@ -17,12 +17,11 @@
|
|
|
17
17
|
|
|
18
18
|
纯浏览器插件(无宿主行为)、纯 JavaScript、零构建、零 npm 依赖(按钮/Tooltip 复用 DSH 内核 seed 的官方 primitives)。
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-

|
|
20
|
+
| 深色模式 | 浅色模式 |
|
|
21
|
+
| :---: | :---: |
|
|
22
|
+
|  |  |
|
|
24
23
|
|
|
25
|
-
>
|
|
24
|
+
> 深色 / 浅色模式下的会话导航面板。三种形态:显示轮次、隐藏轮次、极简·左(极简·右自 0.2.6 暂缓,代码保留;极简收起仅露行内指示条,悬停展开定位面板)。更多截图见 [assets/screenshots](./assets/screenshots)。
|
|
26
25
|
|
|
27
26
|
## 功能
|
|
28
27
|
|
|
@@ -93,6 +92,19 @@ dsh plugin --profile web add ./dsh-conversation-navigator-<version>.tgz
|
|
|
93
92
|
- **版本敏感点**:`[data-chat-anchor-key]` / `[data-conversation-scroll]` 是当前 DSH 聊天视图的 DOM 锚点约定(官方 v0.1.2-rc.1 中已验证仍在),DSH 升级后若锚点变化,只需调整 `lib/client.js` 中 `findAnchor` / `computeActiveKey` 两个函数
|
|
94
93
|
- 未声明 `timer` 硬依赖:客户端的 timer 服务存在则用于节流,不存在时自动退化为未节流模式
|
|
95
94
|
|
|
95
|
+
## 宿主版本 ↔ 插件版本
|
|
96
|
+
|
|
97
|
+
官方 v0.1.2-rc.1 对会话数据层做了一次爆破性更新(会话节点从 `session.chat` 快照迁移到 `uiConversation` 的 chat target 快照),因此插件按宿主版本分叉:
|
|
98
|
+
|
|
99
|
+
| 宿主 `dsh-client-ui-conversation` | 对应插件版本 | npm 标签 |
|
|
100
|
+
|---|---|---|
|
|
101
|
+
| **≥ 0.1.2-rc.1**(有 `uiConversation` 服务) | **0.2.6 及以后**(当前 0.2.9) | `latest`(默认) |
|
|
102
|
+
| **≤ 0.1.1-rc.2**(无 `uiConversation`,旧 `session.chat` 快照) | **0.2.5 及以前** | `legacy` |
|
|
103
|
+
|
|
104
|
+
- 新宿主直接安装最新版即可(`dsh plugin --profile web add dsh-conversation-navigator`)。
|
|
105
|
+
- 旧宿主请指定旧标签:`npm i dsh-conversation-navigator@legacy`(= 0.2.5)。
|
|
106
|
+
- 0.2.6 起 `peerDependencies` 声明为 `>=0.1.2-rc.1 <0.2.0`(仅新宿主);0.2.5 及以前不声明该范围。
|
|
107
|
+
|
|
96
108
|
## 目录结构
|
|
97
109
|
|
|
98
110
|
```
|
|
@@ -105,6 +117,14 @@ cordis.patch.yml # 组合包补丁层(插入插件行)
|
|
|
105
117
|
example.patch.yml # 手动安装时的补丁示例
|
|
106
118
|
```
|
|
107
119
|
|
|
120
|
+
## 流量
|
|
121
|
+
|
|
122
|
+

|
|
123
|
+
|
|
124
|
+
- 上图由 GitHub Actions 每日自动刷新(上半区 GitHub 独立访客/独立克隆者,下半区 npm 每日下载,橙色虚线为发版日)。
|
|
125
|
+
- 明细报告:[traffic-report.md](./docs/traffic/traffic-report.md)|原始归档:[traffic-archive.json](./docs/traffic/traffic-archive.json)|说明与本地刷新:[docs/traffic](./docs/traffic/README.md)
|
|
126
|
+
- 为什么需要归档:GitHub 流量 API 只保留最近 14 天,过期即永久丢失;本仓库把每次抓取合并留存,逐日序列只增不减。
|
|
127
|
+
|
|
108
128
|
## License
|
|
109
129
|
|
|
110
130
|
MIT
|
package/lib/client.js
CHANGED
|
@@ -96,6 +96,9 @@ window.__ModuleLoader__.load({
|
|
|
96
96
|
const CSS = `
|
|
97
97
|
.cnvnav-panel {
|
|
98
98
|
position: fixed; z-index: 9999; width: 288px;
|
|
99
|
+
/* 显式 border-box: 面板有 1px 边框, 若按默认 content-box, style.width(内容宽) 会与
|
|
100
|
+
offsetWidth/rect.width(含边框) 差 2px, 拖拽缩放的几何换算会因此逐帧漂移 */
|
|
101
|
+
box-sizing: border-box;
|
|
99
102
|
display: flex; flex-direction: column;
|
|
100
103
|
pointer-events: auto;
|
|
101
104
|
background: var(--dsw-alias-bg-overlay, #fff);
|
|
@@ -636,6 +639,17 @@ window.__ModuleLoader__.load({
|
|
|
636
639
|
count += 1;
|
|
637
640
|
}
|
|
638
641
|
for (const g of groups) {
|
|
642
|
+
/* 轮次组头必须是人类消息(user): 官方节点序里 system-prompt / turn-process
|
|
643
|
+
的 anchorSeq 可能早于 user 而排在前面, 直接把 items[0] 当轮头会把
|
|
644
|
+
"系统提示"错当轮次主体。把首个 user 稳定提到最前, headKey/标题/
|
|
645
|
+
步次(slice(1)) 才能都对准用户消息。 */
|
|
646
|
+
if (g.turn !== null) {
|
|
647
|
+
const ui = g.items.findIndex((it) => it.kind === "user");
|
|
648
|
+
if (ui > 0) {
|
|
649
|
+
const u = g.items.splice(ui, 1)[0];
|
|
650
|
+
g.items.unshift(u);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
639
653
|
const first = g.items[0];
|
|
640
654
|
if (g.turn === null) {
|
|
641
655
|
g.title = first.label;
|
|
@@ -792,6 +806,17 @@ window.__ModuleLoader__.load({
|
|
|
792
806
|
count += 1;
|
|
793
807
|
}
|
|
794
808
|
for (const g of groups) {
|
|
809
|
+
/* 轮次组头必须是人类消息(user): 官方节点序里 system-prompt / turn-process
|
|
810
|
+
的 anchorSeq 可能早于 user 而排在前面, 直接把 items[0] 当轮头会把
|
|
811
|
+
"系统提示"错当轮次主体。把首个 user 稳定提到最前, headKey/标题/
|
|
812
|
+
步次(slice(1)) 才能都对准用户消息。 */
|
|
813
|
+
if (g.turn !== null) {
|
|
814
|
+
const ui = g.items.findIndex((it) => it.kind === "user");
|
|
815
|
+
if (ui > 0) {
|
|
816
|
+
const u = g.items.splice(ui, 1)[0];
|
|
817
|
+
g.items.unshift(u);
|
|
818
|
+
}
|
|
819
|
+
}
|
|
795
820
|
const first = g.items[0];
|
|
796
821
|
if (g.turn === null) {
|
|
797
822
|
g.title = first.label;
|
|
@@ -1134,11 +1159,16 @@ window.__ModuleLoader__.load({
|
|
|
1134
1159
|
if (resizeStart !== null) return;
|
|
1135
1160
|
const el = panelEl;
|
|
1136
1161
|
if (el === null) return;
|
|
1162
|
+
/* 锚定拖动开始时的右边缘/上边缘: 之后每帧都基于它换算 left/高度上限。
|
|
1163
|
+
绝不能用实时 rect 反推(老实现如此), 否则「请求宽度 ≠ 实际渲染宽度」的
|
|
1164
|
+
差值会逐帧累积, 表现为任何方向的鼠标位移都把面板往右推。 */
|
|
1165
|
+
const rect = el.getBoundingClientRect();
|
|
1137
1166
|
resizeStart = {
|
|
1138
1167
|
startX: e.clientX, startY: e.clientY,
|
|
1139
1168
|
baseW: el.offsetWidth || 288,
|
|
1140
1169
|
baseH: el.offsetHeight || 200,
|
|
1141
|
-
|
|
1170
|
+
anchorRight: rect.right,
|
|
1171
|
+
anchorTop: rect.top,
|
|
1142
1172
|
el: el,
|
|
1143
1173
|
};
|
|
1144
1174
|
try { e.currentTarget.setPointerCapture(e.pointerId); } catch (err) { /* 忽略 */ }
|
|
@@ -1153,7 +1183,6 @@ window.__ModuleLoader__.load({
|
|
|
1153
1183
|
以拖拽起点为基准线性跟随鼠标(无漂移/无状态跳变):
|
|
1154
1184
|
拖小立即压缩出滚动, 拖大在内容充足时线性恢复更多行;
|
|
1155
1185
|
内容不足时面板保持内容高(拖动无感, 属预期)。 */
|
|
1156
|
-
const r = d.el.getBoundingClientRect();
|
|
1157
1186
|
const sp = document.querySelector("[data-conversation-scroll]");
|
|
1158
1187
|
/* 上限必须与 place() 各分支一致, 否则松手后会被 place 压回造成跳变:
|
|
1159
1188
|
docked/常规 = min(容器高-24, vh-40); 自由位置 = vh-顶-8 */
|
|
@@ -1161,14 +1190,15 @@ window.__ModuleLoader__.load({
|
|
|
1161
1190
|
const cap = Math.max(minPanelH(), Math.round(
|
|
1162
1191
|
state.docked && sr !== null
|
|
1163
1192
|
? Math.min(sr.height - 24, vh - 40)
|
|
1164
|
-
: vh -
|
|
1193
|
+
: vh - d.anchorTop - 8
|
|
1165
1194
|
));
|
|
1166
1195
|
const nw = Math.min(Math.max(240, d.baseW - dx), 560);
|
|
1167
1196
|
/* 目标上限 = 起点可见高 + 总位移, 线性且可逆 */
|
|
1168
1197
|
const nMaxH = Math.min(Math.max(minPanelH(), d.baseH + dy), cap);
|
|
1169
|
-
|
|
1198
|
+
/* 右边缘钉在起点位置(而不是实时 rect): 拖动过程中面板绝不平移 */
|
|
1199
|
+
const left = Math.max(8, Math.round(d.anchorRight - nw));
|
|
1170
1200
|
d.el.style.width = Math.round(nw) + "px";
|
|
1171
|
-
d.el.style.left =
|
|
1201
|
+
d.el.style.left = left + "px";
|
|
1172
1202
|
d.el.style.height = "";
|
|
1173
1203
|
d.el.style.maxHeight = Math.round(nMaxH) + "px";
|
|
1174
1204
|
}
|
|
@@ -1198,6 +1228,10 @@ window.__ModuleLoader__.load({
|
|
|
1198
1228
|
const panel = panelEl;
|
|
1199
1229
|
if (panel === null) return false;
|
|
1200
1230
|
if (dragMove !== null) return true;
|
|
1231
|
+
/* 缩放中同样不接管: place() 会按"持久化的旧宽高"重写 width/left/maxHeight,
|
|
1232
|
+
若在拖拽缩放过程中触发(400ms 复查 / ResizeObserver / window.resize),
|
|
1233
|
+
就会把用户正在拖的几何值顶掉。 */
|
|
1234
|
+
if (resizeStart !== null) return true;
|
|
1201
1235
|
const vw = document.documentElement.clientWidth || 1000;
|
|
1202
1236
|
const vh = document.documentElement.clientHeight || 800;
|
|
1203
1237
|
/* 新宿主 dock 右侧需让出官方 rail 的 28px 竖带(right: calc(12px - clearance) + width:28px),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-conversation-navigator",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.9",
|
|
4
4
|
"description": "DSH(DeepSeek Harness)会话导航插件:按轮折叠的对话大纲面板,支持节点点击跳转、滚动位置高亮与轨迹视图同款配色。",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dsh",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"node": ">=18"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
|
-
"@deepseek-ai/dsh-client-ui-conversation": ">=0.1.
|
|
36
|
+
"@deepseek-ai/dsh-client-ui-conversation": ">=0.1.2-rc.1 <0.2.0"
|
|
37
37
|
},
|
|
38
38
|
"dsh": {
|
|
39
39
|
"bundle": {
|