@khorsheed/dsh-message-timeline 0.2.3 → 0.2.5

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 CHANGED
@@ -1,5 +1,19 @@
1
1
  # 变更记录
2
2
 
3
+ ## 0.2.5(2026-10-22)
4
+
5
+ - **整会话一次列出,首条消息即刻可达**:列表改读宿主 `turnOutline` 投影(每轮一条:轮次号、`turn/start` 序号、50 字首条预览),与已加载窗口合并——不再靠逐页翻历史才能看到更早消息。未加载轮次的行点击后经会话 jump loader(`ISession.loadThrough`)回翻历史再落位;行物化即落位,翻页停滞或轮次不可达时落到其后最近可见行。
6
+ - **静止态对比度调整**:所有行统一压淡灰刻度(不再区分已加载/未加载),只有当前阅读位置为蓝色加长刻度加粗行文字(无选中时默认最新一条);回翻中的行以刻度脉动提示。
7
+ - **无文本预览的消息保留展示**(标记「无文本预览」),不再过滤;**修复自动轮次点击无反应**:重启恢复、定时任务等轮次在聊天视图渲染为 turn-trigger 卡片而非 user 行,原落位只找 user 行导致永远落不到。落位改为官方同款 `user ?? loaded[0]`:优先该轮首个 user 行,没有则落该轮第一个可见节点(触发卡片、图片气泡均可达)。
8
+ - **自动轮次成为一等行,选中不再跑偏**:turn-trigger 纳入时间轴行 kind——已加载时直接显示触发正文,未加载时标记「第 N 轮」;阅读位置锚点也认触发卡片,跳转后选中保持在该轮,不再跳到下一条用户消息。图片/附件消息分别标记「图片消息」「附件消息」。
9
+ - 装配未挂载 turn-outline 单元时退回原窗口分页行为(打开预取 + 面板滚顶翻页),`initialPages` 只作用于该兜底路径。
10
+ - 注入面变化:`jumpTo` 现在返回是否命中(供落位重试),新增 `loadThrough`。
11
+ - **适配宿主 0.2.1 线**:`@deepseek-ai/dsh-*` peer 区间追加 `^0.2.1-rc.1`(`^0.2.0-rc.1` 在 npm/pnpm 严格解析下不覆盖 0.2.1 预发布三元组);宿主 0.2.1 移除 invariants 体系,随包 invariant 伴生退役、兼容判定改由 package.json `engines.dsh` 声明;`dsh.compat.verifiedHost` 前移至 `0.2.1-rc.1`(全量构建+测试在该树通过,无其它表面变化)。
12
+
13
+ ## 0.2.4(2026-09-30)
14
+
15
+ 无功能变更。加宽 `@deepseek-ai/dsh-*` peer 区间以覆盖宿主 0.2.0(0.2.0 的兼容闸会禁用 peer 区间不覆盖宿主版本的已装插件)。
16
+
3
17
  ## 0.2.3(2026-09-27)
4
18
 
5
19
  无功能变更。随宿主 0.1.7-rc.2 基线发布波重发:全量构建+测试在 rc.2 基线通过(rc.1→rc.2 无触及本包的宿主变更)。
package/README.en.md CHANGED
@@ -6,18 +6,19 @@ Every message you sent in a long conversation — visible at a glance, one click
6
6
 
7
7
  Once a session gets long, finding that requirement you mentioned three messages ago means scrolling up forever. This plugin parks a timeline on the chat's left edge: one row per message you sent, with a one-line preview. At rest it's just a strip of dimmed ticks that stays out of the way; hover to expand it, and clicking a row scrolls the transcript straight to that message. It only reads the session and never sends anything — the model doesn't notice it at all.
8
8
 
9
- <img src="https://raw.githubusercontent.com/Khorsheed/dsh-web-basic/main/docs/screenshots/message-timeline1.png" width="640" alt="the expanded message timeline on the chat's left edge: one row per user message, click a row to jump to it">
9
+ <img src="https://raw.githubusercontent.com/Khorsheed/dsh-basic/main/docs/screenshots/message-timeline1.png" width="640" alt="the expanded message timeline on the chat's left edge: one row per user message, click a row to jump to it">
10
10
 
