dsh-claude-style 0.16.2 → 0.16.3-dev.33

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
@@ -4,6 +4,60 @@ All notable changes to `dsh-claude-style` are documented here, newest first.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.16.3] - 2026-10-18
8
+
9
+ [中文](#cn-0.16.3) | [English](#en-0.16.3)
10
+
11
+ <h3 id="cn-0.16.3">新增功能</h3>
12
+
13
+ - **Beam 的模型行画出厂商组合标**:目录里 `opencode-go/beam-free` 这类标识现在认领 Reflection 的组合标。字标是厂名的,模型名里从不写它,字标因此站在名字前面;标记在浅色画布上用厂商自己的品牌色,深色画布上随标签文字。
14
+
15
+ ### 体验优化
16
+
17
+ - **一次改写或折叠作废的淡入片段改由一趟原地压缩收走**:此前每摘掉一段都要搬动它后面的全部片段,一批里作废的片段一多,这一趟就按片段数的平方增长;现在一趟写完。读者看到的样子不变。
18
+ - **流式期间写回的 tokens 把工具调用算进去**:调用的参数从不出现在页面上,一个只调工具的步骤因此原先停在结算值不动,现在每出现一行调用就按一行计,纯文字的字重也降到更接近实际的比例;计数挂在页面结构上,不再为此每帧扫一遍对话。
19
+ - **等待行换词不再强制页面同步重算样式与布局**:换词需要的宽度改由渲染本身的布局经尺寸观察得到,旧词离场、新词进场与宽度过渡都在随后一帧起步,看到的动作不变;本机桌面端跑 `/perf-stream 150 tps=1000`(主会话加两个子智能体)、对话涨到约 435 个节点的 215 次换词里,标签上的布局读取为 0 次,改动前每次换词要强制重算两次,每次 13.5–44 ms。
20
+ - **过程组较多的会话切换时,摘要一次量完**:16 个过程组的一次切换里最长强制布局从约 360 毫秒降到约 40 毫秒,切换耗时从约 0.58 秒降到约 0.33 秒。
21
+ - **等待行加载点换动作时先出后进**:离场的那组点各自在折返处淡出,最后一颗走完新的那组才从头开始、各自淡入,18×14 的小框里不再有 400–650 ms 同时挤着两组共六七颗点。
22
+
23
+ ### 问题修复
24
+
25
+ - **用量面板里热力格的日期提示不再把面板撑出横向滚动条**:提示胶囊按自己当时的宽度决定贴向格子的哪一边,靠近两端的格子不再把它带出面板边缘,悬停时面板本身也不再横向滚动。
26
+ - **设置页里刚改动的开关不再先跳回原值**:改动交给宿主的这段时间里,宿主重读设置文档不会再把页面上的值盖回改动之前,控件停在读者按下的那一档,宿主给出答复时再按答复校正。
27
+ - **关闭「聊天区滚动动画」后,进行中的状态行留在文档里**:此时滚动整份交回宿主,这一行不再停在输入框上方,读者往回翻看时它随内容一起滚走。
28
+ - **窗口很窄时,思考强度按钮留在输入卡片里**:它在模型按钮旁边借的那点宽度改为从模型名的截断里出,输入卡片不再因此横向滚动,按钮也不会画到侧栏上方。
29
+ - **等待行加载点沿直线往返时走的是简谐运动**:三颗点在两端停顿、穿过中点最快,经过中点时缩到最小;此前它们匀速往返。
30
+
31
+ ### 其他变更
32
+
33
+ - **内置文档与注释里重复的那一份清掉了**:每个功能签名上一律重复的三行参数注释、每个 `copy.ts` 里同一句「One key of this feature's own copy」、以及散在各处的「此前是怎么做的」「实测读到多少」一律删去;`constants.ts` 叠放的两段模块注释合成一段(顺带修掉一处注释里多出的星号),`shared/activity-phrase.ts` 的长注释压到约定长度并引用 D70,`docs/SETTINGS.md` 与英文版里三段与功能一览逐字相同的说明改成指向那一条。代码行为不变。
34
+ - **两道检查各补上一处**:750 行停线开始管单元测试文件(一个测试文件长过停线,就是一份文件装了几个题目);整份文档查找的登记规则写明单元测试不在其内,测试里的文档跑在测试浏览器上,不花读者一分钱。`packages/contracts/src/timing.ts` 的 `host.column-observer` 添上持有它的那份单元测试,构建里「一条时刻假设要么点名场景、要么点名单元测试」的后半句从此有实例。
35
+
36
+ <h3 id="en-0.16.3">New Features</h3>
37
+
38
+ - **Beam rows draw the vendor lockup**: an id such as `opencode-go/beam-free` now claims Reflection's lockup. The wordmark is the vendor's, which the catalog's name never spells, so it leads the label; the mark wears the vendor's own brand colour on the ivory canvas and the label's ink on the warm black one.
39
+
40
+ ### Improvements
41
+
42
+ - **The fade segments one rewrite or fold invalidates are taken out in a single in-place compaction**: taking one out used to move every segment after it, so a batch that invalidated many grew with the square of the segment count; one pass now writes them out. Nothing on screen changes.
43
+ - **The written-back tokens count the tool calls while an answer streams**: a call's arguments never appear on the page, so a step that only called tools used to stand still at the settled number; each call row now counts once, and the per-character share of plain text is closer to what the provider bills. The count rides on the page structure rather than a per-frame sweep of the conversation.
44
+ - **The waiting line swaps its words without forcing a synchronous style and layout pass**: the width a swap needs is heard from the render's own layout through a size observer, and the old words leaving, the new ones arriving and the width travel all start on the frame after, looking the same as before; on this machine's desktop app a `/perf-stream 150 tps=1000` run (one main session and two subagents) made 215 swaps up to about 435 conversation nodes with no layout read on the label, where each swap used to force two passes of 13.5–44 ms.
45
+ - **A conversation with many process groups switches with its summaries measured once**: across a 16-group switch the longest forced layout falls from about 360 ms to about 40 ms and the switch from about 0.58 s to about 0.33 s.
46
+ - **The waiting line's loader changes motion one set at a time**: the set leaving fades each dot out where it turns, and only once the last one has gone does the next set start from the top and fade its dots in, so the 18×14 box no longer crowds six or seven dots from two motions together for 400–650 ms.
47
+
48
+ ### Bug Fixes
49
+
50
+ - **A heat cell's day tip no longer pushes the usage panel into a horizontal scrollbar**: the pill lines up with the side its own width needs, so a cell near either end keeps it inside the panel and hovering no longer scrolls the panel sideways.
51
+ - **A control just changed in the settings page no longer snaps back first**: while the change is crossing to the host, a re-read of the settings document no longer puts the pre-change value back on the page — the control stays where the reader left it and follows the host's answer when it arrives.
52
+ - **With the chat-area scrolling animation off, the running status line keeps its document place**: the host owns the scroll then, so the line no longer rests above the composer and wheels away with the content as you read back.
53
+ - **With a very narrow window the reasoning-effort trigger stays inside the composer card**: the room it borrows beside the model trigger now comes out of the model name's truncation, so the card no longer scrolls sideways and the trigger is never drawn over the sidebar.
54
+ - **The waiting line's loader dots walk their lines in simple harmonic motion**: each one rests at either end and is fastest through the middle, where it is smallest; they used to walk at a constant speed.
55
+
56
+ ### Chores
57
+
58
+ - **The built-in documents and comments lose the copy that stood twice**: the three parameter lines every feature's signature repeated, the same "One key of this feature's own copy" line in every `copy.ts`, and the scattered notes about how the code used to work and what a measurement once read are gone; `constants.ts`'s two stacked module comments are one (and a stray asterisk in one of them is fixed), `shared/activity-phrase.ts`'s long comment is down to the length the conventions set with D70 cited, and the three paragraphs in `docs/SETTINGS.md` and its English twin that repeated the feature list word for word now point at it. No behaviour changes.
59
+ - **Two checks each gain one thing**: the 750-line stop line now covers unit test files (a test file past the line is one file holding several subjects), and the whole-document lookup register says plainly that a unit test stands outside it, since a test's document runs in the test browser and costs no reader anything. `packages/contracts/src/timing.ts`'s `host.column-observer` names the unit test that holds it, so the second half of "an assumption names a scenario or a unit test" has an instance.
60
+
7
61
  ## [0.16.2] - 2026-10-17
8
62
 
9
63
  [中文](#cn-0.16.2) | [English](#en-0.16.2)
@@ -273,15 +327,11 @@ All notable changes to `dsh-claude-style` are documented here, newest first.
273
327
  - 端到端通道让每个场景声明的浏览器开关真正生效:远端设置走查改用一台带名字映射(`--host-resolver-rules`)的浏览器,不论整条通道是否共用一个浏览器都跑到底。
274
328
  - 重要性台账记下两种判定都算数的记录(`either`):一行只在某一帧里存在,或由宿主的运行平台决定画不画,这一趟抓到与否都算数,检查不再要求把它划掉;台账同时按云端与本机两次判定重算。
275
329
 
276
- <<<<<<< HEAD
277
- <h3 id="en-0.14.2">Improvements</h3>
278
- =======
279
330
  ### 问题修复
280
331
 
281
332
  - 侧边栏的工作区名字过长时让位给行尾的悬停操作(名字以省略号收尾),工作区菜单与新建会话两个按钮始终留在栏内并可点击。
282
333
 
283
- <h3 id="en-unreleased">Improvements</h3>
284
- >>>>>>> f25e6c0 (fix(sidebar): 工作区名字过长时不再把行尾按钮挤出栏外)
334
+ <h3 id="en-0.14.2">Improvements</h3>
285
335
 
286
336
  - The end-to-end lane honours the browser switches a scenario declares: the remote-settings walk opens its page under the mapped name whether or not the lane shares one browser between scenarios.
287
337
  - The importance ledger records the rows the walk cannot decide either way (`either`) — a row that lives inside one animation frame, or one the host's own platform decides to draw: whether this run catches it is right both ways, so the check no longer asks for it to be struck. The list is recomputed from the cloud run and this machine's run together.
@@ -36,7 +36,7 @@ SOFTWARE.
36
36
 
37
37
  ## Lobe Icons
38
38
 
39
- The vendor lockups the model picker draws (`packages/assets/src/icons/combine/`, inlined into `lib/client.js`) are composed by `scripts/fetch-lobe-combines.py` from Lobe Icons: `@lobehub/icons-static-svg` ships each vendor's mono mark, colour mark and wordmark, and `@lobehub/icons` carries the composition ratios. Brand names and logos remain trademarks of their respective owners.
39
+ The vendor lockups the model picker draws (`packages/assets/src/icons/combine/`, inlined into `lib/client.js`) are composed by `scripts/fetch-lobe-combines.py`: most from Lobe Icons (`@lobehub/icons-static-svg` ships each vendor's mono mark, colour mark and wordmark, and `@lobehub/icons` carries each vendor's brand colour and which artwork variants exist), the rest — OpenAI's and Reflection's — from artwork the repository carries under `packages/assets/src/icons/`. Brand names and logos remain trademarks of their respective owners.
40
40
 
41
41
  Source: <https://github.com/lobehub/lobe-icons>
42
42
 
@@ -12,7 +12,7 @@ What each feature does and where its switch lives; the six tabs, their rows and
12
12
  - **Ripple glyph background**: The new-conversation page's background is a field of digits and letters in the monospace face, redrawn twice a second under a slowly drifting cloud and faintly visible only where the cloud is thin. A press anywhere on the page sends out waves: they travel fastest at the click and slow with distance, so each ring thins as it goes; the characters a wave passes show, blue at its front and grey in its wake, fading away. A switch of the same name under the home layout on the Appearance tab is off until it is turned on, and is marked experimental.
13
13
  - **Mascot**: A pixel companion stands on the composer's top edge and changes its animation with what the agent is doing (thinking, writing and calling tools, several sessions at work, subagents, waiting on you, compacting the context, finished, failed, asleep). Follow the brand shows the pixel crab under Claude and Deepy the whale under DeepSeek; either can be picked for good, or none. Where it appears keeps it to the new-conversation page, or puts it in conversations as well.
14
14
  - **Permission control**: The composer's permission menu becomes a row of segments on the classic home; the studio home and conversations carry one trigger with its tier card, shaped like the composer's other pickers. The presets are the host's own catalog, a plugin's preset included; the new-conversation page shows the one a new session will start in.
15
- - **Session numbers**: The session statistics and the token usage follow the host's data live and stand in the context meter's popover by default: the host's own context rows, followed by this session's detail rows — turns and steps, the output speed, the tokens read in and written back, the cache-hit share. On its own line writes them on a line of their own below the input card with the meter's pie at its end, and pressing that line opens and closes the same popover (opening and closing on hover stays the pie's own path). A figure counts from the value on show to a new reading, carries on from where it stands when another reading lands mid-count, and counts to another session's numbers from the ones it was showing; the popover's rows count the same way; while an answer streams, the written-back figure climbs with the text that has arrived, by estimate, and is replaced by the host's own number once that step settles; no separator glyph stands between the groups — the line's own gap is what sets them apart — and the cache share's band marks its figure and percent sign alone while the meter's pie takes the colour its occupancy falls on.
15
+ - **Session numbers**: The session statistics and the token usage follow the host's data live and stand in the context meter's popover by default: the host's own context rows, followed by this session's detail rows — turns and steps, the output speed, the tokens read in and written back, the cache-hit share. On its own line writes them on a line of their own below the input card with the meter's pie at its end, and pressing that line opens and closes the same popover (opening and closing on hover stays the pie's own path). A figure counts from the value on show to a new reading, carries on from where it stands when another reading lands mid-count, and counts to another session's numbers from the ones it was showing; the popover's rows count the same way; while an answer streams, the written-back figure climbs with the text that has arrived, by estimate, and each tool call counts once since a call's arguments never reach the page, with the host's own number replacing the estimate once that step settles; no separator glyph stands between the groups — the line's own gap is what sets them apart — and the cache share's band marks its figure and percent sign alone while the meter's pie takes the colour its occupancy falls on.
16
16
  - **Peak rate meter**: Every row of the model picker carries the rate in force for that model right now: peak, off-peak and a dated promotion each get their own mark, the colour says expensive or cheap, and the countdown says how long it lasts; hovering reads the whole judgement, the state in force and what it becomes and when. Each provider is judged on its own clock, public holidays are off-peak in full, and windows crossing midnight and daylight-saving changes are resolved against real instants.
