@deepseek-ai/dsh-client-ui-chat 0.1.7-alpha.1 → 0.1.7-alpha.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/README.i18n.yaml +2 -2
- package/README.md +24 -3
- package/README.zh.md +24 -3
- package/lib/client.js +481 -177
- package/lib/types/client/chat/use-chat-reading.d.ts +3 -2
- package/lib/types/client/chat/use-chat-viewport.d.ts +5 -8
- package/lib/types/client/chat/use-process-scroll.d.ts +23 -0
- package/lib/types/client/chat/use-scroll-follow.d.ts +105 -0
- package/package.json +39 -39
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/client/ui-chat/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 1aa7d71b3f932a7a14ef6d23e9ace7eda444fc3b
|
|
6
|
+
README.zh.md: 2239234448e1e00fd395634de39a96c2a80a35f7
|
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ File-mention providers receive the viewed Session ID with the closing-turn owner
|
|
|
33
33
|
|
|
34
34
|
Chat supplies file and HTTP(S) navigation through one `MarkdownDelegateProvider` around its node list. Assistant Markdown file links open in the right Sidebar after the message settles, including references to unmodified files. Relative paths resolve in the viewed Session's workspace; absolute paths retain the same Session's filesystem access. `#L24` and `#L24-L30` navigate to the first specified line and reuse an existing file tab. Missing files show the preview's error state.
|
|
35
35
|
|
|
36
|
-
Settings → General → Open chat links in selects the destination for ordinary clicks on Chat HTTP(S) links:
|
|
36
|
+
Settings → General → Open chat links in selects the destination for ordinary clicks on Chat HTTP(S) links: In-App Sidebar (default) opens a new right-Sidebar Browser tab, while Default Browser opens an external tab. The setting is shown only while the Sidebar Browser is available. If the Sidebar Browser is not registered, both choices use the external browser; modified clicks retain native behavior. The `ui-chat.linkOpening` preference persists on loopback browsers and stays process-local when settings cannot persist writes. Sent file references and skills confirmed by the message’s logged invocation also open in the right Sidebar. File paths use the viewed Session; skill names resolve through its current input-trigger source. Both use the prose file-link dotted underline on hover or focus. Sessions, directories, and command labels remain non-navigating references.
|
|
37
37
|
|
|
38
38
|
<a id="system-prompt-row"></a>
|
|
39
39
|
## Hidden Chat rows
|
|
@@ -72,7 +72,9 @@ The completed-turn action footer follows the recorded Turn end. Its action row s
|
|
|
72
72
|
<a id="turn-process-folding"></a>
|
|
73
73
|
## Turn Process Folding
|
|
74
74
|
|
|
75
|
-
During uninterrupted following, local steering echoes remain mounted through Inbox acceptance and claim until the durable message arrives, without triggering tail following twice. Pending
|
|
75
|
+
During uninterrupted following, local transcript and steering echoes remain mounted through Inbox acceptance and claim until the durable message arrives, without triggering tail following twice. Pending steering follows Inbox order across clients, using matching local echoes in place. Admitted local steering also suppresses matching stale Inbox rows until the claim projection arrives; steering without a locally tracked submission continues to follow the Inbox projection. After reconnect, Host-owned rows replace receipt-confirmed local echoes; a claim awaiting admission may briefly have no bubble.
|
|
76
|
+
|
|
77
|
+
When Chat ends with an open Turn control and that Turn has no visible input, the first local transcript echo precedes the control. Other echoes remain at the flow tail. The control and echoes share one keyed list, so arrival of the control preserves the echo's mounted identity. Durable inputs replace their matching echoes in the same render.
|
|
76
78
|
|
|
77
79
|
Work-details modes control process-group display and reasoning previews; eligible completed Turns fold their process without hiding the final answer. The [business-rule reference](src/client/conversation-nodes/README.md#display-modes) contains the mode table, title behavior, whole-Turn eligibility, clocks, and disclosure resets.
|
|
78
80
|
|
|
@@ -100,6 +102,19 @@ The Chat-node slot injects a reset-bound `useDisclosure` Hook for reasoning and
|
|
|
100
102
|
|
|
101
103
|
Chat restores semantic anchors across history prepend and renderer remounts, with browser scroll anchoring disabled on its scrollport only while following the tail. Pinned scroll deliveries without reader movement, and reader input that reaches the exact floor, update follow ownership immediately, before subsequent layout changes can invalidate their floor. Other reader movement remains pending until the sampling interval or `scrollend`, even inside the follow threshold, so layout growth cannot erase small scroll gestures. Submitting transcript input or steering immediately restores tail following and clears an older pending reader sample. While the reader is pinned to the floor, `ResizeObserver` follows the new floor and selects the latest loaded Turn without reading row geometry. Once the reader moves away, flow-height changes preserve the top position and the reading-line geometry selects the active Turn. Turn-rail previews paint above sticky Markdown code-block banners, while the rail frame remains inside the transcript band above the composer.
|
|
102
104
|
|
|
105
|
+
The turn rail and back-to-bottom button sit outside the clipped transcript. They use the shared conversation scrollport for sticky positioning, or the Chat frame for absolute positioning when Chat owns its scrollport. The rail hides when the transcript's available width, excluding its horizontal padding, is at most 900px; the browser viewport width is not the criterion.
|
|
106
|
+
|
|
107
|
+
The transcript root uses `overflow-x: visible; overflow-y: clip`: vertical overflow is clipped without creating a scroll container. Sticky Markdown code banners and expanded compaction headers therefore retain the actual conversation scrollport as their reference when no nearer scrolling ancestor exists. Capped process groups and terminal sections keep their own scrollports.
|
|
108
|
+
|
|
109
|
+
Outer transcript following and each open capped group's following are independent. Native animation progress retains follow intent; a reader gesture interrupts the animation, and actual movement determines whether following remains enabled. Scroll chaining can move the outer transcript, which then applies its own distance threshold. The back-to-bottom button restores only outer following.
|
|
110
|
+
|
|
111
|
+
| Outer follows | Open group follows | Back-to-bottom button | New content |
|
|
112
|
+
|---|---|---|---|
|
|
113
|
+
| Yes | Yes | Hidden | Each scrollport follows its own floor. |
|
|
114
|
+
| Yes | No | Hidden | The outer transcript follows; the group retains its position. |
|
|
115
|
+
| No | Yes | Visible | The group follows; the outer transcript retains its reading position. |
|
|
116
|
+
| No | No | Visible | Both retain their reading positions. |
|
|
117
|
+
|
|
103
118
|
The turn rail mounts only visible marks, overscan, and the focused mark's neighbors. Its fixed pitch and observed viewport size determine scroll offsets without reading the DOM scroll extent. Initial placement waits for the body's restored active Turn and the rail's first usable viewport size. The ref controls activate a Turn or scroll the rail independently; the transcript itself remains fully mounted.
|
|
104
119
|
|
|
105
120
|
While the pointer is outside the rail, automatic follow keeps the rail still when the active mark's center is inside the fade-free band and centers it after it leaves that band. Previews follow pointer movement or focus; marks scrolling under a stationary pointer do not select another preview.
|
|
@@ -107,7 +122,11 @@ While the pointer is outside the rail, automatic follow keeps the rail still whe
|
|
|
107
122
|
<details>
|
|
108
123
|
<summary>Scroll implementation — click to expand</summary>
|
|
109
124
|
|
|
110
|
-
|
|
125
|
+
Within a process group, wheel, touchstart, and any pointerdown interrupt an active smooth animation, including presses on tool cards. ArrowUp/ArrowDown, PageUp/PageDown, Home/End, and Space keys also interrupt it unless a child has prevented the key's default action; editable controls are not excluded. These events stop the animation without requiring a scroll displacement. Subsequent position sampling determines whether following continues.
|
|
126
|
+
|
|
127
|
+
`useScrollFollow` supplies independent controllers for shared bottom thresholds, follow intent, and native scrolling. `useProcessScroll` owns group observation, initial placement, and edge fades. Outer following remains immediate; group growth uses native smooth scrolling unless reduced motion is requested. Growth retains an in-flight target until `scrollend`; arrival at that target or its shrink-clamped position continues toward the latest floor, while another endpoint releases following. Opening placement remains immediate. A bottom-follow request within tolerance uses immediate positioning when no animation is outstanding, so a fractional no-op cannot leave a pending smooth target.
|
|
128
|
+
|
|
129
|
+
`useChatViewport` owns turn-aware DOM reads, clamped writes, native events, and one retained paging anchor. For Load older, Node and Group seats mark eligible anchors from their existing disclosure state. The viewport selects the first nonempty, unhidden marker in transcript order without hit testing or geometry-based search, then measures that element and its scroll containers. It compensates the anchor's capped group first, then gives the remaining displacement to the transcript scrollport. An inner compensation write cancels that group's animation through its bound controller and pauses following; reader scrolling back to the bottom resumes it. Commits and later content resizes reuse that anchor; a remounted row is resolved by the same semantic key. Compensation stays within the actual scroll ranges without adding bottom space.
|
|
111
130
|
|
|
112
131
|
`useChatReading` owns follow policy, sampled reader input, and semantic memory; `useChatNavigation` owns turn jumps and requests preservation from the viewport. Reading gestures release the paging anchor, but composer clicks, typing, and non-scrolling keys retain it; while a page is still loading, `scrollend` captures the reader's new position. `useChatScroll` coordinates their committed inputs. Explicit navigation carries its measured landing into reading policy, so it does not rediscover the known target with a hit test.
|
|
113
132
|
|
|
@@ -133,6 +152,8 @@ None; Chat presentation does not assemble or mutate provider requests.
|
|
|
133
152
|
|
|
134
153
|
- **Developer messages are not displayed** — presentation is intentionally deferred; encountering `developer/message` throws instead of rendering a fallback row.
|
|
135
154
|
|
|
155
|
+
- **Opening echoes predict local order** — several submissions made before the running update can all remain in Chat. Their initial order follows local submission order, not Host queue order; admission can reposition them when the Host receives requests in a different order.
|
|
156
|
+
|
|
136
157
|
- **The transcript reflects the loaded Session window** — older transcript nodes become available only after Session Controller loads the preceding event page. Turn navigation is wider than the window: the rail merges the loaded Turns with the host `turnOutline` projection, so every started Turn gets a fixed-pitch mark (10px apart; a ladder taller than the frame scrolls inside it with gradient fades), and activating an unloaded mark pages history through the Turn's `turn/start` seq before landing on its row. Without the projection (assemblies not mounting `dsh-session-turn-outline`) the rail falls back to loaded Turns only.
|
|
137
158
|
- **Rail previews are card-sized** — one prompt line (50 characters) and up to three response lines (120), on loaded and unloaded Turns alike; an unloaded Turn's response arrives from the outline only once the Turn settled, so an open Turn previews its prompt (or just the Turn number) until then.
|
|
138
159
|
|
package/README.zh.md
CHANGED
|
@@ -33,7 +33,7 @@ kind: "package-reference"
|
|
|
33
33
|
|
|
34
34
|
Chat 在节点列表外通过一个 `MarkdownDelegateProvider` 提供文件及 HTTP(S) 导航。Assistant Markdown 文件链接在消息落定后可于右侧栏打开,包括未修改文件的引用。相对路径基于当前查看的 Session 工作区解析;绝对路径仍使用同一 Session 的文件系统访问。`#L24` 和 `#L24-L30` 定位到指定起始行,并复用现有文件标签。文件缺失时显示预览错误状态。
|
|
35
35
|
|
|
36
|
-
设置 → 通用设置 →
|
|
36
|
+
设置 → 通用设置 → 网页链接默认打开方式控制普通点击 Chat HTTP(S) 链接时的目标:「应用内侧边栏」(默认)打开新的右侧 Sidebar Browser tab,「默认浏览器」打开外部标签页。该设置项仅在 Sidebar Browser 可用时显示。若 Sidebar Browser 未注册,两种选择均使用外部浏览器;带修饰键的点击保留原生行为。`ui-chat.linkOpening` 偏好在回环地址浏览器中持久化,设置无法持久化写入时仅在当前进程内生效。已发送的文件引用及消息日志确认调用的 skill 也可在右侧栏打开预览。文件路径使用当前查看的 Session;skill 名称由该 Session 当前的输入触发源解析。两者悬停或聚焦时均使用正文文件链接的虚线下划线。会话、目录和命令标签仍只作为引用展示。
|
|
37
37
|
|
|
38
38
|
<a id="system-prompt-row"></a>
|
|
39
39
|
## Chat 隐藏的行
|
|
@@ -72,7 +72,9 @@ Assistant 尝试结束且没有可见消息时,Chat 隐藏已发布的 Node,
|
|
|
72
72
|
<a id="turn-process-folding"></a>
|
|
73
73
|
## 轮次过程折叠
|
|
74
74
|
|
|
75
|
-
正常在线时,本地 steering 回显在 Inbox
|
|
75
|
+
正常在线时,本地 transcript 与 steering 回显在 Inbox 接受与领取期间保持挂载,直到持久消息到达,不会重复触发跟随底部。跨客户端的待处理 steering 遵循 Inbox 顺序,在匹配位置使用本地回显。已入档的本地 steering 还会排除匹配的旧 Inbox 行,直到领取投影到达;没有本地提交身份的 steering 仍按 Inbox 投影显示。重连后,Host 消息替代已有接收回执的本地回显;已领取但尚未入档时,气泡可能短暂消失。
|
|
76
|
+
|
|
77
|
+
Chat 末尾为进行中的 Turn 控制行,且该轮尚无可见输入时,第一条本地 transcript 回显显示在控制行前。其他回显保留在正文末尾。控制行与回显共用一个 keyed 列表,因此控制行到达时不会重新挂载回显。持久输入在同一次渲染中替换匹配的回显。
|
|
76
78
|
|
|
77
79
|
工作过程展示模式控制过程组显示与推理预览;符合条件的已完成轮次折叠过程,但不隐藏最终答案。[业务规则明细](src/client/conversation-nodes/README.zh.md#display-modes) 统一说明模式表、组头行为、整轮折叠资格、时钟与开合重置。
|
|
78
80
|
|
|
@@ -100,6 +102,19 @@ Chat 节点 slot 为推理与工具注入绑定重置来源的 `useDisclosure`
|
|
|
100
102
|
|
|
101
103
|
Chat 会在历史前插与 renderer 重新挂载时恢复语义锚点,并且只在跟随底部时禁用自己滚动区域的浏览器自动锚定。没有读者移动的贴底滚动事件,以及确实到达最底部的读者输入,会立即更新跟随归属,避免后续布局变化使其底部位置失效。其他读者移动即使位于跟随阈值内,也保持待处理直到采样周期或 `scrollend`,防止布局增长抵消小幅滚动操作。提交正文输入或 steering 时立即恢复跟随底部,并清除先前待处理的读者滚动采样。读者跟随底部时,`ResizeObserver` 追随新的底部,并且无需读取行几何就选中最后一个已加载轮次;读者离开底部后,高度变化会保持顶部位置,再由阅读线几何选择活跃轮次。轮次导航预览位于 Markdown 代码块粘性头栏上方,而导航外框始终处于 composer 上方的 transcript 区域内。
|
|
102
104
|
|
|
105
|
+
轮次轨道与回到底部按钮位于正文裁剪层外。它们相对共享会话滚动容器做 sticky 定位;Chat 自己持有滚动容器时,则相对 Chat 外框做 absolute 定位。正文扣除水平内边距后的可用宽度不超过 900px 时,隐藏轮次轨道;判断依据不是浏览器视口宽度。
|
|
106
|
+
|
|
107
|
+
正文根节点使用 `overflow-x: visible; overflow-y: clip`:裁剪纵向溢出,但不创建滚动容器。因此,在没有更近的滚动祖先时,Markdown 代码块的 sticky 头栏和展开的压缩摘要头栏仍以实际会话滚动容器为参照。限高过程组和终端区域保留各自的滚动容器。
|
|
108
|
+
|
|
109
|
+
外层文本记录与每个已展开限高组的跟随状态彼此独立。原生动画的中间滚动保留跟随意图;读者手势中断动画,是否继续跟随由实际位移决定。滚动传递可以带动外层,外层再按自身离底距离判断。回到底部按钮只恢复外层跟随。
|
|
110
|
+
|
|
111
|
+
| 外层跟随 | 已展开小组跟随 | 回到底部按钮 | 新增内容 |
|
|
112
|
+
|---|---|---|---|
|
|
113
|
+
| 开启 | 开启 | 隐藏 | 各自跟随自己的底部。 |
|
|
114
|
+
| 开启 | 关闭 | 隐藏 | 外层跟随,小组保持原位置。 |
|
|
115
|
+
| 关闭 | 开启 | 显示 | 小组跟随,外层保持阅读位置。 |
|
|
116
|
+
| 关闭 | 关闭 | 显示 | 两者都保持阅读位置。 |
|
|
117
|
+
|
|
103
118
|
轮次轨道只挂载可见刻度、预加载范围及键盘焦点刻度的相邻项。固定间距和观察到的视口尺寸决定滚动偏移,不读取 DOM 滚动总高度。初始定位等待正文恢复活跃轮次,以及轨道首次获得可用视口尺寸。ref 控制接口分别支持激活轮次和仅滚动轨道;正文自身仍完整挂载。
|
|
104
119
|
|
|
105
120
|
指针位于轨道外时,自动跟随在活跃刻度中心处于非渐隐区域内时保持轨道不动,越界后才将其居中。预览随指针移动或焦点切换;刻度在静止指针下滚动不会选中另一个预览。
|
|
@@ -107,7 +122,11 @@ Chat 会在历史前插与 renderer 重新挂载时恢复语义锚点,并且
|
|
|
107
122
|
<details>
|
|
108
123
|
<summary>滚动实现——点击展开</summary>
|
|
109
124
|
|
|
110
|
-
|
|
125
|
+
过程组内的 wheel、touchstart 和任意 pointerdown 都会中断正在进行的平滑动画,包括按下工具卡片。上下方向键、PageUp/PageDown、Home/End 和空格键也会中断动画,除非子控件已阻止该按键的默认行为;输入控件不被排除。这些事件无需产生滚动位移就会停止动画,之后的位置采样再决定是否继续跟随。
|
|
126
|
+
|
|
127
|
+
`useScrollFollow` 提供各自独立的控制器,共用触底阈值判断、跟随意图与原生滚动实现。`useProcessScroll` 负责小组观察、初始定位及边缘渐隐。外层保持即时跟随;组内增长使用原生平滑滚动,减少动态效果偏好开启时改为即时滚动。`scrollend` 前的增长保留当前动画目标;到达该目标或因内容缩短而钳制的位置后,再追随最新底部;停在其他位置则释放跟随。展开时仍即时定位。没有进行中动画时,容差范围内的贴底请求使用即时定位,避免小数位置上的无位移操作留下未结束的平滑目标。
|
|
128
|
+
|
|
129
|
+
`useChatViewport` 负责识别轮次的 DOM 读取、限制范围后的写入、原生事件及一个持续保留的分页锚点。加载更早时,Node 与 Group 容器根据已有开合状态标记可选锚点。视口按正文顺序选择第一个非空、未隐藏的标记,不做命中测试或按几何位置搜索,再测量该元素及其滚动容器。先补偿锚点所在的限高组,再把剩余位移交给整段文本的滚动区域。内层补偿写入通过该组绑定的控制器取消动画并暂停跟随,读者滚回底部后恢复。提交和后续内容尺寸变化复用该锚点;消息行重挂载时按同一语义 key 重新定位。补偿限于实际可滚动范围,不增加底部空白。
|
|
111
130
|
|
|
112
131
|
`useChatReading` 负责跟随策略、读者输入采样和语义位置记忆;`useChatNavigation` 负责轮次跳转,并向视口请求位置保持。阅读手势释放分页锚点,composer 内的点击、打字和非滚动按键则保留锚点;分页仍在加载时,`scrollend` 会记录读者的新位置。`useChatScroll` 协调已提交的输入。显式导航把测得的落点交给阅读策略,因此无需通过命中测试重新寻找已知目标。
|
|
113
132
|
|
|
@@ -133,6 +152,8 @@ Chat 会在历史前插与 renderer 重新挂载时恢复语义锚点,并且
|
|
|
133
152
|
|
|
134
153
|
- **不展示 developer 消息** — 展示能力有意留待后续实现;遇到 `developer/message` 时抛出错误,不渲染回退行。
|
|
135
154
|
|
|
155
|
+
- **开场回显预测本地顺序**——运行状态更新前连续发出的多条消息可能都留在 Chat。初始排列遵循本地提交顺序,而非 Host 队列顺序;Host 按不同顺序接收请求时,入档可能调整它们的位置。
|
|
156
|
+
|
|
136
157
|
- **transcript 只反映已加载的 Session 窗口**——只有会话控制器加载前一页事件后,更早的 transcript node 才会出现。轮次导航比窗口更宽:轨道把已加载的轮次与宿主 `turnOutline` 投影合并,每个已开始的轮次都有固定间距刻度(相隔 10px;阶梯高于外框时在框内滚动并以渐变淡出标示可滚方向),激活未加载刻度会先把历史分页拉到该轮次的 `turn/start` seq 再落到它的行上。没有该投影时(未挂载 `dsh-session-turn-outline` 的装配),轨道回退到仅显示已加载轮次。
|
|
137
158
|
- **导航预览按卡片尺寸截断**——提示词一行(50 字符)、回复至多三行(120 字符),已加载与未加载 Turn 一致;未加载 Turn 的回复要等该轮落定后才随大纲到达,进行中的轮次在此之前只预览提示词(或仅轮次号)。
|
|
138
159
|
|