11
11
  ## Features
12
12
 
13
- - **One row per user message** — tick plus ellipsized one-line preview; steering messages count too (configurable off), and message-tools edited/restored bubbles keep a row. Withdrawn originals are not listed (their transcript row is hidden, so a click could never reach them).
14
- - **Ambient rest state** — only dimmed ticks show until you hover the strip or focus the list.
15
- - **Reading position tracking** — the current position's tick stays lit blue, anchoring to the user message a long answer is replying to.
16
- - **Click to jump** — a row scrolls the transcript to that message; the list follows the reading position.
17
- - **Long-history friendly** — a short list centers vertically; a long one scrolls and pages older history at its top, its bottom-most row flush with the chat input box; goal/todo dock cards never push the timeline up.
13
+ - **One row per user message, the whole session listed from the first one** — tick plus ellipsized one-line preview; the host `turnOutline` projection names every started turn directly, no paging required. Clicking a not-yet-loaded older message pages history back to that turn before landing (its tick pulses while paging). Steering messages count too (configurable off), and message-tools edited/restored bubbles keep a row. Withdrawn originals are not listed (their transcript row is hidden, so a click could never reach them).
14
+ - **Textless rows stay listed and jumpable** — automated turns (restart recovery, scheduled jobs) show their trigger card's text once loaded, and fall back to a "Turn N" label while unloaded; image/attachment-only inputs are labelled "Image message" / "Attachment message". After jumping to an automated turn, the selection stays on that turn instead of moving to the next user message.
15
+ - **Ambient rest state** — only dimmed grey ticks show until you hover the strip or focus the list.
16
+ - **Reading position tracking** — the current position's tick stays blue and lengthened with bold text (defaulting to the latest message while nothing is selected); every other row rests grey. A long answer anchors the lit tick to the user message it replies to.
17
+ - **Click to jump** — a loaded row scrolls the transcript straight to it; an outline row goes through the session's jump loader and lands on the freshly loaded message.
18
+ - **Long-history friendly** — a short list centers vertically; a long one scrolls, its bottom-most row flush with the chat input box; goal/todo dock cards never push the timeline up. Assemblies without the turn-outline unit fall back to window paging: a few pages prefetch on open, and older history loads when the panel is scrolled to its top.
18
19
  - **Never covers the message flow** — the panel's width is capped by the scrollport's left gutter; a gutter too small for the minimum width hides it rather than overlapping the transcript.
19
20
 
20
- <img src="https://raw.githubusercontent.com/Khorsheed/dsh-web-basic/main/docs/screenshots/message-timeline2.png" width="640" alt="the timeline at rest: a strip of dimmed ticks that stays out of the way, expanding on hover">
21
+ <img src="https://raw.githubusercontent.com/Khorsheed/dsh-basic/main/docs/screenshots/message-timeline2.png" width="640" alt="the timeline at rest: a strip of dimmed ticks that stays out of the way, expanding on hover">
21
22
 
22
23
  ## Install
23
24
 
@@ -38,12 +39,13 @@ dsh plugin --profile web remove @khorsheed/dsh-message-timeline
38
39
  | `enabled` | `true` | Master switch; false hides the panel entirely. |
39
40
  | `includeSteering` | `true` | Count steering messages (user text admitted mid-turn) as rows. |
40
41
  | `panelWidth` | `360` | Panel width in px (clamped 120–640); shrinks to fit a narrow column, hides entirely when the gutter is too small. |
41
- | `initialPages` | `5` | History pages (50 events each) prefetched on open; older pages load when the panel is scrolled to its top (clamped 1–20). |
42
+ | `initialPages` | `5` | Window-paging fallback only: history pages (50 events each) prefetched on open (clamped 1–20). When the host serves the turnOutline projection the list starts whole and this does nothing. |
42
43
 