17
17
  - **Model picker**: The composer's model menu becomes a two-level card: the first level holds the official service and the quick providers you picked, each model with its vendor mark and a line of description; the second level holds the rest.
18
18
  - **Effort**: The reasoning effort gets a trigger of its own beside the model, opening a slider. It switches with the model picker, since the host keeps the effort inside its own model menu.
@@ -25,7 +25,7 @@ What each feature does and where its switch lives; the six tabs, their rows and
25
25
  - **Conversation navigator**: The column of short marks at the conversation's right edge holds one per turn and follows where you are reading. Reach it with the pointer and it opens into a list: each row carries the message that started its turn and sits exactly where that turn's mark was — the turn you are reading stays in place, and the turn under the pointer is still under it. The wheel scrolls the list and a click glides the page to the turn, loading earlier history first when it is not loaded yet; the Chat / Trajectory tabs at the top of the conversation stay up while the pointer is on the list. Alt+↑ / Alt+↓ jump to the previous or the next turn, and held or repeated they keep stepping; while the composer holds a draft the keys stay with it. The turn you land on flashes a short line over its start. With [dsh-plugin-msg-nav](https://github.com/SherUnlocked-4869/dsh-plugin-msg-nav) installed too, Alt+↑ / Alt+↓ stay with that plugin.
26
26
  - **Chat-area follow**: At the structural moments — a thinking row folding, a tool call row arriving — a reader sitting at the bottom is handed back to the host's own follow, instead of being left tens of pixels short by the burst of content; a process group capped in the Standard and Compact tiers (thinking and tool output kept in one scrolling body) is caught up the same way. Catching up runs on a curve: a trickle of characters settles softly and a burst glides at one steady speed before landing. While content streams, the host's own follow keeps the position at the end and the newly grown content slides up from the bottom edge instead of the text above it jumping in a single frame, with the status line standing still; the slide runs on the graphics card and takes no layout, so several sessions streaming at once cost no more for it. A message you send does not go through it: the host's scroll to bring it into view lands at once. Once the reader scrolls away from the bottom himself, the plugin stays out of it until he returns.
27
27
  - **Automatic folding and the rolling door**: A thinking row opens while the model reasons and folds back when it stops; a running process group opens and folds back once that piece of work ends. A row or group the reader pressed himself keeps what he chose for that phase. The open reasoning stands in a window that grows with it: the window is as tall as the text until it reaches the height reasoning may take, and there it stays while the text steps up two lines at a steady beat behind a softened edge at each side, stopping at the newest line; once the reasoning stops the window comes off and the reader who opens the row reads it whole, and with Animation set to Reduced the window is never set. A process group's header says what the group holds — "2 thoughts, 1 tool call", empty figures left out — each number rolling as the work grows, and the whole line sweeps the way the host's words do while that piece of work runs; a header without the room for the sentence falls back to `Thinking×2 · Tools×1` and takes the sentence back when the room returns, with the sentence as the control's name either way. Opening or closing a row (a tool card, a thinking row, a command card) or a process group moves the height frame by frame, really pushing the content below away or pulling it back. The door only rolls the stretch the reader can see, so any length moves at the same speed, and a body holding several cards rolls as one door. A message the reader sent that the conversation cannot spare the room for is held under a cap with its bottom edge softened, and the Show the whole message control under it hands the whole message back; once he presses it, that message keeps what he chose for the rest of the session.
28
- - **The line saying what the model is doing**: While a turn runs, the line at the end of the conversation is no longer a fixed "Deep diving for N s ···": it names what that turn is doing now — "Thinking…", "Preparing a tool call…", "Running tools…", "Writing…" — with the time the turn has taken beside it in the host's own units. Three of those states say something more: a call in flight names the file it works on ("Reading app.js", "Editing notes.md", "Writing out.txt" — the file's own name); a command call declares a description in its arguments (the host requires one saying what the command does), and the line writes it as the model wrote it ("Regenerate the changelog": the first line); and reasoning carrying a continuous clause hands the line the model's own words ("Checking the file is true": from the participle to that clause's end, with where a sentence ends left to the page's own sentence rules, so a dot inside a file name or a version number does not cut it; a negated clause, a plan the model has not started, anything inside a quotation and reasoning carrying no clause are passed over — a model quoting a sentence it read, the line's own waiting word among them, is not saying what it is doing; and "Thinking…" where there is none). All three are carried whole: how much of one shows is the width this line itself has, and past that the words are clipped with an ellipsis while the clock and the badge keep their places. The Conversation tab's Waiting-line detail choice set to Simple reads none of these specifics and names the bare states alone; Precise (the default) reads them as written. The line follows the host's own publishes, so a call is read the moment it starts running; every wording written is locked for a second, and the pass that finds the lock run out writes the newest state of that moment — whatever came and went inside the second is passed over, so a turn that moves quickly still changes the line at most once a second. A call's own words are the one thing the lock does not pass over: a small file read inside the second is written as soon as the lock ends, ahead of the state of that moment. The model's own clause has a rule of its own: the stretches between two of them, where the reasoning reads as the bare thinking state or as nothing at all, do not take it off the line — it stands until the next intent arrives, whether that is a newer clause, a call's own words, or a state such as writing; with the Precise status line switched off no clause is read at all, so nothing stands. A wording that changes runs transitions.dev's "Text states swap": the old one blurs and fades upward, the new one rises from below, and the box takes the arriving wording's width in one move, so the clock beside it travels to its new place rather than jumping twice. Where no state can be read at all the line stands on that brand's own word — the same one it says while the model is thinking: the skin's own "Thinking…" under the Claude brand, the host's own "Deep diving" under the DeepSeek brand — and once the model has been silent for ten seconds "No response yet" appears beside the clock, sliding onto the line from below and to the left while it pops out of nothing, and shrinking away as soon as the model speaks. The line sweeps — the Motion tab can give it a colour wash that moves through the letters instead — and the host's whale, which is DeepSeek's own character, gives way under the Claude brand to the skin's own loader: three 4px dots in the accent in force, which bounce the way the snippet has them while the model thinks (each rising 8px and flattening as it leaves the floor, half a second a bounce with the second dot starting two fifths of the period behind the first and the third three fifths) and take a second motion once the turn writes or works — each dot walking its own line, three lines 120° apart with one of them run the other way, the dot largest at either end and smallest as it crosses the middle, 1.25s a round trip with as long spent going out as coming back; the two motions never cut: the lane leaving fades each of its dots out where its own motion next turns back — off the floor for a bounce, off a far end for a walk — and the lane arriving fades each of its dots in where that motion next carries it, each fade over one of its own legs, so no dot is ever moved to a pose its motion does not carry; a motion stands for 2s before the next may take it over, so a state that comes and goes inside that stretch leaves it standing, while under the other brands the host's whale tail stands; the host's screen-reader announcement stays either way; wording wider than the room this line has is cut with an ellipsis while the clock and the badge keep their places; with Animation set to Reduced the wording is written at once, with none of those three phases. As long as the conversation follows its tail the line rests above the composer, so content arriving below no longer drags it around; scrolling back yourself leaves it travelling with the content. When a plugin hides the host wording and provides visible replacement text in the same content container, the theme yields its waiting line and restores it when the takeover ends; other chat animations keep running.
28
+ - **The line saying what the model is doing**: While a turn runs, the line at the end of the conversation is no longer a fixed "Deep diving for N s ···": it names what that turn is doing now — "Thinking…", "Preparing a tool call…", "Running tools…", "Writing…" — with the time the turn has taken beside it in the host's own units. Three of those states say something more: a call in flight names the file it works on ("Reading app.js", "Editing notes.md", "Writing out.txt" — the file's own name); a command call declares a description in its arguments (the host requires one saying what the command does), and the line writes it as the model wrote it ("Regenerate the changelog": the first line); and reasoning carrying a continuous clause hands the line the model's own words ("Checking the file is true": from the participle to that clause's end, with where a sentence ends left to the page's own sentence rules, so a dot inside a file name or a version number does not cut it; a negated clause, a plan the model has not started, anything inside a quotation and reasoning carrying no clause are passed over — a model quoting a sentence it read, the line's own waiting word among them, is not saying what it is doing; and "Thinking…" where there is none). All three are carried whole: how much of one shows is the width this line itself has, and past that the words are clipped with an ellipsis while the clock and the badge keep their places. The Conversation tab's Waiting-line detail choice set to Simple reads none of these specifics and names the bare states alone; Precise (the default) reads them as written. The line follows the host's own publishes, so a call is read the moment it starts running; every wording written is locked for a second, and the pass that finds the lock run out writes the newest state of that moment — whatever came and went inside the second is passed over, so a turn that moves quickly still changes the line at most once a second. A call's own words are the one thing the lock does not pass over: a small file read inside the second is written as soon as the lock ends, ahead of the state of that moment. The model's own clause has a rule of its own: the stretches between two of them, where the reasoning reads as the bare thinking state or as nothing at all, do not take it off the line — it stands until the next intent arrives, whether that is a newer clause, a call's own words, or a state such as writing; with the Precise status line switched off no clause is read at all, so nothing stands. A wording that changes runs transitions.dev's "Text states swap": the old one blurs and fades upward, the new one rises from below, and the box takes the arriving wording's width in one move, so the clock beside it travels to its new place rather than jumping twice. Where no state can be read at all the line stands on that brand's own word — the same one it says while the model is thinking: the skin's own "Thinking…" under the Claude brand, the host's own "Deep diving" under the DeepSeek brand — and once the model has been silent for ten seconds "No response yet" appears beside the clock, sliding onto the line from below and to the left while it pops out of nothing, and shrinking away as soon as the model speaks. The line sweeps — the Motion tab can give it a colour wash that moves through the letters instead — and the host's whale, which is DeepSeek's own character, gives way under the Claude brand to the skin's own loader: three 4px dots in the accent in force, which bounce the way the snippet has them while the model thinks (each rising 8px and flattening as it leaves the floor, half a second a bounce with the second dot starting two fifths of the period behind the first and the third three fifths) and take a second motion once the turn writes or works — each dot walking its own line, three lines 120° apart with one of them run the other way, the dot largest at either end and smallest as it crosses the middle, 1.25s a round trip with as long spent going out as coming back; the two motions never cut: the lane leaving fades each of its dots out where its own motion next turns back — off the floor for a bounce, off a far end for a walk — and the lane arriving fades each of its dots in where that motion next carries it, each fade over one of its own legs, so no dot is ever moved to a pose its motion does not carry; a motion stands for 2s before the next may take it over, so a state that comes and goes inside that stretch leaves it standing, while under the other brands the host's whale tail stands; the host's screen-reader announcement stays either way; wording wider than the room this line has is cut with an ellipsis while the clock and the badge keep their places; with Animation set to Reduced the wording is written at once, with none of those three phases. While the chat area's scrolling animation is on and the conversation follows its tail, the line rests above the composer, so content arriving below no longer drags it around; scrolling back yourself leaves it travelling with the content. When a plugin hides the host wording and provides visible replacement text in the same content container, the theme yields its waiting line and restores it when the takeover ends; other chat animations keep running.
29
29
  - **New text fades in**: Characters arriving in a streaming answer start faint and settle, staggered slightly by arrival order; a block arriving whole, a burst of thousands of characters and text that just reflowed from a fold stay solid. The Motion tab offers Fade in and Appears at once, each with a preview card, shipped on Appears at once.
