dsh-turn-navigator 0.1.0 → 0.4.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/CHANGELOG.md +43 -0
- package/README.md +70 -20
- package/README.zh.md +71 -21
- package/docs/turn-nav-rail.png +0 -0
- package/lib/client.js +795 -162
- package/package.json +8 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,48 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.4.0] - 2026-08-29
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **Rail display mode (Settings → General → Turn navigation)**: three-way choice between `DSH official` (the built-in rail), `DSH STN` (this plugin's rail — default), and `Hide all`. Registered into the official `settings.general.item` seat (root scope), styled like the built-in preference rows (EnterBehaviorRow pattern), persisted browser-locally (localStorage — the official `settingsScope` store needs a Host-registered namespace that an external client-only plugin has no seam to create).
|
|
8
|
+
- **Subtractive takeover of the official rail**: the official built-in TurnNavigator has no off-switch, so in `DSH STN` mode it is hidden with a container-scoped stylesheet override (`body.tn-hide-official [data-conversation-scroll] nav { display: none !important }` — our rail is fixed OUTSIDE the conversation scroll container, so the rule cannot match ours), and our rail takes over the right-edge center position. `Hide all` hides both.
|
|
9
|
+
- **Official-rail detection fix**: the old check matched `nav[aria-label*="轮次"/"Turn navigation"]` anywhere, which also matched OUR OWN rail (same localized label) — so the rail stayed nudged into the header zone even when the official rail was absent (e.g. 1-turn sessions). The check is now scoped to `[data-conversation-scroll]` and reads the COMPUTED display value, so the nudge follows reality: official visible → we nudge; official hidden by our override → we stay centered.
|
|
10
|
+
- **Brand name**: DSH Smoothly Turn Nav (DSH STN) — used in the README, settings row, and changelog.
|
|
11
|
+
|
|
12
|
+
# Changelog
|
|
13
|
+
|
|
14
|
+
## [0.3.0] - 2026-08-29
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **Full history restored on dsh 0.1.2+ (journal channel)**: the 0.2.0 refactor removed the browser→host `sessions.history` RPC, so the rail degraded to loaded-window turns. This release restores the full-history rail in the browser with **zero host changes and zero new dependencies**: the plugin pages the same persisted log the official window reads through the Typert Remote `session/page` endpoint (`ctx.remote.session` — the namespace is mounted by the base web assembly into `ctx.get('remote.session')`, read without adding to the cordis `inject` list because `ctx.get` is the inject-free store read; the traced `ctx.get('remote').session` path would hit the "without inject" gate). Every persisted turn (including turns far outside the window) is shown as plain data, paged incrementally, with no prepends into the conversation flow on open — the same performance story as 0.1.x, now purely client-side.
|
|
19
|
+
- **Official-store jump path**: window expansion for out-of-window jumps now goes through the official session store (`sessions.binding(id).session.loadOlder()`), with the authoritative `hasMore` from `binding(id).eventSource.getSnapshot().hasMore` as the loop terminator (no more DOM "Load earlier" button sniffing on 0.1.2+), and row polling instead of fixed sleeps so fast renders jump immediately. The "Load earlier" button path remains as a fallback on older hosts.
|
|
20
|
+
- **Journal readiness wait**: the official session binding is staged a moment after the conversation view mounts; the full-history fetch now waits (bounded, 15s) for the window's seq bounds instead of silently skipping, so the rail fills with all turns shortly after open.
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- History-channel priority: 0.1.2+ journal (`session/page`) → legacy `sessions.history` RPC → window-only turns (each layer degrades gracefully, including when `remote.session` is not yet mounted at boot — handles are resolved lazily and retried at render).
|
|
25
|
+
|
|
26
|
+
## [0.2.0] - 2026-08-29
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- **Adapted to dsh 0.1.2+ (ui-chat refactor)**: the conversation data model changed — `ConversationSnapshot` lost its `chat` field and the old `dsh-client-runtime` package was removed. The rail now reads turn data through the new `useChat` hook (ChatSnapshot, `navigation.items()`), falls back to the legacy `.chat`-wrapped snapshot on older dsh, and imports `ClientContext` from `@deepseek-ai/cordis` (with the `dsh-client-ui-renderer/client` merge for `ctx.slots`). This fixes the crash that hid the rail after upgrading.
|
|
31
|
+
- **Coexists with the official built-in TurnNavigator**: the official dsh rail (in-chat, always rendered, cannot be disabled) now overlaps-free — when it is present our rail nudges up into the header zone (`.tn-nudge`) instead of the scrollport center. Mirrored the official narrow-viewport hide (`@media max-width: 900px`).
|
|
32
|
+
- **Added follow-scroll active-turn highlight**: the capsule for the turn at the reading line is tinted (brand color) as you scroll — a capability the official rail has and we previously lacked.
|
|
33
|
+
- **History-as-data is window-scoped on 0.1.2+**: the browser→host `sessions.history` RPC (`connection.api`) was removed in the refactor, so the full-history read is unavailable in the browser on new dsh; the rail degrades to the loaded-window turns (same data as the official rail) and keeps its UI/UX (wave hover, scroll buttons, center-on-click, tooltip, jump feedback, follow highlight). Full-history support is a known follow-up (host-half route) if desired.
|
|
34
|
+
|
|
35
|
+
## [0.1.1] - 2026-08-19
|
|
36
|
+
|
|
37
|
+
### Changed
|
|
38
|
+
|
|
39
|
+
- **History-as-data architecture (fixes stalls on very long sessions)**: the rail's turn list is now read from the HOST through the browser→host `sessions.history` RPC — every persisted turn (including ones far outside the conversation window) is shown as plain data, paged incrementally, with **zero prepends into the conversation flow on open**. Previously the rail extended the flow window by auto-clicking "Load earlier", which re-renders the whole flow per page and stalled the UI on ~150-turn sessions. Now the flow window is only extended **on demand**: clicking a capsule for a turn already in the window scrolls directly; for a turn outside the window, the rail extends the window page by page (respecting the paging button's in-flight state) until the target turn is in the window, then scrolls and highlights it.
|
|
40
|
+
- **Immediate jump feedback**: clicking an out-of-window capsule now shows instant feedback — the clicked capsule pulses and a "Locating turn N…" bubble appears beside it (in the DSH tooltip visual style) for the whole duration of the on-demand window extension; on failure a brief "Could not locate turn N" notice shows instead. No more silent waits.
|
|
41
|
+
- **Oldest-turn jumps load to the true start**: jumping to the oldest turn now extends the window until there is no more history to load (hasMore false) — previously the window could include the target's boundary while earlier events were still pending, so the jump landed before the true first turn with a "Load earlier" button remaining. Readiness is judged by the target row being actually rendered in the DOM, not just the turn being listed in the window.
|
|
42
|
+
- **Bilingual README switch**: README (English default) and README.zh.md now link to each other.
|
|
43
|
+
- **Layer stacking**: the rail's z-index is now 10 — above the conversation flow content (max 8) but below full-screen overlays like the kanban board plugin (z-index 50) — matching the header's "Session log" button tier, so an open full-screen page always paints over the rail.
|
|
44
|
+
- **README screenshot**: added `docs/turn-nav-rail.png` to the bilingual README (English default) as marketing, shipped in the npm package.
|
|
45
|
+
|
|
3
46
|
## [0.1.0] - 2026-08-19
|
|
4
47
|
|
|
5
48
|
### Added
|
package/README.md
CHANGED
|
@@ -1,15 +1,54 @@
|
|
|
1
|
-
#
|
|
1
|
+
# DSH Smoothly Turn Nav (DSH STN)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**English · [简体中文](README.zh.md)**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**Every turn of your conversation, one glance away.**
|
|
6
|
+
|
|
7
|
+
DSH Smoothly Turn Nav (**DSH STN**) is an external plugin for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (dsh) that puts a **piano-key turn rail** on the right edge of every conversation — a vertical column of tiny capsules, one per turn. It gives you a full minimap of the conversation: **every turn ever made** (not just the ones currently loaded), hover previews, click-to-jump to any turn's start, and follow-scroll highlighting. It can also **replace the official built-in turn rail**, which has no off-switch of its own.
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
## Why
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
13
|
+
In the default DSH web UI, the official turn rail only shows the **currently loaded window** of turns — in a long conversation, most turns are invisible until you scroll and load more. DSH STN solves this:
|
|
14
|
+
|
|
15
|
+
- **Full history at a glance** — every persisted turn is shown as plain data, including turns far outside the loaded window. No scrolling, no loading, no waiting.
|
|
16
|
+
- **Hover to preview** — the capsule glows with the theme color and widens in a wave ripple; a DSH-style tooltip shows the turn's number, time, and user-message summary.
|
|
17
|
+
- **Click to jump anywhere** — jumps to any turn's start, even turns not yet loaded (the window is extended on demand with instant feedback).
|
|
18
|
+
- **Know where you are** — the current turn is highlighted as you scroll.
|
|
19
|
+
|
|
20
|
+
## Features
|
|
21
|
+
|
|
22
|
+
| | |
|
|
23
|
+
|---|---|
|
|
24
|
+
| 🗺️ **Full-history minimap** | All turns visible immediately — read from the persisted session log as data, **zero prepends** into the conversation flow on open (long sessions stay responsive) |
|
|
25
|
+
| 🎹 **Piano-key design** | One capsule per turn, ~3px tall, right-aligned on the right edge; auto-sizing (up to 30vh) with an internal hidden scrollbar |
|
|
26
|
+
| 🌊 **Wave hover** | Hovered capsule glows with the theme color and widens 150% leftward; its two neighbours widen 125% — a ripple across the rail |
|
|
27
|
+
| 💬 **Rich tooltip** | Turn number, timestamp, and full user-message summary, always fully inside the viewport |
|
|
28
|
+
| 🎯 **Jump to any turn** | Precise `scrollTop` targeting (no `scrollIntoView` fights); out-of-window jumps extend the window on demand with a "Locating turn N…" pulse + bubble; the oldest-turn jump loads to the **true first turn** (`hasMore = false`) |
|
|
29
|
+
| 👁️ **Follow-scroll highlight** | The capsule of the turn at the reading line is tinted as you scroll |
|
|
30
|
+
| ⬆️⬇️ **Scroll buttons** | Click or hover-hold to scroll the rail; greyed out when there is nothing to scroll |
|
|
31
|
+
| 🎛️ **Rail mode switch** | Settings → General → *Turn navigation*: `DSH official` / `DSH STN` (default) / `Hide all` — persisted across reloads |
|
|
32
|
+
| 🔌 **Pure external plugin** | No DSH source code modified; no host changes; no new dependencies; read-only DOM access |
|
|
33
|
+
|
|
34
|
+
## vs. the official DSH turn rail
|
|
35
|
+
|
|
36
|
+
The official built-in `TurnNavigator` has **no off-switch** and is always rendered in the chat view. DSH STN is the upgrade:
|
|
37
|
+
|
|
38
|
+
| Capability | DSH official rail | DSH STN |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| Turns shown | Only the **loaded window** | **Every persisted turn** (full history) |
|
|
41
|
+
| Jump to a turn outside the window | ❌ Not visible, not reachable | ✅ On-demand window extension + feedback |
|
|
42
|
+
| Long-session open performance | Window rendering | **Zero prepend** — no flow re-render, no stall |
|
|
43
|
+
| Follow-scroll highlight | ✅ | ✅ |
|
|
44
|
+
| Hover preview | Prompt + response (≤160 chars each) | Number + time + full summary tooltip |
|
|
45
|
+
| Wave ripple animation | ❌ | ✅ |
|
|
46
|
+
| Scroll buttons (click / hover-hold) | ❌ | ✅ |
|
|
47
|
+
| Rail height | Fixed band, compressed proportionally (≤420px) | Auto-sized (≤30vh), internal scroll |
|
|
48
|
+
| Narrow viewport (<900px) | Auto-hidden | Auto-hidden (mirrors official) |
|
|
49
|
+
| Hide / switch rail | ❌ No off-switch | ✅ Settings → General → 3 modes |
|
|
50
|
+
| Keyboard reachable | ✅ (focus ring) | ✅ (buttons) |
|
|
51
|
+
| Source | Built-in, cannot be disabled | External plugin, **can be replaced/disabled** |
|
|
13
52
|
|
|
14
53
|
## Installation
|
|
15
54
|
|
|
@@ -25,30 +64,41 @@ dsh web
|
|
|
25
64
|
|
|
26
65
|
## Usage
|
|
27
66
|
|
|
67
|
+
0. **Choose which rail to show** (Settings → General → **Turn navigation**): `DSH official` (the built-in rail), `DSH STN` (this plugin's rail — **default**), or `Hide all`. The official rail has no off-switch, so choosing DSH STN hides it with a stylesheet override and our rail takes over the right-edge center position. The choice persists across reloads.
|
|
28
68
|
1. Open any conversation with at least one completed turn.
|
|
29
|
-
2. A vertical rail of grey capsules appears on the right edge
|
|
30
|
-
3. Hover a capsule
|
|
31
|
-
4. Click a capsule to jump to that turn's start
|
|
32
|
-
5.
|
|
69
|
+
2. A vertical rail of grey capsules appears on the right edge (one per turn). It **auto-sizes** — short conversations get a short rail, long ones hit the 30vh cap and scroll internally (hidden scrollbar, no layout jitter).
|
|
70
|
+
3. **Hover** a capsule: it glows, widens in a wave, and shows the turn's index, timestamp, and summary in a tooltip to the left of the rail.
|
|
71
|
+
4. **Click** a capsule to jump to that turn's start. Out-of-window turns pulse the capsule and show a "Locating turn N…" bubble while the window is extended on demand; the target row is highlighted on arrival. The activated capsule centers in the rail (unless it is the first or last turn).
|
|
72
|
+
5. **Scroll** with the mouse wheel, the up/down buttons, or hover-hold on the buttons.
|
|
33
73
|
|
|
34
74
|
## How it works
|
|
35
75
|
|
|
36
|
-
The plugin registers **
|
|
76
|
+
The plugin registers **two additive slots** — **no DSH source code is modified**:
|
|
37
77
|
|
|
38
78
|
| Slot | Scope | Role |
|
|
39
79
|
|------|-------|------|
|
|
40
|
-
| `conversation.session.header.utilities` | session | The floating turn rail
|
|
80
|
+
| `conversation.session.header.utilities` | session | The floating turn rail (renders `position: fixed`; reads the live chat snapshot via the framework `useChat`/`useSession` kit) |
|
|
81
|
+
| `settings.general.item` | root | The *Turn navigation* mode switch in Settings → General |
|
|
41
82
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
- **
|
|
45
|
-
- **
|
|
46
|
-
- **
|
|
83
|
+
- **Full history as data**: on dsh 0.1.2+ the rail pages the same persisted log the official window reads, through the Typert Remote `session/page` channel (`ctx.remote.session` — mounted by the base web assembly; **no host changes, no new dependencies**). On older dsh it uses the `sessions.history` RPC. Every turn is derived from raw `turn/start` / `user/message` / `turn/end` events as plain data.
|
|
84
|
+
- **On-demand jumps**: clicking a turn already in the window scrolls directly; for a turn outside it, the rail extends the window page by page through the official session store (`loadOlder`, with the authoritative `hasMore` as the loop terminator) until the target is in view — the only path that touches the flow, and it runs only when you click.
|
|
85
|
+
- **Precise scrolling**: the rail locates the turn's first chat-node key, finds its DOM row via `data-chat-anchor-key`, and sets the scrollport's `scrollTop` directly (more predictable than `scrollIntoView`).
|
|
86
|
+
- **Replacing the official rail**: the official rail lives inside the conversation scroll container; a container-scoped stylesheet rule (driven by the mode switch) hides it, and the rail takes over its right-edge center position. If a future dsh changes that structure, the worst case is the official rail reappearing (side by side) — never a crash.
|
|
87
|
+
- **Read-only**: the plugin never writes to DSH state, never sends data anywhere, and only reads the DOM for targeting.
|
|
47
88
|
|
|
48
89
|
## Compatibility
|
|
49
90
|
|
|
50
91
|
- DeepSeek Harness (dsh) with the web client (`dsh web`).
|
|
51
|
-
- Requires the `conversation.session.header.utilities` slot
|
|
92
|
+
- Requires the `conversation.session.header.utilities` and `settings.general.item` slot declarations (present in current DSH).
|
|
93
|
+
- Default `DSH STN` mode hides the official rail (stylesheet override) and centers our rail in its place; `DSH official` mode shows the built-in rail instead; `Hide all` hides both. Both rails auto-hide below 900px width.
|
|
94
|
+
- Coexists with full-screen plugin pages (e.g. the kanban board): the rail sits below their overlay layer.
|
|
95
|
+
|
|
96
|
+
## Development
|
|
97
|
+
|
|
98
|
+
- `pnpm typecheck` / `pnpm test` — TypeScript check (tsdown does not typecheck).
|
|
99
|
+
- `pnpm bundle` — build the module-table client bundle into `lib/`.
|
|
100
|
+
- `scripts/verify-*.mjs` — Playwright acceptance scripts against a live `dsh web` (rail, full-history journal, mode switch, jump, feedback, overlay, sizing, UI).
|
|
101
|
+
- `pnpm release:check` — release gates (version, tag, tree, build, registry).
|
|
52
102
|
|
|
53
103
|
## License
|
|
54
104
|
|
package/README.zh.md
CHANGED
|
@@ -1,15 +1,54 @@
|
|
|
1
|
-
#
|
|
1
|
+
# DSH Smoothly Turn Nav(DSH STN)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**[English](README.md) · 简体中文**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**整场会话,一眼纵览。**
|
|
6
|
+
|
|
7
|
+
DSH Smoothly Turn Nav(**DSH STN**)是 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(dsh)的外部插件,在每条会话右侧放一条**钢琴键式轮次胶囊条**——竖向一列小胶囊,一轮一个。它是整场会话的迷你地图:**全部历史轮次一目了然**(不只是当前已加载的窗口),悬停预览、点击跳转到任意轮次起点、滚动跟随高亮。它还可以**取代官方内置轮次胶囊条**(官方没有自己的关闭开关)。
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
## 为什么需要
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
+
DSH Web UI 的官方轮次胶囊条只显示**当前已加载窗口内**的轮次——长会话里,大部分轮次要滚动加载后才可见。DSH STN 解决这个问题:
|
|
14
|
+
|
|
15
|
+
- **全量历史一眼可见**——所有持久化轮次以纯数据呈现,包括远在已加载窗口之外的轮次。不滚动、不加载、不等待。
|
|
16
|
+
- **悬停即预览**——胶囊以主题色亮起并泛起波浪涟漪;DSH 风格 Tooltip 展示该轮序号、时间与用户消息摘要。
|
|
17
|
+
- **点击跳转任意轮**——包括尚未加载的轮次(按需扩展窗口,带即时反馈)。
|
|
18
|
+
- **随时知道自己在哪**——滚动时当前轮次高亮。
|
|
19
|
+
|
|
20
|
+
## 特性
|
|
21
|
+
|
|
22
|
+
| | |
|
|
23
|
+
|---|---|
|
|
24
|
+
| 🗺️ **全量历史迷你地图** | 所有轮次立即可见——从持久化会话日志以数据读取,**打开会话零 prepend**(长会话保持流畅) |
|
|
25
|
+
| 🎹 **钢琴键设计** | 每轮一个约 3px 高的胶囊,右缘右对齐;长度自适应(上限 30vh),超出后内部滚动(滚动条隐藏) |
|
|
26
|
+
| 🌊 **波浪悬停** | 悬停的胶囊以主题色亮起并向左加宽 150%,相邻两个加宽 125%——滑过时如波浪起伏 |
|
|
27
|
+
| 💬 **丰富 Tooltip** | 轮次序号、时间戳、完整用户消息摘要,始终完整显示在视口内 |
|
|
28
|
+
| 🎯 **跳转任意轮** | 精确 `scrollTop` 定位(不与 `scrollIntoView` 打架);窗口外跳转按需扩展窗口并显示"正在定位第 N 轮…"脉冲+气泡;最老轮次跳转加载到**真正第一轮**(`hasMore = false`) |
|
|
29
|
+
| 👁️ **滚动跟随高亮** | 阅读线所在轮次的胶囊随滚动点亮 |
|
|
30
|
+
| ⬆️⬇️ **滚动按钮** | 点击或悬停持续滚动;无可滚动内容时置灰 |
|
|
31
|
+
| 🎛️ **胶囊条模式开关** | 设置 → 通用 → *轮次导航*:`DSH 官方` / `DSH STN`(默认)/ `全部隐藏`——跨刷新持久保存 |
|
|
32
|
+
| 🔌 **纯外部插件** | 不改 DSH 源码;零宿主改动;零新增依赖;仅只读 DOM |
|
|
33
|
+
|
|
34
|
+
## 与官方 DSH 轮次胶囊条对比
|
|
35
|
+
|
|
36
|
+
官方内置 `TurnNavigator` **没有关闭开关**,始终渲染在会话视图里。DSH STN 是它的升级版:
|
|
37
|
+
|
|
38
|
+
| 能力 | DSH 官方胶囊条 | DSH STN |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| 显示的轮次 | 仅**已加载窗口** | **全部持久化轮次**(全量历史) |
|
|
41
|
+
| 跳转窗口外轮次 | ❌ 看不到也跳不了 | ✅ 按需扩展窗口 + 即时反馈 |
|
|
42
|
+
| 长会话打开性能 | 窗口渲染 | **零 prepend**——不重渲染会话流、不卡顿 |
|
|
43
|
+
| 滚动跟随高亮 | ✅ | ✅ |
|
|
44
|
+
| 悬停预览 | prompt + response(各 ≤160 字符) | 序号 + 时间 + 完整摘要 Tooltip |
|
|
45
|
+
| 波浪涟漪动画 | ❌ | ✅ |
|
|
46
|
+
| 滚动按钮(点击 / 悬停持续) | ❌ | ✅ |
|
|
47
|
+
| 胶囊条高度 | 固定区域按比例压缩(≤420px) | 自适应(≤30vh)+ 内部滚动 |
|
|
48
|
+
| 窄窗口(<900px) | 自动隐藏 | 自动隐藏(与官方对齐) |
|
|
49
|
+
| 隐藏 / 切换胶囊条 | ❌ 无开关 | ✅ 设置 → 通用 → 三档 |
|
|
50
|
+
| 键盘可达 | ✅(焦点环) | ✅(按钮) |
|
|
51
|
+
| 来源 | 内置、无法关闭 | 外部插件,**可替换 / 可关闭** |
|
|
13
52
|
|
|
14
53
|
## 安装
|
|
15
54
|
|
|
@@ -25,30 +64,41 @@ dsh web
|
|
|
25
64
|
|
|
26
65
|
## 使用
|
|
27
66
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
67
|
+
0. **选择显示哪个胶囊条**(设置 → 通用 → **轮次导航**):`DSH 官方`(内置 rail)、`DSH STN`(本插件 rail——**默认**)、或`全部隐藏`。官方 rail 没有关闭开关,选择 DSH STN 时以样式覆盖将其隐藏,我们的 rail 接管右缘居中位置。选择会跨刷新持久保存。
|
|
68
|
+
1. 打开任意包含至少一轮已完成轮次的会话。
|
|
69
|
+
2. 会话右侧出现一条竖向灰色胶囊列(每轮一个)。胶囊条**长度自适应**:轮次少则短,轮次多则达 30vh 上限后内部滚动(滚动条隐藏,无布局抖动)。
|
|
70
|
+
3. **悬停**某个胶囊:它以主题色亮起并泛起波浪、向左加宽,胶囊条左侧弹出 Tooltip(序号、时间、摘要),始终完整在视口内。
|
|
71
|
+
4. **点击**某个胶囊:会话滚动到该轮起点并短暂高亮目标行;窗口外轮次会先脉冲闪烁 + 弹出"正在定位第 N 轮…"气泡,按需扩展窗口后定位。被点击的胶囊自动滚动到胶囊条中央(首尾两条除外)。
|
|
72
|
+
5. **滚动**:滚轮、上下按钮、或按住按钮持续滚动。
|
|
33
73
|
|
|
34
74
|
## 原理
|
|
35
75
|
|
|
36
|
-
|
|
76
|
+
插件注册**两个加法 slot**——**不修改 DSH 源码**:
|
|
37
77
|
|
|
38
78
|
| Slot | 作用域 | 职责 |
|
|
39
79
|
|------|--------|------|
|
|
40
|
-
| `conversation.session.header.utilities` | session |
|
|
80
|
+
| `conversation.session.header.utilities` | session | 悬浮轮次胶囊条(`position: fixed`;通过框架 `useChat`/`useSession` kit 读取实时会话快照) |
|
|
81
|
+
| `settings.general.item` | root | 设置 → 通用 的 *轮次导航* 模式开关 |
|
|
41
82
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
-
|
|
83
|
+
- **全量历史即数据**:dsh 0.1.2+ 上,胶囊条通过 Typert Remote `session/page` 通道分页读取与官方窗口同一条持久化日志(`ctx.remote.session`——由基础 web 装配挂载;**零宿主改动、零新增依赖**);旧版 dsh 走 `sessions.history` RPC。每轮从 `turn/start` / `user/message` / `turn/end` 原始事件派生为纯数据。
|
|
84
|
+
- **按需跳转**:点击窗口内轮次直接滚动;窗口外轮次通过官方会话 store 的 `loadOlder()` 逐页扩展窗口(以权威 `hasMore` 为终止条件)直到目标进入视图——这是唯一触碰会话流的路径,且只在点击时发生。
|
|
85
|
+
- **精确定位**:取该轮第一个 chat-node key,通过 `data-chat-anchor-key` 找到 DOM 行,直接设置滚动容器 `scrollTop`(比 `scrollIntoView` 更可控)。
|
|
86
|
+
- **取代官方胶囊条**:官方 rail 位于会话滚动容器内;模式开关驱动的容器限定样式规则将其隐藏,我们的 rail 接管右缘居中位置。若未来 dsh 改变该结构,最坏情况是官方 rail 重新出现(并存)——绝不会崩溃。
|
|
87
|
+
- **只读**:插件从不写入 DSH 状态、从不外发数据,仅读取 DOM 用于定位。
|
|
47
88
|
|
|
48
89
|
## 兼容性
|
|
49
90
|
|
|
50
91
|
- DeepSeek Harness (dsh) Web 客户端(`dsh web`)。
|
|
51
|
-
- 需要 `conversation.session.header.utilities` slot 声明(当前 DSH 已包含)。
|
|
92
|
+
- 需要 `conversation.session.header.utilities` 与 `settings.general.item` slot 声明(当前 DSH 已包含)。
|
|
93
|
+
- 默认 `DSH STN` 模式以样式覆盖隐藏官方 rail,我们的 rail 居中接管;`DSH 官方` 模式显示内置 rail;`全部隐藏` 两者皆隐。900px 以下都自动隐藏。
|
|
94
|
+
- 与全屏插件页面(如看板)共存:胶囊条层级位于全屏 overlay 之下。
|
|
95
|
+
|
|
96
|
+
## 开发
|
|
97
|
+
|
|
98
|
+
- `pnpm typecheck` / `pnpm test` — TypeScript 检查(tsdown 只转译不检查)。
|
|
99
|
+
- `pnpm bundle` — 构建模块表 client bundle 到 `lib/`。
|
|
100
|
+
- `scripts/verify-*.mjs` — 针对真实 `dsh web` 的 Playwright 验收脚本(rail、全量历史 journal、模式开关、跳转、反馈、overlay、尺寸、UI)。
|
|
101
|
+
- `pnpm release:check` — 发布门禁(版本、tag、工作树、构建、registry)。
|
|
52
102
|
|
|
53
103
|
## 许可证
|
|
54
104
|
|
|
Binary file
|