43
44
  ## Compatibility
44
45
 
45
46
  - npm release line (`@deepseek-ai/dsh@0.1.2-rc.1`): ✅ full — baseline moved to the 0.1.2-rc.1 API surface (single-arm 0.1.2 API consumption; the 0.1.1-rc.2 runtime arm is retired), full build+test green; minHost moves up to 0.1.2-rc.1 — older hosts stay on the previous release line.
46
- - source line (deepseek-harness master): ✅ (verifiedHost: 0.1.2-rc.1)
47
+ - source line (deepseek-harness master): ✅ (verifiedHost: 0.2.1-rc.1) — host-021 wave: full build+test green against the 0.2.1-rc.1 tree, no other surface changes.
48
+ - Degraded item: the whole-session list relies on the host `turnOutline` projection (`@deepseek-ai/dsh-session-turn-outline`, mounted by the official web bundle since 0.1.2-alpha.3 — below the minHost floor). An assembly without the unit falls back to window paging: older history loads page by page, fully functional, but the first message appears only once paged in.
47
49
 
48
50
  **Version line mapping**: 0.2.0 and up support host `0.1.2-rc.1` and later; hosts on `0.1.0-rc.6` ~ `0.1.1-rc.2` stay on the 0.1.x release line (last release `0.1.0`).
49
51
 
@@ -52,7 +54,7 @@ dsh plugin --profile web remove @khorsheed/dsh-message-timeline
52
54
  - **DOM probe coupling** — the panel targets official row attributes and the `[data-conversation-scroll]` scrollport; if the official DOM changes, it hides itself (one `console.warn`) until the probe is updated.
53
55
  - **Best-effort width fallback** — while the message-flow probe is unanswered, the panel renders at a capped fraction of the scrollport instead of hiding, so it may overlap the flow until the probe recovers; with a healthy probe the width never crosses the flow's left edge.
54
56
  - **Single rendered session** — rows and jumps address only the currently rendered conversation.
55
- - **Loaded history only** — rows cover materialized nodes; older messages arrive one page at a time when the panel is scrolled to its top.
57
+ - **The outline is turn-grained** — the projection keeps only each turn's first-prompt preview: steering rows appear once their turn pages into the window; a turn whose first message was withdrawn stays listed per the outline (matching the official turn rail), and confirming it lands on the turn's nearest visible row.
56
58
  - **No full index view yet** — a searchable message-index tab is planned.
57
59
 
58
60
  ## How it works
@@ -65,14 +67,16 @@ The plugin is purely additive and modifies no official code.
65
67
  - `src/client/index.ts` — plugin body (`apply`/`inject`)
66
68
  - `src/client/rail-tracker.ts` — the only DOM the plugin touches: read-only probes, the reading-position resolution, plus the jump's scroll write
67
69
  - `src/client/TimelineRail.tsx` — the panel component
70
+ - `src/client/outline.ts` — the `turnOutline` wire narrow (absent or damaged values both read as "capability absent")
71
+ - `src/client/rows.ts` — the merge of loaded-window rows with outline rows (single interleaving pass, transcript-ordered)
68
72
  - `src/client/timeline-kinds.ts` — the single source of truth for which node kinds are rows and which carry a hidden span
69
73
  - `src/client/hidden-spans.ts` — folds the message-tools withdraw/edit spans so covered originals are dropped as dead rows
70
74
  - `src/client/preview.ts` — message content to one-line preview text
71
75
  - `src/index.ts` — empty host `apply`, anchors the plugin into the host Loader
72
76
 