30
30
  - **File operation rows**: A read, edit or write of a file carries the `+n -m` tail and an expandable diff card or read window, and its path opens the file; the calls on one file inside one process group stand as a single row whose icon and title move on with the file's last operation and whose tail is their change total, turning character by character as each change lands, and opening that row reads every change — or the window it was last read at when nothing changed; a failed or interrupted row keeps its verdict.
31
31
  - **Send flight**: On submission the composer card lifts and narrows into the bubble as it travels, the flying copy carrying the bubble's colour from its first frame and its words re-flowing into the shape; it meets the message row, where the real bubble shows underneath and the flying copy fades out, so the words sharpen into place.
package/docs/FEATURES.md CHANGED
@@ -12,7 +12,7 @@
12
12
  - **水波纹字符背景**:新会话页的背景是一片等宽字体的数字与字母,每秒重绘两次,被缓缓漂移的云层遮住,只在云层稀薄处隐约可见。点击页面任意位置会荡开水波:波速在点击处最快、越远越慢,环越走越细;被波扫过的字符显现出来,波前染成蓝色,尾迹留下灰色并慢慢淡去。设置页「外观」页首页版面下有一个同名开关,默认关闭,标为实验性。
13
13
  - **吉祥物**:输入框上沿站着一只像素小伙伴,随智能体的工作状态换动画(思考、写回答与调用工具、多个会话同时工作、子代理、等你操作、压缩上下文、完成、失败、睡着)。「跟随品牌」在 Claude 品牌下是像素螃蟹,在 DeepSeek 品牌下是小鲸鱼 Deepy,也可以固定选一个或者关闭;「出现位置」决定它只在新会话页出现,还是新会话页和对话页都出现。
14
14
  - **权限控件**:输入区的权限菜单在经典首页换成一排分段按钮,工作台首页与对话页是一枚按钮加一张档位卡片,与输入区其余选择器同一形制;档位以宿主的目录为准,别的插件加的档位也在里面;新会话页上显示新会话会用的那一档。
15
- - **会话数字**:会话统计与 Token 用量随宿主的数据实时更新,默认收进上下文计量那张弹层:里面是宿主自己的上下文行,后面接上这一段会话的数字明细——轮数与步数、输出速度、读入与写回的 tokens、缓存命中率。也可以选「独立成行」,把这些数字写在输入卡片下面单独一行、末尾就是那枚计量饼,按一下那一行同样开合这张弹层(悬停开合只归那枚饼)。数字接到新读数就从眼前的数连续计数到新值,答案流式输出期间接连更新时从当时的值接着走;写回的那一数还按流式文字估算着上涨,这一步结算时换成宿主给出的真实值;切换会话时也从上一段的数字计数过去,弹层里的数字同样这样计数;各段之间没有分隔符号、只靠间距分开,缓存命中那一截的色带只染数字与百分号,计量饼按占用自己取色。
15
+ - **会话数字**:会话统计与 Token 用量随宿主的数据实时更新,默认收进上下文计量那张弹层:里面是宿主自己的上下文行,后面接上这一段会话的数字明细——轮数与步数、输出速度、读入与写回的 tokens、缓存命中率。也可以选「独立成行」,把这些数字写在输入卡片下面单独一行、末尾就是那枚计量饼,按一下那一行同样开合这张弹层(悬停开合只归那枚饼)。数字接到新读数就从眼前的数连续计数到新值,答案流式输出期间接连更新时从当时的值接着走;写回的那一数还按流式文字估算着上涨,工具调用的参数不上页面,每出现一行调用另按一行计入,这一步结算时换成宿主给出的真实值;切换会话时也从上一段的数字计数过去,弹层里的数字同样这样计数;各段之间没有分隔符号、只靠间距分开,缓存命中那一截的色带只染数字与百分号,计量饼按占用自己取色。
16
16
  - **峰谷电表**:模型选择器的每一行标出该模型此刻的峰谷:峰价、谷价与限时活动三种状态各有自己的图标,颜色表示贵还是便宜,并跟上距离切换还有多久;悬停读到完整的一条,讲出此刻的判定与切换后的状态。各家供应商按各自时区的作息判定,法定节假日整日算谷价,跨零点与夏令时都按真实时刻计算。
17
17
  - **模型选择器**:输入区的模型菜单换成两级卡片:第一级是官方服务与你挑的快捷供应商,每个模型带厂商标志与一句说明,第二级是其余模型。
18
18
  - **工作强度**:模型旁边有一个自己的工作强度按钮,点开是一条滑杆;它跟着模型选择器一起开关,因为宿主把工作强度放在自己的模型菜单里。