73
- **Mount & data** — one entry in the official `conversation.session.header.utilities` slot anchors the plugin into the session scope; the panel renders through a body portal with fixed geometry measured from the official scrollport. Rows derive from the framework `useSession` chat snapshot (`s.chat.order` / `s.chat.nodes`): the ordinary `user` (and optional `steering`) rows come from the host order, and message-tools `message-tools-edited`/`message-tools-restored` bubbles that the host order does not always surface are appended from the node store — no store outside the session, no event registration. A bubble for a withdrawn original is dropped (its row is hidden by the DOM hider, so a click could never reach it), and appended bubbles are sorted by their anchor seq so the newest message is always last.
77
+ **Mount & data** — one entry in the official `conversation.session.header.utilities` slot anchors the plugin into the session scope; the panel renders through a body portal with fixed geometry measured from the official scrollport. Rows merge two sources: the host `turnOutline` projection (the `useProjection` standard seat — one entry per started turn: its number, its `turn/start` seq, and a 50-char first-prompt preview) lists every turn of the session, and the loaded window (`useChat`'s `order` / `nodes`) overlays richer previews, steering rows, and message-tools bubbles for the turns it covers (`message-tools-edited`/`message-tools-restored` bubbles the host order does not always surface are appended from the node store). A bubble for a withdrawn original is dropped (its row is hidden by the DOM hider, so a click could never reach it), and appended bubbles are sorted by their anchor seq so the newest message is always last. Without the projection, the window rows alone carry the list.
74
78
 
75
- **Jump & degradation** — clicking a row finds the transcript row by the official `data-chat-anchor-key` attribute and writes `scrollTop`; the official ChatView treats that as a normal reader move (bottom-follow and scroll memory keep working). The probed attributes are official render output, not a declared API: when they change, the panel hides itself with one `console.warn`; nothing throws and the boot never fails. The panel's width is capped by the scrollport's left gutter so it never covers the message flow; while the flow probe is unanswered (an official structure change) the width degrades to a capped fraction of the scrollport as a best-effort fallback — the panel may then overlap the flow until the probe recovers.
79
+ **Jump & degradation** — clicking a loaded row finds the transcript row by the official `data-chat-anchor-key` attribute and writes `scrollTop`; the official ChatView treats that as a normal reader move (bottom-follow and scroll memory keep working). Clicking an outline row goes through the session's jump loader (`ISession.loadThrough`, since 0.1.2-alpha.3): history pages back through the turn's `turn/start` seq, and the rail lands the moment the row materializes; when paging stalls or the turn is unreachable (e.g. its first message was withdrawn), it lands on the nearest visible row after the turn instead. The probed attributes are official render output, not a declared API: when they change, the panel hides itself with one `console.warn`; nothing throws and the boot never fails. The panel's width is capped by the scrollport's left gutter so it never covers the message flow; while the flow probe is unanswered (an official structure change) the width degrades to a capped fraction of the scrollport as a best-effort fallback — the panel may then overlap the flow until the probe recovers.
76
80
 
77
81
  **Model experience: none.** The panel reads the session snapshot and scrolls the transcript; it never sends prompts, appends session events, or enters the session log. KV cache effect: none. The `enabled` config turns the plugin off entirely; removing it from cordis.yml removes every surface it adds.
78
82
 
package/README.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # last confirmed-consistent state. Both languages carry equal authority; after
3
3
  # editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/message-timeline/README.en.md
5
- packages/message-timeline/README.en.md: 5c8d6f4b24c2852e1d64db8aeb0a4817e0832c64
6
- packages/message-timeline/README.md: 1718fba1afa90e0cdd1e23956cea3aa45fde0502
5
+ packages/message-timeline/README.en.md: bfd6e90fef2a0358c2c0d2156d2e2c07b7507636
6
+ packages/message-timeline/README.md: 6baf27211ccf3573bc364666d37de772e6e80750
package/README.md CHANGED
@@ -6,18 +6,19 @@
6
6
 
7
7
  会话一长,想找回三条消息前提过的那个要求,就只能一路往上滚。这个插件在对话左缘放了一条时间轴:你说过的每句话占一行,带单行预览;平时它收成一排压淡的刻度,不占视线,鼠标一悬停才展开,点哪一行就把会话滚到哪一句。它只读会话、不发任何消息,模型完全无感。
8
8
 
9
- <img src="https://raw.githubusercontent.com/Khorsheed/dsh-web-basic/main/docs/screenshots/message-timeline1.png" width="640" alt="对话左缘展开的消息时间轴:每行一条用户消息,点行即跳转到对应消息">
9
+ <img src="https://raw.githubusercontent.com/Khorsheed/dsh-basic/main/docs/screenshots/message-timeline1.png" width="640" alt="对话左缘展开的消息时间轴:每行一条用户消息,点行即跳转到对应消息">
10
10
 
11
11
  ## 特性
12
12
 
13
- - **每行一条用户消息**——竖刻度加单行省略预览;steering 消息也计入(可配置关闭),message-tools 的编辑/恢复气泡也保留一行。被撤回的原消息不展示(其会话行被隐藏,点击也到不了)。
14
- - **环境化静止态**——只显示压淡的刻度,悬停刻度条或聚焦列表才展开文字。
15
- - **阅读位置跟踪**——当前位置的刻度保持蓝色高亮,停在超长回复中时锚定在所回答的用户消息上。
16
- - **点击跳转**——点击行把会话滚动到对应消息;列表跟随阅读位置。
17
- - **长历史友好**——列表短时垂直居中;长时隐形滚动并在顶部翻页加载更早历史,最底部贴着聊天输入框;目标/任务等 dock 卡片不会把时间轴顶上去。
13
+ - **每行一条用户消息,从第一句起全量列出**——竖刻度加单行省略预览;宿主 `turnOutline` 投影直接给出整段会话的每一轮(含第一条消息),无需翻页。点击尚未加载的更早消息会先把历史回翻到那一轮再落位(回翻期间该行的刻度脉动提示)。steering 消息也计入(可配置关闭),message-tools 的编辑/恢复气泡也保留一行。被撤回的原消息不展示(其会话行被隐藏,点击也到不了)。
14
+ - **无文本预览的消息也有行、也能跳**——自动轮次(重启恢复、定时任务等)已加载时直接显示触发卡片正文,未加载时按「第 N 轮」标记;图片/附件消息分别标记为「图片消息」「附件消息」。点击自动轮次落到触发卡片后,选中保持在该轮,不会跳到下一条用户消息。
15
+ - **环境化静止态**——只显示压淡的灰色刻度,悬停刻度条或聚焦列表才展开文字。
16
+ - **阅读位置跟踪**——当前位置的刻度保持蓝色、加长且文字加粗(未选中时默认最新一条),其余行一律灰色;停在超长回复中时锚定在所回答的用户消息上。
17
+ - **点击跳转**——点击已加载的行直接滚动到位;点击未加载的行经会话的 jump loader 回翻历史后落位。
18
+ - **长历史友好**——列表短时垂直居中;长时隐形滚动,最底部贴着聊天输入框;目标/任务等 dock 卡片不会把时间轴顶上去。投影缺席的装配(未挂载 turn-outline 单元)退回窗口分页:打开时预取数页,更早历史在面板滚动到顶部时按需加载。
18
19
  - **绝不遮住消息流**——面板宽度受滚动区左缘沟槽约束;沟槽放不下最小宽度时隐藏而不是盖住会话。
19
20
 
20
- <img src="https://raw.githubusercontent.com/Khorsheed/dsh-web-basic/main/docs/screenshots/message-timeline2.png" width="640" alt="时间轴的静止态:收成一排压淡的刻度条,不挡视线,悬停才展开">
21
+ <img src="https://raw.githubusercontent.com/Khorsheed/dsh-basic/main/docs/screenshots/message-timeline2.png" width="640" alt="时间轴的静止态:收成一排压淡的刻度条,不挡视线,悬停才展开">
21
22
 
22
23
  ## 安装
23
24
 
@@ -38,12 +39,13 @@ dsh plugin --profile web remove @khorsheed/dsh-message-timeline
38
39
  | `enabled` | `true` | 总开关;false 时面板完全不渲染。 |
39
40
  | `includeSteering` | `true` | 回合中插入的用户消息(steering)是否也算行。 |
40
41
  | `panelWidth` | `360` | 面板宽度(px,限 120–640);窄列自动收缩,左缘沟槽放不下时整条隐藏。 |
41
- | `initialPages` | `5` | 面板打开时预取的历史页数(每页 50 条事件);更早历史在面板滚动到顶部时按需加载(限 1–20)。 |
42
+ | `initialPages` | `5` | 窗口分页兜底路径下,面板打开时预取的历史页数(每页 50 条事件;限 1–20)。宿主提供 turnOutline 投影时列表一次到位,此配置不生效。 |
42
43
 
43
44
  ## Compatibility
44
45
 
45
46
  - npm 发布线(`@deepseek-ai/dsh@0.1.2-rc.1`):✅ 完整——基线迁移至 0.1.2-rc.1 API 面(单臂消费 0.1.2 API,0.1.1-rc.2 运行臂已退役),全量构建测试通过;minHost 前移至 0.1.2-rc.1,旧宿主请停留在旧发布线。
46
- - 源码线(deepseek-harness master):✅(verifiedHost: 0.1.2-rc.1)
47
+ - 源码线(deepseek-harness master):✅(verifiedHost: 0.2.1-rc.1)——host-021 波对 0.2.1-rc.1 树全量 build+test 绿,无其它表面变化。
48
+ - 降级项:整会话列表依赖宿主 `turnOutline` 投影(`@deepseek-ai/dsh-session-turn-outline`,官方 web bundle 自 0.1.2-alpha.3 起默认挂载,早于 minHost)。装配未挂载该单元时面板退回窗口分页——逐页加载更早历史,功能完整但首条消息要翻到才出现。
47
49
 
48
50
  **版本线对照**:0.2.0 起支持宿主 `0.1.2-rc.1` 及以后;宿主 `0.1.0-rc.6` ~ `0.1.1-rc.2` 的用户请停留在 0.1.x 发布线(末版 `0.1.0`)。
49
51
 
@@ -52,7 +54,7 @@ dsh plugin --profile web remove @khorsheed/dsh-message-timeline
52
54
  - **依赖官方 DOM 探针** —— 面板针对官方行属性与 `[data-conversation-scroll]` 滚动区;官方结构变化时面板自行隐藏(console.warn 一次)直到探针更新。
53
55
  - **best-effort 宽度兜底** —— 消息流探针无应答时,面板以滚动区受限比例渲染而非隐藏,可能压到消息流直到探针恢复;探针健康时宽度绝不越过消息流左缘。
54
56
  - **单会话渲染** —— 行与跳转只作用于当前渲染的会话。
55
- - **仅已加载历史** —— 行覆盖已物化的节点;更早消息在面板滚动到顶部时逐页加载。
57
+ - **大纲按轮次归组** —— 投影每轮只留首条用户消息的预览:steering 行在其所在轮次加载进窗口后才出现;被撤回消息的轮次仍按大纲列出(与官方轮次轨道一致),点击后落位到该轮最近可见行。
56
58
  - **暂无整页导览** —— 可搜索的消息索引标签页在计划中。
57
59
 
58
60
  ## 实现原理
@@ -65,14 +67,16 @@ dsh plugin --profile web remove @khorsheed/dsh-message-timeline
65
67
  - `src/client/index.ts` —— 插件主体(`apply`/`inject`)
66
68
  - `src/client/rail-tracker.ts` —— 插件唯一接触的 DOM:只读探针、阅读位置解析,加跳转时的滚动写入
67
69
  - `src/client/TimelineRail.tsx` —— 面板组件
70
+ - `src/client/outline.ts` —— `turnOutline` 投影值的线路收窄(缺席/损坏一律读作"能力不在")
71
+ - `src/client/rows.ts` —— 已加载窗口行与大纲行的合并(单趟交错,保持会话序)
68
72
  - `src/client/timeline-kinds.ts` —— 哪些 kind 算行、哪些 kind 携带隐藏范围,的唯一权威
69
73
  - `src/client/hidden-spans.ts` —— 折叠 message-tools 撤回/编辑范围,把被覆盖的原消息作为死行丢弃
70
74
  - `src/client/preview.ts` —— 消息内容转单行预览文本
71
75
  - `src/index.ts` —— 空的宿主 `apply`,只负责把插件锚定进宿主 Loader
72
76
 
73
- **挂载与数据** —— 一个条目注册进官方 `conversation.session.header.utilities` 槽位,把插件锚定进会话作用域;面板通过 body portal 以固定几何渲染,数据从官方滚动区实测。行取自框架 `useSession` 会话快照(`s.chat.order` / `s.chat.nodes`):普通 `user`(及可选 `steering`)行来自宿主 order,而宿主 order 未必补上的 message-tools `message-tools-edited`/`message-tools-restored` 气泡从节点库追加——不持有会话外状态,不注册事件。被撤回原消息的气泡会被丢弃(其会话行已被 DOM hider 隐藏,点击到不了),追加的气泡按锚定 seq 排序,保证最新消息恒为最后一行。
77
+ **挂载与数据** —— 一个条目注册进官方 `conversation.session.header.utilities` 槽位,把插件锚定进会话作用域;面板通过 body portal 以固定几何渲染,数据从官方滚动区实测。行来自两路合并:宿主 `turnOutline` 投影(`useProjection` 标准座席,整会话每轮一条:轮次号、`turn/start` 序号、首条用户消息的 50 字预览)列出每一轮;已加载窗口(`useChat` 的 `order` / `nodes`)为其覆盖的轮次提供更丰富的预览、steering 行和 message-tools 气泡(宿主 order 未必补上的 `message-tools-edited`/`message-tools-restored` 气泡从节点库追加)。被撤回原消息的气泡会被丢弃(其会话行已被 DOM hider 隐藏,点击到不了),追加的气泡按锚定 seq 排序,保证最新消息恒为最后一行。投影缺席时退回纯窗口行。
74
78
 
75
- **跳转与降级** —— 点击行按官方 `data-chat-anchor-key` 属性找到会话行并写 `scrollTop`;官方 ChatView 把这种程序化滚动当正常读者移动处理(底部跟随与滚动记忆照常工作)。探测的属性是官方渲染产物而非契约 API:官方改结构时面板自行隐藏并 console.warn 一次,不抛错、boot 永不失败。面板宽度受左缘沟槽约束、不越过消息流左缘;流探针无应答(官方结构变化)时宽度退化为滚动区受限比例以 best-effort 兜底——此时面板可能压到消息流,直到探针恢复。
79
+ **跳转与降级** —— 点击已加载行按官方 `data-chat-anchor-key` 属性找到会话行并写 `scrollTop`;官方 ChatView 把这种程序化滚动当正常读者移动处理(底部跟随与滚动记忆照常工作)。点击大纲行则经会话的 jump loader(`ISession.loadThrough`,0.1.2-alpha.3 起)把历史回翻到该轮的 `turn/start` 序号,行一物化即落位;翻页停滞或该轮不可达(如首条消息已被撤回)时落位到其后最近的可行。探测的属性是官方渲染产物而非契约 API:官方改结构时面板自行隐藏并 console.warn 一次,不抛错、boot 永不失败。面板宽度受左缘沟槽约束、不越过消息流左缘;流探针无应答(官方结构变化)时宽度退化为滚动区受限比例以 best-effort 兜底——此时面板可能压到消息流,直到探针恢复。
76
80
 
77
81
  **模型体验:无。** 面板只读会话快照并滚动会话,不发送提示词、不追加会话事件、不进会话日志。KV 缓存影响:无。`enabled` 配置可整体关闭插件;从 cordis.yml 移除本插件即移除它添加的所有界面。
78
82