@@ -25,7 +25,7 @@
25
25
  - **对话导航**:对话区右侧那列短横线每一轮一条,跟着你读到的位置走。鼠标碰到它,它就展开成一张列表:每一行写着开启这一轮的那条消息,正好落在它那条短横线原来的位置上——你正在读的那一轮还在原处,鼠标下面还是刚才那一轮;滚轮上下翻,点一行页面滑到那一轮,还没加载的早期对话先加载再跳;指针停在列表上时,对话区顶部的对话 / 轨迹标签照常显示。Alt+↑ / Alt+↓ 跳到上一轮或下一轮,连按会一轮一轮接着走;输入框里有草稿时这两个键留给输入框。跳到的那一轮开头会闪一条短横线。同时装着 [dsh-plugin-msg-nav](https://github.com/SherUnlocked-4869/dsh-plugin-msg-nav) 时,Alt+↑ / Alt+↓ 留给它。
26
26
  - **聊天区跟随**:思考行收起、工具调用行出现这些结构时刻,贴着底部的读者被交还给系统自己的跟随,内容成片到达时不再停在离底部几十像素的地方;「标准」与「简洁」档里封顶的过程组(思考与工具输出收在一个带滚动条的组体里)同样补到底部。补到底部走的是曲线:零散到达的字收得住尾巴,成片涌进的文字以一段稳速滑过去,再落到末尾。流式输出期间位置由宿主自己的跟随写到末尾,新长出的内容从屏幕下缘平滑滑上来,上方文字不再一帧跳上去,状态行停在原处不动;这段滑动由显卡完成,不占用页面的布局,多个会话同时输出时也不加重负担。你自己发出的消息不走这条曲线:宿主把它滚进视野的那一下照旧一步到位。读者自己滚动离开底部之后,插件不再插手,直到他自己回到底部。
27
27
  - **自动开合与卷帘门**:模型还在思考时思考行开着,思考停下就收回去;运行中的过程组自动展开,这一段结束再收起。读者自己按过的行或组在当时的阶段里不再被改动。开着的那段思考停在一个跟着它长高的窗口里:窗口先是和文本一样高,长到推理能到的最大高度就停在那里,只有到了这一刻文字才一档一档往上走两行,走到最新一行就停住,上下边缘渐隐,也不再往下推整列对话;推理一停,窗口撤下,读者打开这一行读到的是完整文本,「动画」为「减弱」时不设这个窗口。过程组的标题改写成这一组装了什么:「执行 2 次思考,调用 1 次工具」,没有的项不写,数字随内容增加逐位滚动,这一段还在进行时整行带着宿主那样的扫光;放不下整句时改用「思考×2 · 工具×1」,位置宽回来再换回整句,控件的可访问名字始终是整句。点开或收起一行(工具卡片、思考行、命令卡片)以及过程组时,高度逐帧变化,下方内容被真的推开或收回;门只走读者看得见的那一段,内容再长也是同一速度,多张卡片的展开体整扇门一起走。读者自己发出的消息装不下时收在一个上限高度里,下缘渐隐,气泡下面的「展开全文」把整条消息放回来;按过一次之后,这条消息在本次会话里保持读者选的样子。
28
- - **模型正在做什么的那一行**:轮次进行中,对话末尾那一行不再是固定的「深度求索中,用时 N 秒 ···」,而是写出这一轮此刻在做的事:「正在思考」「正在准备工具调用」「正在调用工具」「正在写回答」,后面跟着这一轮已用的时间(用宿主自己的单位)。三种状态说的是具体的东西:调用在跑时写出它操作的文件(「正在读取 app.js」「正在编辑 notes.md」「正在写入 out.txt」,只取文件名);命令调用在参数里声明了这条命令做什么(宿主要求声明),这一行把它原样写出(「Regenerate the changelog」:只取第一行);推理正文里出现进行时从句时把模型自己那句话写出来(「Checking the file is true」:从动词截到这一句的句末;句子在哪里断开交给页面自己的句子规则,所以文件名与版本号里的点号不算句末;否定的句子、还没动手的打算、引号里的话与读不出从句的正文都不取——模型引用它读到的一句话、甚至引用这一行自己那个等待词时,那不是它在说自己正在做什么;取不到就回到「正在思考」)。这三种说法都整句带出来,不按字数截断:放得下多少由这一行自己的宽度决定,放不下时在断开处画省略号,计时与徽标留在原处。「对话」页的「状态行描述」选「简洁」时这些具体内容都不读,只说状态本身;选「精确」(默认)照旧。这一行跟着宿主自己的发布走,调用刚开始跑就被读到;每种说法写上之后锁住 1 秒,这一秒里状态再换也不动,锁一过就直接写当时最新的状态(中间来过的那些不补演),因此一个轮次里状态换得再快,这一行也只一秒换一次;被锁跨过去的调用说法不在此列——一次读完的小文件调用会在锁一过先补上它,再轮到当时的状态。模型自己那句从句另有一条:两次从句之间读不出东西的那几拍(正在思考,或刚起一步还没写下什么)不把它换掉,它一直站到下一次意图到达为止——新的从句、调用自带的说法,或写回答这类状态;「精确状态行」关掉时本来就不读从句,也就无所谓站住。说法换掉时旧的向上淡出、新的从下方升起(来自 transitions.dev 的「Text states swap」);说法盒子换宽度时,旁边的计时随之滑到新位置,不做两次跳变;一直读不出状态时这一行说这个品牌自己的那一个词,与模型思考时说的同一个:Claude 品牌下是「正在思考」,DeepSeek 品牌下是宿主自己的「深度求索中」,不因为读不出状态而换一次说法;模型连续 10 秒没有开口时,计时后面多一枚「暂未响应」:它从左下方滑上这一行,同时从无到有弹出来,模型一开口就缩回消失。这一行带扫光(「动效」页可换成让文字本身流动着变色的那一档);宿主的小鲸鱼是 DeepSeek 自己的形象,Claude 品牌下它让位给本插件自己的加载点:三枚 4px 圆点用当时生效的主题色,模型思考时它们照旧弹跳(各自弹起 8 像素、离地时压扁,半秒一次,第二枚与第三枚分别错开五分之二与五分之三个周期),这一轮改成写回答或调用工具时换另一套走法——三颗点各沿一条直线来回,三条直线彼此相差 120°、其中一条反着走,球在两端最大、过中点最小,一个来回 1.25 秒、去程与回程一样长;两套走法之间不硬切:旧的那一列各自淡出、新的那一列各自淡入,每颗球都在自己动作里的那一拍上开始——跳球从落地回弹那一刻开始淡出、到最高点淡完,从最高点开始淡入、到落地淡完;走路从线的一端开始淡出、到中点淡完,从中点开始淡入、到另一端淡完,没有哪颗球被挪到别的动作的位置上;一个动作站满 2 秒才允许下一套接手,这段时间里来了又走的状态不打扰它;其余品牌下宿主的鲸鱼尾照旧,读屏播报也照旧;说法比这一行放得下的宽度更长时,它在这个宽度上截断并画省略号,计时与徽标留在原处;「动画」设为「减弱」时说法直接换掉,不做上面那三段。只要对话还在跟随末尾,这一行就停在输入框上方,不断追加的内容不再带着它上下移动;读者自己往回翻看时它照常随内容走。同一内容容器内,第三方插件隐藏宿主文案并提供可见替代文字时,主题等待行自动让位;接管结束后恢复,其他聊天动效继续运行。
28
+ - **模型正在做什么的那一行**:轮次进行中,对话末尾那一行不再是固定的「深度求索中,用时 N 秒 ···」,而是写出这一轮此刻在做的事:「正在思考」「正在准备工具调用」「正在调用工具」「正在写回答」,后面跟着这一轮已用的时间(用宿主自己的单位)。三种状态说的是具体的东西:调用在跑时写出它操作的文件(「正在读取 app.js」「正在编辑 notes.md」「正在写入 out.txt」,只取文件名);命令调用在参数里声明了这条命令做什么(宿主要求声明),这一行把它原样写出(「Regenerate the changelog」:只取第一行);推理正文里出现进行时从句时把模型自己那句话写出来(「Checking the file is true」:从动词截到这一句的句末;句子在哪里断开交给页面自己的句子规则,所以文件名与版本号里的点号不算句末;否定的句子、还没动手的打算、引号里的话与读不出从句的正文都不取——模型引用它读到的一句话、甚至引用这一行自己那个等待词时,那不是它在说自己正在做什么;取不到就回到「正在思考」)。这三种说法都整句带出来,不按字数截断:放得下多少由这一行自己的宽度决定,放不下时在断开处画省略号,计时与徽标留在原处。「对话」页的「状态行描述」选「简洁」时这些具体内容都不读,只说状态本身;选「精确」(默认)照旧。这一行跟着宿主自己的发布走,调用刚开始跑就被读到;每种说法写上之后锁住 1 秒,这一秒里状态再换也不动,锁一过就直接写当时最新的状态(中间来过的那些不补演),因此一个轮次里状态换得再快,这一行也只一秒换一次;被锁跨过去的调用说法不在此列——一次读完的小文件调用会在锁一过先补上它,再轮到当时的状态。模型自己那句从句另有一条:两次从句之间读不出东西的那几拍(正在思考,或刚起一步还没写下什么)不把它换掉,它一直站到下一次意图到达为止——新的从句、调用自带的说法,或写回答这类状态;「精确状态行」关掉时本来就不读从句,也就无所谓站住。说法换掉时旧的向上淡出、新的从下方升起(来自 transitions.dev 的「Text states swap」);说法盒子换宽度时,旁边的计时随之滑到新位置,不做两次跳变;一直读不出状态时这一行说这个品牌自己的那一个词,与模型思考时说的同一个:Claude 品牌下是「正在思考」,DeepSeek 品牌下是宿主自己的「深度求索中」,不因为读不出状态而换一次说法;模型连续 10 秒没有开口时,计时后面多一枚「暂未响应」:它从左下方滑上这一行,同时从无到有弹出来,模型一开口就缩回消失。这一行带扫光(「动效」页可换成让文字本身流动着变色的那一档);宿主的小鲸鱼是 DeepSeek 自己的形象,Claude 品牌下它让位给本插件自己的加载点:三枚 4px 圆点用当时生效的主题色,模型思考时它们照旧弹跳(各自弹起 8 像素、离地时压扁,半秒一次,第二枚与第三枚分别错开五分之二与五分之三个周期),这一轮改成写回答或调用工具时换另一套走法——三颗点各沿一条直线来回,三条直线彼此相差 120°、其中一条反着走,球在两端最大、过中点最小,一个来回 1.25 秒、去程与回程一样长;两套走法之间不硬切:旧的那一列各自淡出、新的那一列各自淡入,每颗球都在自己动作里的那一拍上开始——跳球从落地回弹那一刻开始淡出、到最高点淡完,从最高点开始淡入、到落地淡完;走路从线的一端开始淡出、到中点淡完,从中点开始淡入、到另一端淡完,没有哪颗球被挪到别的动作的位置上;一个动作站满 2 秒才允许下一套接手,这段时间里来了又走的状态不打扰它;其余品牌下宿主的鲸鱼尾照旧,读屏播报也照旧;说法比这一行放得下的宽度更长时,它在这个宽度上截断并画省略号,计时与徽标留在原处;「动画」设为「减弱」时说法直接换掉,不做上面那三段。「聊天区滚动动画」开着、对话还在跟随末尾时,这一行停在输入框上方,不断追加的内容不再带着它上下移动;读者自己往回翻看时它照常随内容走。同一内容容器内,第三方插件隐藏宿主文案并提供可见替代文字时,主题等待行自动让位;接管结束后恢复,其他聊天动效继续运行。
29
29
  - **新文字淡入**:流式回答里新出现的字符先淡后实,并按到达次序略作错开;整段一次到达的内容、几千字的突发与刚被折叠重排过的文字保持本色。设置页的「动效」页有「淡入」与「直接出现」两档,各带一张预览卡,默认「直接出现」。
30
30
  - **文件操作行**:一个文件的读取、编辑与写入带着行尾的 `+n -m`、可展开的改动卡片或读取窗口,路径可点开文件;同一个文件在同一个过程组里的多次调用读成一行,行首的图标与标题跟着最后一次操作换新,行尾的数字是这些改动的累计值、随每次改动到达逐位翻页,展开这一行读到全部改动(只被读取过时读到这一次读取的窗口);失败与中断的行保留裁决信息。
31
31
  - **聊天气泡动效**:提交消息时输入卡片浮起、一路收成那条气泡:飞行的这一份从第一帧就是气泡的颜色,草稿里的字跟着形状重新排,最后接上真实的消息行——真实气泡在下面先显示出来,飞行的那份淡出,文字逐渐变清晰。
@@ -43,7 +43,7 @@ In the settings dialog, this page's heading row ends with a GitHub mark; pressin
43
43
 
44
44
  **Alongside other theme plugins**: with Colours and Typefaces set to Follow the host, the skin no longer rewrites the host's colours and fonts and keeps only its layout and controls; the colours are left to DSH itself, or to another theme plugin enabled at the same time. With [dsh-wallpaper-engine](https://github.com/elysia395/dsh-wallpaper-engine), for example, the wallpaper shows through the sidebar and the conversation, and the skin's own popovers take that plugin's glass, translucent and blurring the picture behind them. **Alongside [dsh-chat-ux](https://github.com/alm-allen/dsh-chat-ux)**: that plugin implements the same chat-area interactions (the rolling door, automatic folding, the token fade, file change rows, the send flight, the drawn caret), and two copies of them intercept each other's clicks and press the same controls. So this skin stands down when it sees that plugin: the Chat-area animations row on the settings page's Conversation tab and the Composer caret motion and New-text fade rows on the Motion tab have their controls disabled while each still shows the value you set, with a line underneath in the accent colour reading "Managed by dsh-chat-ux". Your settings are not rewritten, and they take effect as they are once dsh-chat-ux is removed. **Alongside a skin from the Skin Center**: the Skin Center lists this plugin as one of its selectable looks, and picking it hands the whole page to this plugin; picking another skin there hands the page back whole — the sidebar, the conversation, the composer and this skin's settings page all leave, and that skin and the host paint the page. Picking this plugin's row in the Skin Center brings them all back.
45
45
 
46
- **Chat-area follow**: at the structural moments — a thinking row folding, a tool call row arriving — a reader sitting at the bottom is handed back to the host's own follow, instead of being left tens of pixels short by the burst of content; a process group capped in the Standard and Compact tiers (thinking and tool output kept in one scrolling body) is caught up the same way. Catching up runs on a curve: a trickle of characters settles softly and a burst glides at one steady speed before landing. While content streams, the host's own follow keeps the position at the end and the newly grown content slides up from the bottom edge instead of the text above it jumping in a single frame, with the status line standing still; the slide runs on the graphics card and takes no layout, so several sessions streaming at once cost no more for it. A message you send does not go through it: the host's scroll to bring it into view lands at once. Once the reader scrolls away from the bottom himself, the plugin stays out of it until he returns.
46
+ **Chat-area follow**: the first of the three things Chat-area scrolling animation covers; what it does is the same entry in [Features](FEATURES.en.md).
47
47
 
48
48
  **Automatic folding**: a thinking row opens while the model reasons and folds back when it stops; a running process group opens and folds back once that piece of work ends. A row or group the reader pressed himself keeps what he chose for that phase.
49
49
 
@@ -51,7 +51,7 @@ In the settings dialog, this page's heading row ends with a GitHub mark; pressin
51
51
 
52
52
  **Counted process headers**: a process group's header says what the group holds, in place of the host's list of activities — "2 thoughts, 1 tool call". Empty figures are left out, each number rolls as the work grows, and the whole line sweeps the way the host's words do while that piece of work runs. A header without the room for the sentence (a narrow window, a narrow row) falls back to the compact figures, `Thinking×2 · Tools×1`, and takes the sentence back when the room returns; the control's accessible name is the sentence either way.
53
53
 
54
- **The line saying what the model is doing**: while a turn runs, the line at the end of the conversation is no longer a fixed "Deep diving for N s ···": it names what that turn is doing now — "Thinking…", "Preparing a tool call…", "Running tools…", "Writing…" — with the time the turn has taken beside it in the host's own units. Two of those states say something more: a call in flight names the file it works on ("Reading app.js", "Editing notes.md", "Writing out.txt" — the file's own name), and reasoning carrying a continuous clause hands the line the model's own words ("Checking the file is true": from the participle to that clause's end, with where a sentence ends left to the page's own sentence rules, so a dot inside a file name or a version number does not cut it; a negated clause, a plan the model has not started, anything inside a quotation and reasoning carrying no clause are passed over — a model quoting a sentence it read, the line's own waiting word among them, is not saying what it is doing; and "Thinking…" where there is none). Both are carried whole: how much of one shows is the width this line itself has, and past that the words are clipped with an ellipsis while the clock and the badge keep their places. The line follows the host's own publishes, so a call is read the moment it starts running; every wording written is locked for a second, and the pass that finds the lock run out writes the newest state of that moment — whatever came and went inside the second is passed over, so a turn that moves quickly still changes the line at most once a second. A call's own words are the one thing the lock does not pass over: a small file read inside the second is written as soon as the lock ends, ahead of the state of that moment. The model's own clause has a rule of its own: the stretches between two of them, where the reasoning reads as the bare thinking state or as nothing at all, do not take it off the line — it stands until the next intent arrives, whether that is a newer clause, a call's own words, or a state such as writing; with the Precise status line switched off no clause is read at all, so nothing stands. A wording that changes runs transitions.dev's "Text states swap": the old one blurs and fades upward while the new one rises from below, the two travelling together and the change over in about 0.2 s, and the box takes the arriving wording's width in one move, so the clock beside it travels to its new place (about 0.24 s) rather than jumping twice. Where no state can be read at all the line stands on that brand's own word — the same one it says while the model is thinking: the skin's own "Thinking…" under the Claude brand, the host's own "Deep diving" under the DeepSeek brand — and once the model has been silent for ten seconds "No response yet" appears beside the clock. The line sweeps, and the host's whale, which is DeepSeek's own character, gives way under the Claude brand to the skin's own loader: three 4px dots in the accent in force, which bounce the way the snippet has them while the model thinks (each rising 8px and flattening as it leaves the floor, half a second a bounce with the second dot starting two fifths of the period behind the first and the third three fifths) and take a second motion once the turn writes or works — each dot walking its own line, three lines 120° apart with one of them run the other way, the dot largest at either end and smallest as it crosses the middle, 1.25s a round trip with as long spent going out as coming back; the two motions never cut: the lane leaving fades each of its dots out where its own motion next turns back — off the floor for a bounce, off a far end for a walk — and the lane arriving fades each of its dots in where that motion next carries it, each fade over one of its own legs, so no dot is ever moved to a pose its motion does not carry; a motion stands for 2s before the next may take it over, so a state that comes and goes inside that stretch leaves it standing, while under the other brands the host's whale tail stands and the host's screen-reader announcement stays either way; wording wider than the room this line has is cut with an ellipsis while the clock and the badge keep their places; with Animation set to Reduced the wording is written at once, with neither half of the swap. As long as the conversation follows its tail the line rests above the composer, so content arriving below no longer drags it around; scrolling back yourself leaves it travelling with the content.
54
+ **The line saying what the model is doing**: while a turn runs, the line at the end of the conversation is no longer a fixed "Deep diving for N s ···": it names what that turn is doing now — "Thinking…", "Preparing a tool call…", "Running tools…", "Writing…" — with the time the turn has taken beside it in the host's own units. Two of those states say something more: a call in flight names the file it works on ("Reading app.js", "Editing notes.md", "Writing out.txt" — the file's own name), and reasoning carrying a continuous clause hands the line the model's own words ("Checking the file is true": from the participle to that clause's end, with where a sentence ends left to the page's own sentence rules, so a dot inside a file name or a version number does not cut it; a negated clause, a plan the model has not started, anything inside a quotation and reasoning carrying no clause are passed over — a model quoting a sentence it read, the line's own waiting word among them, is not saying what it is doing; and "Thinking…" where there is none). Both are carried whole: how much of one shows is the width this line itself has, and past that the words are clipped with an ellipsis while the clock and the badge keep their places. The line follows the host's own publishes, so a call is read the moment it starts running; every wording written is locked for a second, and the pass that finds the lock run out writes the newest state of that moment — whatever came and went inside the second is passed over, so a turn that moves quickly still changes the line at most once a second. A call's own words are the one thing the lock does not pass over: a small file read inside the second is written as soon as the lock ends, ahead of the state of that moment. The model's own clause has a rule of its own: the stretches between two of them, where the reasoning reads as the bare thinking state or as nothing at all, do not take it off the line — it stands until the next intent arrives, whether that is a newer clause, a call's own words, or a state such as writing; with the Precise status line switched off no clause is read at all, so nothing stands. A wording that changes runs transitions.dev's "Text states swap": the old one blurs and fades upward while the new one rises from below, the two travelling together and the change over in about 0.2 s, and the box takes the arriving wording's width in one move, so the clock beside it travels to its new place (about 0.24 s) rather than jumping twice. Where no state can be read at all the line stands on that brand's own word — the same one it says while the model is thinking: the skin's own "Thinking…" under the Claude brand, the host's own "Deep diving" under the DeepSeek brand — and once the model has been silent for ten seconds "No response yet" appears beside the clock. The line sweeps, and the host's whale, which is DeepSeek's own character, gives way under the Claude brand to the skin's own loader: three 4px dots in the accent in force, which bounce the way the snippet has them while the model thinks (each rising 8px and flattening as it leaves the floor, half a second a bounce with the second dot starting two fifths of the period behind the first and the third three fifths) and take a second motion once the turn writes or works — each dot walking its own line, three lines 120° apart with one of them run the other way, the dot largest at either end and smallest as it crosses the middle, 1.25s a round trip with as long spent going out as coming back; the two motions never cut: the lane leaving fades each of its dots out where its own motion next turns back — off the floor for a bounce, off a far end for a walk — and the lane arriving fades each of its dots in where that motion next carries it, each fade over one of its own legs, so no dot is ever moved to a pose its motion does not carry; a motion stands for 2s before the next may take it over, so a state that comes and goes inside that stretch leaves it standing, while under the other brands the host's whale tail stands and the host's screen-reader announcement stays either way; wording wider than the room this line has is cut with an ellipsis while the clock and the badge keep their places; with Animation set to Reduced the wording is written at once, with neither half of the swap. While the chat area's scrolling animation is on and the conversation follows its tail, the line rests above the composer, so content arriving below no longer drags it around; scrolling back yourself leaves it travelling with the content.
55
55
 
56
56
  **Send flight**: on submission the composer card lifts as it is and narrows into the bubble as it travels, its words re-flowing into the shape, landing on the message row: the real bubble shows underneath and the flying copy fades out, so the words sharpen into place.
57
57
 
@@ -69,8 +69,8 @@ In the settings dialog, this page's heading row ends with a GitHub mark; pressin
69
69
 
70
70
  **Ongoing conversations**: this row on the Motion tab decides how the sidebar marks a conversation that is still running, at the head of its row. Each of the two cards is one sidebar row as the sidebar draws it — the mark first, its title after — so the two differ in the mark alone; one press on a card changes the real row at once. Breathing light (the default) is a filled dot the size of an idle row's hollow circle, brightening and dimming in place; Turning ring is what earlier builds drew: a 10px ring whose track carries one brighter stretch around it. With Animation set to Reduced both stand still (the light at its brightest, the ring caught at one step), and the mark still reads as a row at work.
71
71
 
72
- **Conversation statistics position**: the session's eight figures have two places to live. Inside the context popover (the default) puts them in the panel that the meter's pie opens and leaves only the pie under the input card; On its own line writes the turns and steps, the output speed, the tokens read in, the tokens written back and the cache-hit share on a line of their own below the input card, with the pie itself at the end. A figure on that line counts from the value on show to a new reading (every step moves it; through a streaming answer the written-back figure climbs with the text that has arrived, by estimate, and takes the host's own number once that step settles), carries on from where it stands when another reading lands mid-count, and counts to another session's numbers from the ones it was showing; the popover's rows count the same way; the cache share's band marks its figure and percent sign alone, the words before them keeping the line's own tone — the share runs from red in the nineties to dark green at 99%, and the pie takes a colour between green at two fifths and red at four fifths. A window too narrow for the whole line makes it give way one step at a time: first the cache share's words, then the turns and steps, then the number beside the pie (the pie stays), then the tokens read in and written back as one total, and last the counts folded into k / M / B — and the same order gives them back when the window grows.
72
+ **Conversation statistics position**: the session's eight figures have two places to live. Inside the context popover (the default) puts them in the panel that the meter's pie opens and leaves only the pie under the input card; On its own line writes the turns and steps, the output speed, the tokens read in, the tokens written back and the cache-hit share on a line of their own below the input card, with the pie itself at the end. A figure on that line counts from the value on show to a new reading (every step moves it; through a streaming answer the written-back figure climbs with the text that has arrived, by estimate, and each tool call counts once since a call's arguments never reach the page, with the host's own number replacing the estimate once that step settles), carries on from where it stands when another reading lands mid-count, and counts to another session's numbers from the ones it was showing; the popover's rows count the same way; the cache share's band marks its figure and percent sign alone, the words before them keeping the line's own tone — the share runs from red in the nineties to dark green at 99%, and the pie takes a colour between green at two fifths and red at four fifths. A window too narrow for the whole line makes it give way one step at a time: first the cache share's words, then the turns and steps, then the number beside the pie (the pie stays), then the tokens read in and written back as one total, and last the counts folded into k / M / B — and the same order gives them back when the window grows.
73
73
 
74
- **Conversation navigator**: the column of short marks at the conversation's right edge holds one per turn and follows where you are reading. Reach it with the pointer and it opens into a list: each row carries the message that started its turn and sits exactly where that turn's mark was — the turn you are reading stays in place, and the turn under the pointer is still under it. The wheel scrolls the list and a click glides the page to the turn, loading earlier history first when it is not loaded yet; the Chat / Trajectory tabs at the top of the conversation stay up while the pointer is on the list. Alt+↑ / Alt+↓ jump to the previous or the next turn, and held or repeated they keep stepping; while the composer holds a draft the keys stay with it. The turn you land on flashes a short line over its start. With [dsh-plugin-msg-nav](https://github.com/SherUnlocked-4869/dsh-plugin-msg-nav) installed too, Alt+↑ / Alt+↓ stay with that plugin.
74
+ **Conversation navigator**: the column of short marks at the conversation's right edge, and the keys that jump to a turn; what it does is the same entry in [Features](FEATURES.en.md).
75
75
 
76
- **Mascot**: a pixel companion stands on the composer's top edge and changes its animation with what the agent is doing (thinking, writing and calling tools, several sessions at work, subagents, waiting on you, compacting the context, finished, failed, asleep). Follow the brand shows the pixel crab under Claude and Deepy the whale under DeepSeek; either can be picked for good, or none. Where it appears keeps it to the new-conversation page, or puts it in conversations as well.
76
+ **Mascot**: the pixel companion on the composer's top edge, and which pages it appears on; what it does is the same entry in [Features](FEATURES.en.md).
package/docs/SETTINGS.md CHANGED
@@ -43,7 +43,7 @@
43
43
 
44
44
  **与其他主题插件同时使用**:「配色」与「字体」选「跟随宿主」后,本插件不再改写宿主的颜色与字体,只保留布局和控件;颜色交给 DSH 自己,或者交给同时启用的其他主题插件。例如与 [dsh-wallpaper-engine](https://github.com/elysia395/dsh-wallpaper-engine) 一起用时,壁纸透过侧栏与对话区显示出来,插件自己的弹层随壁纸插件的玻璃效果变成半透明并模糊背后的画面。**与 [dsh-chat-ux](https://github.com/alm-allen/dsh-chat-ux) 同时使用时**:那个插件实现了同一批聊天区交互(卷帘门、自动开合、文字淡入、文件变更行、聊天气泡动效、插入符动效),两套同时生效会互相拦点击、抢同一批按钮。所以本插件在检测到它时让位:设置页「对话」页的「聊天区动画效果」与「动效」页的「光标动画」「新文字淡入」三行控件禁用,但仍显示你自己设的值,下面另起一行用强调色注明「该选项由 dsh-chat-ux 管理」;你的设置不会被改写,卸载 dsh-chat-ux 之后原样生效。**与皮肤中心里的皮肤同时使用时**:皮肤中心把本插件列为可选皮肤,选中它即把整页交给本插件;换选别的皮肤时本主题整页让出,侧栏、对话、输入区与设置页一并撤下,页面由那款皮肤与宿主自己画,在皮肤中心里本插件那一行选回本主题即恢复。
45
45
 
46
- **聊天区跟随**:思考行收起、工具调用行出现这些结构时刻,贴着底部的读者被交还给系统自己的跟随,内容成片到达时不再停在离底部几十像素的地方;「标准」与「简洁」档里封顶的过程组(思考与工具输出收在一个带滚动条的组体里)同样补到底部。补到底部走的是曲线:零散到达的字收得住尾巴,成片涌进的文字以一段稳速滑过去,再落到末尾。流式输出期间位置由宿主自己的跟随写到末尾,新长出的内容从屏幕下缘平滑滑上来,上方文字不再一帧跳上去,状态行停在原处不动;这段滑动由显卡完成,不占用页面的布局,多个会话同时输出时也不加重负担。你自己发出的消息不走这条曲线:宿主把它滚进视野的那一下照旧一步到位。读者自己滚动离开底部之后,插件不再插手,直到他自己回到底部。
46
+ **聊天区跟随**:「聊天区滚动动画」三样里的第一样;它做什么见[功能一览](FEATURES.md)里的同一条。
47
47
 
48
48
  **思考与过程自动开合**:模型还在思考时思考行开着,思考停下就收回去;运行中的过程组自动展开,这一段结束再收起。读者自己按过的行或组在当时的阶段里不再被改动。
49
49
 
@@ -51,7 +51,7 @@
51
51
 
52
52
  **过程组标题上的计数**:过程组的标题不再只写「执行了命令,已读取文件,已调用工具等」,而是写这一组装了什么,例如「执行 2 次思考,调用 1 次工具」;没有的项不写,数字随内容增加逐位滚动,这一段还在进行时整行带着与宿主同样的扫光。这一行放不下整句时(窗口窄、过程组所在的行窄)改用简洁写法「思考×2 · 工具×1」,位置宽回来再换回整句;控件的可访问名字始终是整句。
53
53
 
54
- **模型正在做什么的那一行**:轮次进行中,对话末尾那一行不再是固定的「深度求索中,用时 N 秒 ···」,而是写出这一轮此刻在做的事:「正在思考」「正在准备工具调用」「正在调用工具」「正在写回答」,后面跟着这一轮已用的时间(用宿主自己的单位)。两种状态说的是具体的东西:调用在跑时写出它操作的文件(「正在读取 app.js」「正在编辑 notes.md」「正在写入 out.txt」,只取文件名),推理正文里出现进行时从句时把模型自己那句话写出来(「Checking the file is true」:从动词截到这一句的句末;句子在哪里断开交给页面自己的句子规则,所以文件名与版本号里的点号不算句末;否定的句子、还没动手的打算、引号里的话与读不出从句的正文都不取——模型引用它读到的一句话、甚至引用这一行自己那个等待词时,那不是它在说自己正在做什么;取不到就回到「正在思考」)。这两种说法都整句带出来,不按字数截断:放得下多少由这一行自己的宽度决定,放不下时在断开处画省略号,计时与徽标留在原处。这一行跟着宿主自己的发布走,调用刚开始跑就被读到;每种说法写上之后锁住 1 秒,这一秒里状态再换也不动,锁一过就直接写当时最新的状态(中间来过的那些不补演),因此一个轮次里状态换得再快,这一行也只一秒换一次;被锁跨过去的调用说法不在此列——一次读完的小文件调用会在锁一过先补上它,再轮到当时的状态。模型自己那句从句另有一条:两次从句之间读不出东西的那几拍(正在思考,或刚起一步还没写下什么)不把它换掉,它一直站到下一次意图到达为止——新的从句、调用自带的说法,或写回答这类状态;「精确状态行」关掉时本来就不读从句,也就无所谓站住。说法换掉时旧的向上淡出、新的从下方升起,两段重叠着一同走完(整次约 0.2 秒,来自 transitions.dev 的「Text states swap」);说法盒子换宽度时,旁边的计时随之滑到新位置(约 0.24 秒),不做两次跳变;一直读不出状态时这一行说这个品牌自己的那一个词,与模型思考时说的同一个:Claude 品牌下「正在思考」,DeepSeek 品牌下宿主自己的「深度求索中」;模型连续 10 秒没有开口时,计时后面多一枚「暂未响应」。这一行带扫光;宿主的小鲸鱼是 DeepSeek 自己的形象,Claude 品牌下它让位给本插件自己的加载点:三枚 4px 圆点用当时生效的主题色,模型思考时它们照旧弹跳(各自弹起 8 像素并在离地时压扁,半秒一次,第二枚与第三枚分别错开五分之二与五分之三个周期),这一轮改成写回答或调用工具时换另一套走法——三颗点各沿一条直线来回,三条直线彼此相差 120°、其中一条反着走,球在两端最大、过中点最小,一个来回 1.25 秒、去程与回程一样长;两套走法之间不硬切:旧的那一列各自淡出、新的那一列各自淡入,每颗球都在自己动作里的那一拍上开始——跳球从落地回弹那一刻开始淡出、到最高点淡完,从最高点开始淡入、到落地淡完;走路从线的一端开始淡出、到中点淡完,从中点开始淡入、到另一端淡完,没有哪颗球被挪到别的动作的位置上;一个动作站满 2 秒才允许下一套接手,这段时间里来了又走的状态不打扰它;其余品牌下宿主的鲸鱼尾照旧,读屏播报也照旧;说法比这一行放得下的宽度更长时,它在这个宽度上截断并画省略号,计时与徽标留在原处;「动画」设为「减弱」时说法直接换掉,不做上面那两段。只要对话还在跟随末尾,这一行就停在输入框上方,不断追加的内容不再带着它上下移动;读者自己往回翻看时它照常随内容走。
54
+ **模型正在做什么的那一行**:轮次进行中,对话末尾那一行不再是固定的「深度求索中,用时 N 秒 ···」,而是写出这一轮此刻在做的事:「正在思考」「正在准备工具调用」「正在调用工具」「正在写回答」,后面跟着这一轮已用的时间(用宿主自己的单位)。两种状态说的是具体的东西:调用在跑时写出它操作的文件(「正在读取 app.js」「正在编辑 notes.md」「正在写入 out.txt」,只取文件名),推理正文里出现进行时从句时把模型自己那句话写出来(「Checking the file is true」:从动词截到这一句的句末;句子在哪里断开交给页面自己的句子规则,所以文件名与版本号里的点号不算句末;否定的句子、还没动手的打算、引号里的话与读不出从句的正文都不取——模型引用它读到的一句话、甚至引用这一行自己那个等待词时,那不是它在说自己正在做什么;取不到就回到「正在思考」)。这两种说法都整句带出来,不按字数截断:放得下多少由这一行自己的宽度决定,放不下时在断开处画省略号,计时与徽标留在原处。这一行跟着宿主自己的发布走,调用刚开始跑就被读到;每种说法写上之后锁住 1 秒,这一秒里状态再换也不动,锁一过就直接写当时最新的状态(中间来过的那些不补演),因此一个轮次里状态换得再快,这一行也只一秒换一次;被锁跨过去的调用说法不在此列——一次读完的小文件调用会在锁一过先补上它,再轮到当时的状态。模型自己那句从句另有一条:两次从句之间读不出东西的那几拍(正在思考,或刚起一步还没写下什么)不把它换掉,它一直站到下一次意图到达为止——新的从句、调用自带的说法,或写回答这类状态;「精确状态行」关掉时本来就不读从句,也就无所谓站住。说法换掉时旧的向上淡出、新的从下方升起,两段重叠着一同走完(整次约 0.2 秒,来自 transitions.dev 的「Text states swap」);说法盒子换宽度时,旁边的计时随之滑到新位置(约 0.24 秒),不做两次跳变;一直读不出状态时这一行说这个品牌自己的那一个词,与模型思考时说的同一个:Claude 品牌下「正在思考」,DeepSeek 品牌下宿主自己的「深度求索中」;模型连续 10 秒没有开口时,计时后面多一枚「暂未响应」。这一行带扫光;宿主的小鲸鱼是 DeepSeek 自己的形象,Claude 品牌下它让位给本插件自己的加载点:三枚 4px 圆点用当时生效的主题色,模型思考时它们照旧弹跳(各自弹起 8 像素并在离地时压扁,半秒一次,第二枚与第三枚分别错开五分之二与五分之三个周期),这一轮改成写回答或调用工具时换另一套走法——三颗点各沿一条直线来回,三条直线彼此相差 120°、其中一条反着走,球在两端最大、过中点最小,一个来回 1.25 秒、去程与回程一样长;两套走法之间不硬切:旧的那一列各自淡出、新的那一列各自淡入,每颗球都在自己动作里的那一拍上开始——跳球从落地回弹那一刻开始淡出、到最高点淡完,从最高点开始淡入、到落地淡完;走路从线的一端开始淡出、到中点淡完,从中点开始淡入、到另一端淡完,没有哪颗球被挪到别的动作的位置上;一个动作站满 2 秒才允许下一套接手,这段时间里来了又走的状态不打扰它;其余品牌下宿主的鲸鱼尾照旧,读屏播报也照旧;说法比这一行放得下的宽度更长时,它在这个宽度上截断并画省略号,计时与徽标留在原处;「动画」设为「减弱」时说法直接换掉,不做上面那两段。「聊天区滚动动画」开着、对话还在跟随末尾时,这一行停在输入框上方,不断追加的内容不再带着它上下移动;读者自己往回翻看时它照常随内容走。
55
55
 
56
56
  **聊天气泡动效**:提交消息时输入卡片原样浮起、一路收成那条气泡,草稿里的字跟着形状重新排,落地正好接上真实的消息行:真实气泡在下面先显示出来,飞行的那份淡出,文字逐渐变清晰。
57
57
 
@@ -69,8 +69,8 @@
69
69
 
70
70
  **侧栏进行中的标记**:「动效」页的这一项决定侧栏里正在进行的对话,行首那颗标记画成什么。两张卡片里各是一行侧栏的样子——标记在前、标题在后——所以两档的分别就是标记本身;点一张卡片立刻换过来,真实的那一行当场换掉。「呼吸灯」(默认)是一颗与空闲行的空心圈同大的实心圆点,原地明暗起伏;「滚动圆环」是此前版本的样子:一枚 10px 的圆环,轨道之上有一段更亮的部分转着走。「动画」设为「减弱」时两档都停住(圆点停在最亮处、圆环停在一格),仍看得出这一行在跑。
71
71
 
72
- **对话统计信息位置**:会话的八个数字有两个去处。「收进上下文」(默认)把它们放进那枚上下文计量饼的弹层,输入卡片下方只留那枚饼;「独立成行」把其中的轮数与步数、输出速度、读入的 tokens、写回的 tokens 与缓存命中率写在输入卡片下面单独一行,末尾就是那枚计量饼。这一行里的数字接到新读数就从眼前的数连续计数到新值(每走一个步骤都在动;流式输出期间写回的那一数按收到的文字估算着上涨,这一步结算时换成宿主的真实值),中途再接到新读数就从当时的值接着走,切换会话时也从上一段的数字计数到新一段的,弹层里的数字同样这样计数;缓存命中那一截的色带只染数字与百分号,前面的字样留在这一行自己的颜色,命中率从九成的红走到 99% 的深绿,计量饼按占用自己在四成的绿到八成的红之间取色。窗口窄到这一行放不下时它会依次让位:先去缓存那截的字样,再去轮数与步数,再去计量饼旁的数字(饼留下),然后把读入与写回合成一个合计,最后把数字折叠成 k / M / B;窗口宽回来时按同一顺序退回。
72
+ **对话统计信息位置**:会话的八个数字有两个去处。「收进上下文」(默认)把它们放进那枚上下文计量饼的弹层,输入卡片下方只留那枚饼;「独立成行」把其中的轮数与步数、输出速度、读入的 tokens、写回的 tokens 与缓存命中率写在输入卡片下面单独一行,末尾就是那枚计量饼。这一行里的数字接到新读数就从眼前的数连续计数到新值(每走一个步骤都在动;流式输出期间写回的那一数按收到的文字估算着上涨,工具调用的参数不上页面,每出现一行调用另按一行计入,这一步结算时换成宿主的真实值),中途再接到新读数就从当时的值接着走,切换会话时也从上一段的数字计数到新一段的,弹层里的数字同样这样计数;缓存命中那一截的色带只染数字与百分号,前面的字样留在这一行自己的颜色,命中率从九成的红走到 99% 的深绿,计量饼按占用自己在四成的绿到八成的红之间取色。窗口窄到这一行放不下时它会依次让位:先去缓存那截的字样,再去轮数与步数,再去计量饼旁的数字(饼留下),然后把读入与写回合成一个合计,最后把数字折叠成 k / M / B;窗口宽回来时按同一顺序退回。
73
73
 
74
- **对话导航**:对话区右侧那列短横线每一轮一条,跟着你读到的位置走。鼠标碰到它,它就展开成一张列表:每一行写着开启这一轮的那条消息,正好落在它那条短横线原来的位置上——你正在读的那一轮还在原处,鼠标下面还是刚才那一轮;滚轮上下翻,点一行页面滑到那一轮,还没加载的早期对话先加载再跳;指针停在列表上时,对话区顶部的对话 / 轨迹标签照常显示。Alt+↑ / Alt+↓ 跳到上一轮或下一轮,连按会一轮一轮接着走;输入框里有草稿时这两个键留给输入框。跳到的那一轮开头会闪一条短横线。同时装着 [dsh-plugin-msg-nav](https://github.com/SherUnlocked-4869/dsh-plugin-msg-nav) 时,Alt+↑ / Alt+↓ 留给它。
74
+ **对话导航**:对话区右侧那列短横线,以及跳到某一轮的快捷键;它做什么见[功能一览](FEATURES.md)里的同一条。
75
75
 
76
- **吉祥物**:输入框上沿站着一只像素小伙伴,随智能体的工作状态换动画(思考、写回答与调用工具、多个会话同时工作、子代理、等你操作、压缩上下文、完成、失败、睡着)。「跟随品牌」在 Claude 品牌下是像素螃蟹,在 DeepSeek 品牌下是小鲸鱼 Deepy,也可以固定选一个或者关闭;「出现位置」决定它只在新会话页出现,还是新会话页和对话页都出现。
76
+ **吉祥物**:输入框上沿那只像素小伙伴,以及它出现在哪些页面;它做什么见[功能一览](FEATURES.md)里的同一条。
package/docs/STYLE.md CHANGED
@@ -323,8 +323,9 @@ edit the JSON, not the table.
323
323
  | `--dsh-claude-ease-spring` | `cubic-bezier(0.34, 1.45, 0.64, 1)` | a small overshoot as something lands: the overtime badge popping in, a switch's knob bouncing past its end |
324
324
  | `--dsh-claude-ease-settle` | `cubic-bezier(0.22, 1, 0.36, 1)` | a surface or a page settling into place out of its anchor: menus and dialogs opening and closing, a settings page sliding, the overtime badge sliding onto its line, the greeting's lines rising |
325
325
  | `--dsh-claude-ease-host-sweep` | `steps(48, end)` | the band across the waiting line's words and a running process group's header |
326
- | `--dsh-claude-ease-damped-out` | `cubic-bezier(0.33, 1, 0.68, 1)` | a loader dot slowing into the end of its line: the damping the line motion carries, so a dot dwells at its turning point before it comes back |
327
- | `--dsh-claude-ease-damped-in` | `cubic-bezier(0.32, 0, 0.67, 0)` | a loader dot leaving the end of its line and gathering speed towards the middle |
326
+ | `--dsh-claude-ease-harmonic` | `cubic-bezier(0.37, 0, 0.63, 1)` | a loader dot walking its line from one end to the other, and its size between an end and the middle: a sine's simple harmonic, at rest at either end and fastest halfway |
327
+ | `--dsh-claude-ease-damped-out` | `cubic-bezier(0.33, 1, 0.68, 1)` | a loader dot's fade in a hand-over that does most of its change early: a walking or swapping dot coming in, a bouncing one going out |
328
+ | `--dsh-claude-ease-damped-in` | `cubic-bezier(0.32, 0, 0.67, 0)` | a loader dot's fade in a hand-over that does most of its change late: a walking or swapping dot going out, a bouncing one coming in |
328
329
  | `--dsh-claude-distance-nudge` | `4px` | the short offset a surface rises from, and a small row's wording swap travels |
329
330
  | `--dsh-claude-distance-travel` | `8px` | the waiting line's wording swap, a settings page's slide, the overtime badge's sideways slide, and both directions of the waiting line's loader dots: the lift off their floor and the reach along their own lines |
330
331
  | `--dsh-claude-distance-rise` | `12px` | how far below its place a line of the home greeting starts, and the overtime badge's upward slide |
@@ -709,12 +710,13 @@ wear these same two paints (`packages/client/src/features/settings/settings.css`
709
710
  and take turns between a state word and the host's own word for a wait, so a card
710
711
  shows the wording swap as well as the paint.
711
712
 
712
- While the conversation follows its tail the row is pinned at the place the
713
- follow's glide comes to rest — the composer's own height, the fade band above it
714
- and the host's 16px transcript padding — the canvas painted behind it, since the
715
- transcript's tail would otherwise show through. The pin stands only while the
716
- host reports the tail (or the stream glide holds the position) and steps aside
717
- for the reader's own scrolling.
713
+ With the chat area's own follow on, the row is pinned while the conversation
714
+ follows its tail, at the place that follow's glide comes to rest — the
715
+ composer's own height, the fade band above it and the host's 16px transcript
716
+ padding — the canvas painted behind it, since the transcript's tail would
717
+ otherwise show through. The pin stands only while the host reports the tail (or
718
+ the stream glide holds the position) and steps aside for the reader's own
719
+ scrolling.
718
720
 
719
721
  ## Home layouts · 首页版面
720
722
 
@@ -791,8 +793,10 @@ week can never fall past the edge. Hovering a cell shows Claude Code's day tip a
791
793
  once: a solid pill in the label ink with the canvas tone for text (so it inverts
792
794
  with the theme), 13px medium, reading the day in the shell's language and the
793
795
  tokens that day spent ("Sep 9 — 15.9k tokens"), the same figure the cell's heat
794
- is bucketed from; over the three columns at either end the pill lines
795
- up with the cell's outer edge so it stays inside the panel.
796
+ is bucketed from; the pill is centred on its cell except where its own width
797
+ would carry it past the panel's edge, and there it lines up with that cell's
798
+ outer edge so it stays inside the panel, the width being read off the cell the
799
+ pointer is on (`packages/client/src/features/home/heat-tip.ts`).
796
800
  Models is Claude Code's own shape: one column
797
801
  per day of the chart's thirty-day window, stacked from the axis up with each
798
802
  model's slice in its rank's colour (ranks past the ramp share its last, grey
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -91,25 +91,25 @@
91
91
  "encoding": "br",
92
92
  "bytes": 143044
93
93
  },
94
- "0443f196403b.js": {
94
+ "45f65931db18.js": {
95
95
  "type": "text/javascript; charset=utf-8",
96
96
  "encoding": "br",
97
97
  "bytes": 15735
98
98
  },
99
- "be1508c8b2ba.js.map": {
99
+ "941e0bf043b9.js.map": {
100
100
  "type": "application/json; charset=utf-8",
101
101
  "encoding": "br",
102
- "bytes": 77316
102
+ "bytes": 77088
103
103
  },
104
- "0cde9ade580e.js": {
104
+ "d62fadde7087.js": {
105
105
  "type": "text/javascript; charset=utf-8",
106
106
  "encoding": "br",
107
- "bytes": 26253
107
+ "bytes": 27772
108
108
  },
109
- "fa257e5906cb.js.map": {
109
+ "c28d77bbeabf.js.map": {
110
110
  "type": "application/json; charset=utf-8",
111
111
  "encoding": "br",
112
- "bytes": 145823
112
+ "bytes": 157300
113
113
  },
114
114
  "b55a1acf34e0.js": {
115
115
  "type": "text/javascript; charset=utf-8",
@@ -121,45 +121,45 @@
121
121
  "encoding": "br",
122
122
  "bytes": 28560
123
123
  },
124
- "39f1a2e69bb7.js": {
124
+ "a6e3e1688c31.js": {
125
125
  "type": "text/javascript; charset=utf-8",
126
126
  "encoding": "br",
127
127
  "bytes": 20043
128
128
  },
129
- "30da116fe14e.js.map": {
129
+ "3095b1bf43a1.js.map": {
130
130
  "type": "application/json; charset=utf-8",
131
131
  "encoding": "br",
132
- "bytes": 74969
132
+ "bytes": 74791
133
133
  },
134
- "bebb9a8751b0.js": {
134
+ "926518b8cde7.js": {
135
135
  "type": "text/javascript; charset=utf-8",
136
136
  "encoding": "br",
137
137
  "bytes": 8319
138
138
  },
139
- "f70c3fda4e83.js.map": {
139
+ "4c83b8f589e0.js.map": {
140
140
  "type": "application/json; charset=utf-8",
141
141
  "encoding": "br",
142
- "bytes": 34875
142
+ "bytes": 34774
143
143
  },
144
- "d2064c247435.js": {
144
+ "3990ca748494.js": {
145
145
  "type": "text/javascript; charset=utf-8",
146
146
  "encoding": "br",
147
147
  "bytes": 20847
148
148
  },
149
- "1cd94c7ebc56.js.map": {
149
+ "22605541d413.js.map": {
150
150
  "type": "application/json; charset=utf-8",
151
151
  "encoding": "br",
152
- "bytes": 132800
152
+ "bytes": 132278
153
153
  },
154
- "89c261313699.js": {
154
+ "a59afbc34773.js": {
155
155
  "type": "text/javascript; charset=utf-8",
156
156
  "encoding": "br",
157
157
  "bytes": 31940
158
158
  },
159
- "d8602385cac2.js.map": {
159
+ "fa08309f6148.js.map": {
160
160
  "type": "application/json; charset=utf-8",
161
161
  "encoding": "br",
162
- "bytes": 127865
162
+ "bytes": 127704
163
163
  }
164
164
  }
165
165
  }