dsh-claude-style 0.13.1 → 0.13.3
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 +108 -0
- package/README.md +3 -10
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/docs/FEATURES.en.md +3 -3
- package/docs/FEATURES.md +3 -3
- package/docs/SETTINGS.en.md +8 -4
- package/docs/SETTINGS.md +8 -4
- package/docs/STYLE.md +48 -31
- package/docs/decisions/D11-private-routes.md +2 -2
- package/docs/decisions/D12-fail-fast.md +3 -1
- package/docs/decisions/D22-search-panel.md +1 -1
- package/docs/decisions/D32-chat-interactions.md +2 -2
- package/docs/decisions/D41-scroll-owner.md +1 -1
- package/docs/decisions/D45-testing.md +1 -1
- package/docs/decisions/D50-brand.md +1 -1
- package/docs/decisions/D53-usage-merge.md +2 -1
- package/docs/decisions/D54-peakrate-meter.md +1 -1
- package/docs/decisions/D58-redraw-retired.md +2 -2
- package/docs/decisions/D62-file-row-merge.md +28 -0
- package/docs/decisions/D63-turn-status-retired.md +29 -0
- package/docs/decisions/D64-custom-brand.md +29 -0
- package/docs/decisions/README.md +4 -2
- package/lib/assets/2c01384360ac.js.map.br +0 -0
- package/lib/assets/84b3319c06fb.js.br +0 -0
- package/lib/assets/91558108acf4.js.map.br +0 -0
- package/lib/assets/e1291f79b7c9.js.br +0 -0
- package/lib/assets/manifest.json +8 -8
- package/lib/client.js +8 -8
- package/lib/client.js.map +4 -4
- package/lib/host/brand.js +136 -0
- package/lib/host/http.js +74 -0
- package/lib/host/peakrate.js +14 -4
- package/lib/host/routes.js +26 -64
- package/lib/host/search.js +7 -3
- package/lib/host/session-events.js +29 -8
- package/lib/host/settings.js +4 -1
- package/lib/host/usage-ledger.js +8 -0
- package/lib/host/usage-summary.js +5 -5
- package/lib/host/usage.js +3 -2
- package/lib/model-descriptions.json +126 -22
- package/package.json +1 -1
- package/docs/decisions/D23-turn-status.md +0 -27
- package/lib/assets/2fb22164cb7e.js.map.br +0 -0
- package/lib/assets/5b286686ae65.js.br +0 -0
- package/lib/assets/abdc076dfd70.js.map.br +0 -0
- package/lib/assets/b7b1e2f247e3.js.br +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,114 @@ All notable changes to `dsh-claude-style` are documented here, newest first.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.13.3] - 2026-10-12
|
|
8
|
+
|
|
9
|
+
[中文](#cn-0.13.3) | [English](#en-0.13.3)
|
|
10
|
+
|
|
11
|
+
<h3 id="cn-0.13.3">新增功能</h3>
|
|
12
|
+
|
|
13
|
+
- 选完 Claude 或 DeepSeek 主题风格后,侧栏顶部、新会话页与账号行的兜底头像只能挂这两家的标志;设置页「外观」里现在可以填自己的品牌名称、上传标志图片与文字标志(PNG / SVG / WebP,不超过 2 MB),选择图片保留原色或按文字颜色着色,并指定一个主色替换按钮、选中标记、链接与焦点环的颜色。图片存在 DSH 主目录的 `dsh-claude-style/brand/` 下,由宿主半边新增的 `/dsh-claude-style/brand`、`/brand/mark`、`/brand/wordmark` 三条私有路由读写;设置项新增 `brandName`、`brandInk`、`brandAccent`。
|
|
14
|
+
|
|
15
|
+
### 问题修复
|
|
16
|
+
|
|
17
|
+
- 等待行曾连带隐藏 dsh-status-rotator 等插件插入的状态行;现在只隐藏宿主文案,第三方状态行保持可见。
|
|
18
|
+
|
|
19
|
+
<h3 id="en-0.13.3">New Features</h3>
|
|
20
|
+
|
|
21
|
+
- With the Claude or DeepSeek theme style chosen, the top of the sidebar, the new-conversation page and the account row's fallback picture could only carry those two brands' marks; the Appearance tab now takes your own brand name, a mark and a wordmark image (PNG / SVG / WebP, up to 2 MB), a choice between the images' own colours and the text colour, and an accent colour for buttons, selected marks, links and focus rings. The images live under `dsh-claude-style/brand/` in the DSH home directory, read and written through three new private routes of the host half — `/dsh-claude-style/brand`, `/brand/mark` and `/brand/wordmark`; the settings gain `brandName`, `brandInk` and `brandAccent`.
|
|
22
|
+
|
|
23
|
+
### Bug Fixes
|
|
24
|
+
|
|
25
|
+
- The waiting line hid status lines inserted by plugins such as dsh-status-rotator; it now hides only the host wording and leaves third-party status lines visible.
|
|
26
|
+
|
|
27
|
+
## [0.13.2] - 2026-10-11
|
|
28
|
+
|
|
29
|
+
[中文](#cn-0.13.2) | [English](#en-0.13.2)
|
|
30
|
+
|
|
31
|
+
<h3 id="cn-0.13.2">新增功能</h3>
|
|
32
|
+
|
|
33
|
+
- 设置页「侧栏」多了一行「左侧栏布局」:「宽松」是现在的样子,「紧凑」把左侧栏的间距收小——上侧各行(新会话、插件、自动化任务,以及搜索框独立成行时的那一行)到工作区之间的空隙、工作区标题自身的上下留白、对话行的高度与行间距、两个分区之间的间隔,以及账号区的内边距与它那一行的上下边距。控件的形状、字号、图标与配色不变。新增一项偏好 `sidebarLayout`(默认 `relaxed`),把它解析到 `<body data-dsh-claude-sidebar-layout>`;宿主半边由共享的偏好表生成,因此该键也会出现在 DSH 的设置文档里。
|
|
34
|
+
|
|
35
|
+
### 体验优化
|
|
36
|
+
|
|
37
|
+
- 同一个文件在一段过程里被改了几次,聊天区就并排列出几行,改动越密集越难看出这个文件一共改了多少。现在同一个文件在同一个过程组里的多次编辑与写入读成一行:这一行是这一组里最早的那一次改动,行尾的 `+n -m` 是这些改动的累计值,每到达一次改动就滚动一次,展开这一行读到的是全部改动;只改动过一次的文件保持原样,失败与中断的行仍各自保留裁决信息。
|
|
38
|
+
- 「模型正在做什么的那一行」在跟随末尾时停在输入框上方:这一行的固定此前挂在「轮次状态行」这一个开关上,而它属于运行中的这一行本身。现在它随「聊天区动画效果」这一开关,与这一行的说法、扫光同一处;读者自己接管滚动,或跟随的滑行正持有位置时,它照旧让开,回到文档位置随内容走。
|
|
39
|
+
- 首页用量面板的用量热力图,格子悬停提示原本写的是那天的消息条数,现在改成那天的 Token 用量(「9月9日 — 15.9k Token」),与格子深浅取自同一个数字;两份数据来源都带每天的 Token 合计,提示不再随来源换口径。
|
|
40
|
+
- 侧栏搜索框选「独立在品牌行下方」时,那一行自己还留着 8 像素的左右内边距,盒子因此比下面的「新会话」等行窄 16 像素;现在这一行不再留内边距,盒子的左右边框与下面各行的宽度落在同两条边上。
|
|
41
|
+
- 侧栏「新会话」一行右侧的快捷键提示原本是等宽字体的普通文字(Ctrl + N),现在与搜索框的按键同一套样式:每个键一个 20 像素圆角键帽、1 像素描边、12 像素次级文字,两个键之间的「+」不再出现。
|
|
42
|
+
- 样式表里写死的颜色改读令牌:强调色按钮上的文字取填充自己的前景令牌(原先写死纯白,换成浅色填充后对比度没有保障),设置页里插件图标的底色取主文字令牌(原先写死十六进制)。docs/STYLE.md 的形状一节补上实际使用的圆角与描边,并写明它们来自被复制的那枚宿主控件。
|
|
43
|
+
|
|
44
|
+
### 问题修复
|
|
45
|
+
|
|
46
|
+
- 会话很多时,用量汇总与内容搜索读日志会让宿主进程持续占住一个核心:它们经 `sessionQuery.readSession` 按 id 读,而这一版会为了定位一个 id 先把整份会话存档列一遍(列一次要打开并解压每个存档的头部帧),改动过的会话越多就越慢,首次运行或任何一次会话变动都按变更个数叠加。现在两处都改走宿主的观察接口 `sessionQuery.observeSession`,它只观察这一份存档、不先列档,读 N 个会话就是 N 次观察、零次列档(观察的租约在事件到手后立即释放);只发布 `readSession` 的宿主退回按 id 读,仍然照常工作。按大小与修改时间的增量缓存不变,没有变动的会话照旧跳过,用量数字与负载结构不变。
|
|
47
|
+
- 删除会话的请求体超过上限时,客户端原先只看到连接被重置;现在先答 400,这条应答送出之后再结束连接。
|
|
48
|
+
- 成本计量账本里出现不是真实日期的键时,合并原先按字符串把它当成最新的一天,本地折算出的所有日子与它们的会话一起消失,首页模型图表还会读到一个非法日期而报错;现在这类键在读取时被跳过,其余日子照常合并。
|
|
49
|
+
- 机器上没有成本计量插件时,用量汇总的来源原先报成 cost-meter+local;现在报 local,与「哪个来源作答」的定义一致。
|
|
50
|
+
- 峰谷目录的 24 小时定时器原先在页面问过一次之后一直拉取到进程退出,设置里关掉峰谷功能也停不下来;现在连续 48 小时没有请求就自己停下,下一次请求再启动。
|
|
51
|
+
- 宿主没有网页服务器服务时,插件原先静默地一条路由也没注册,卸载时又按每一条记一次失败;现在报告一次缺少的服务,路由的撤销表里只留真正的撤销函数。
|
|
52
|
+
- 会话内容检索里,整份列举取代在途的尾扫时,旧的一轮结束会把新一轮的状态一起清掉,于是可以再起第三轮并发地读同一批会话;现在只有仍然是最新的一轮才清状态。
|
|
53
|
+
- 关闭状态的弹层卡片原先只把不透明度降到 0,卡片里的按钮仍然留在 Tab 顺序里,键盘读者会停在完全看不见的行上;现在关闭的卡片同时移出绘制、命中与焦点顺序,开关的淡入淡出照旧。
|
|
54
|
+
- 进行中那一行:皮肤把宿主自己的文字藏起来之后,画的替身又标着「装饰」,读屏在这一行上收不到「模型正在做什么」「暂未响应」和计时;现在替身是这一行的可读文字,宿主自己的实时区域照旧播报。
|
|
55
|
+
- 把「动画效果」设为减弱之后,工作强度滑杆顶档的点阵仍按运行时写下的动画时长闪一次;现在这一档不写动画的周期与相位,点阵静止。
|
|
56
|
+
- 几个控件对读屏说不出自己是什么:会话统计那一行只有数字与箭头,工作强度与模型触发器从不报告菜单是否展开,设置页的开关没有名字,权限弹层的当前档位只有勾号,输入输出箭标进了名称。现在统计行有自己的名称、两个触发器跟着菜单报告展开状态、开关取所在行的标题为名、权限弹层的当前档位写 aria-checked、箭标对读屏隐藏。
|
|
57
|
+
- 手机宽度下输入卡片下方那一行与手机插件自己画的度量条落在同一条 28 像素带里,两行文字叠在一起(权限标签上压了 52 像素、模型标签上压了 21 像素);现在输入区会量出那条度量条的高度,把这一行连同上下文圆环整体抬起同样的距离,度量条出现与消失时分别抬起与落回。
|
|
58
|
+
|
|
59
|
+
### 安全
|
|
60
|
+
|
|
61
|
+
- 宿主没有 connection 服务时,私有路由的回退栅栏原先只看请求方自己写的 Host 头,局域网连接谎报 localhost 即通过;现在先看连接的对端地址,回环地址之外一律拒绝。冒烟的宿主半边新增一条检查:局域网连接加回环 Host 必须被拒。
|
|
62
|
+
- 删除会话时「目录留在会话根目录内」的判定改为比较解析符号链接之后的路径:会话根目录下有指向别处的项目目录链接时,删除不再跟着链接走到根目录之外。
|
|
63
|
+
|
|
64
|
+
### 移除
|
|
65
|
+
|
|
66
|
+
- 「轮次状态行」整体移除:这一项把宿主的过程控件搬到自己那一轮工作的末尾,并为进行中、已停止与失败的轮次换上插件自己画的火花与文字(用时、输出 tokens、当前动作)。宿主早已把运行中的状态做成对话末尾自己的一行(小鲸鱼、说法与计时),过程控件只在轮次结束之后出现,于是这条状态条只剩停止与失败两种情形还在渲染,画法又与那一行不同。现在宿主自己的控件留在它原来的位置与写法上:已停止与失败的轮次显示宿主自己的「已停止」「处理失败」,用时与输出 tokens 不再显示;设置页「对话」页的「轮次状态行」一行随之消失,早先存下的取值不再被读取。
|
|
67
|
+
|
|
68
|
+
### 其他变更
|
|
69
|
+
|
|
70
|
+
- 模型标志的 `cap` 高度回退原先写在同一规则里的两条 `height`,端到端的 `!important` 审计因此整条跳过这条规则;现在两条高度分处两条规则,规则的每一处权重都受审计。
|
|
71
|
+
- 两处内部记录的清理:滚动主人记「哪个来源在滑这一格」的表改用弱引用键,弹簧自己走完之后不再把已经分离的对话子树留在内存里;页脚接管挂在宿主自己的账号行与菜单上的监听随功能的拆卸一并摘下,反复开关不再叠加。
|
|
72
|
+
|
|
73
|
+
<h3 id="en-0.13.2">New Features</h3>
|
|
74
|
+
|
|
75
|
+
- The settings page's Sidebar tab gains a Sidebar layout row: Relaxed is how the sidebar looks now, and Compact takes its spacing down — the gap between the top rows (New session, Plugins, Automation tasks, and the search box's own row when it stands alone) and the workspace, the workspace heading's own margins, the conversation rows' height and spacing, the distance between two sections, and the account area's padding and row margins. Control shapes, type sizes, icons and colours are unchanged. A new preference, `sidebarLayout` (default `relaxed`), resolves onto `<body data-dsh-claude-sidebar-layout>`; the host half is generated from the shared preference table, so the key appears in DSH's own settings document too.
|
|
76
|
+
|
|
77
|
+
### Improvements
|
|
78
|
+
|
|
79
|
+
- A file changed several times in one piece of work was listed as one row per change, so a dense stretch of edits made it hard to see how much the file had changed in total. The edits and writes of one file inside one process group now stand as a single row: the earliest of them carries the total of those changes in its `+n -m` tail, rolls once per change as each one lands, and opens onto every change. A file changed once is drawn as before, and a failed or interrupted row keeps its own verdict.
|
|
80
|
+
- The line saying what the model is doing now holds its place above the composer while the conversation follows its tail: that hold used to hang on the Turn status line switch, a switch for a line of its own. It rides the Chat-area animations switch now, together with the line's wording and sweep, and it still steps aside — keeping its document place — while the reader owns the scroll or the follow's glide holds the position.
|
|
81
|
+
- On the home page's usage panel, the heat map's cell tip used to name the day's messages; it now names the tokens that day spent ("Sep 9 — 15.9k tokens"), the same figure the cell's shade is bucketed from. Both sources behind the grid carry a per-day token total, so the tip no longer changes its reading with the source.
|
|
82
|
+
- With the sidebar search box on Standalone, its own row still carried 8px of inline padding, which made the box 16px narrower than the New session row under it; the row adds no padding now, so the box's two edges stand where the rows under it stand.
|
|
83
|
+
- The shortcut hint at the right of the sidebar's New session row was plain monospace text (Ctrl + N); it now wears the search box's own key caps — one 20px cap per key with a 1px hairline and 12px secondary text — and the `+` between the two keys is gone.
|
|
84
|
+
- Literals in the stylesheets read tokens: the label on a filled accent button takes the fill's own foreground token (it was a hard-coded white, which promised nothing once a palette turns the fill light), and the settings page's plugin mark takes the primary label token (it was a hard-coded hex). The shape section of docs/STYLE.md records the radii and strokes actually in use, with the host control each copy came from.
|
|
85
|
+
|
|
86
|
+
### Bug Fixes
|
|
87
|
+
|
|
88
|
+
- With many sessions the usage roll-up and the content search pinned a core while reading logs: they read by id through `sessionQuery.readSession`, which locates that id by listing the WHOLE stored corpus first (a listing opens and decompresses every stored session's header), so the pass grew with the number of changed logs on a first run and after any session change. Both now read through the host's observation entry point `sessionQuery.observeSession`, which resolves the one session without listing the corpus: N sessions cost N observations and no listings, each lease released as soon as its events are in hand. A host publishing only `readSession` falls back to the per-id read and keeps working. The size and modification time cache is unchanged, unchanged logs are still skipped, and the usage figures and payload shape are untouched.
|
|
89
|
+
- A session deletion whose body went past the limit left the client with a reset connection; the 400 is answered first now, and the connection is ended once that answer has gone out.
|
|
90
|
+
- A key in the cost meter's ledger that is not a real date used to become the newest day by string comparison, which dropped every day the local fold contributed, along with its sessions, and left the home page's model chart formatting an invalid date; such a key is skipped as the ledger is read now, and the rest of the days merge as before.
|
|
91
|
+
- With no cost-meter plugin on the machine, the usage roll-up reported its source as cost-meter+local; it reports local now, which is what "which source answered" means.
|
|
92
|
+
- The peak-rate catalog's daily timer kept reaching the source until the process exited once a page had asked, and switching the peak-rate feature off did not stop it; it stands down after 48 hours with no request now, and the next request starts it again.
|
|
93
|
+
- A host without a web server service registered no route in silence and then logged one failure per route as it unloaded; the missing service is reported once now, and the route disposers hold the real disposals alone.
|
|
94
|
+
- In session content search, when a full listing replaced a tail-only pass in flight, the older pass's end cleared the newer pass's state, which let a third pass read the same sessions alongside it; only the pass that is still current clears the state now.
|
|
95
|
+
- A closed popover card only dropped its opacity, so the buttons inside stayed in the tab order and a keyboard reader landed on rows nothing was drawing; a closed card leaves the paint, hit-testing and the tab order together now, and the open and close fades are unchanged.
|
|
96
|
+
- On the live turn's running row, the skin hid the host's own words and marked its replacement decorative, so a screen reader received neither what the model is doing, nor the wait badge, nor the clock; the replacement is the row's readable text now, and the host's own live region still announces the row.
|
|
97
|
+
- With Animation set to Reduced, the reasoning-effort slider's top-rung matrix still flashed once per block on the duration written at run time; that duration and phase are not written in this setting now, and the matrix stands still.
|
|
98
|
+
- Several controls could not say what they were: the conversation-statistics line held only figures and arrows, the effort and model triggers never reported whether their menu was open, the settings page's switches had no name, the permission popover marked its current tier with a check mark alone, and the input and output arrows joined a name. The line carries its own name now, both triggers report the open state with their menu, a switch takes its row's title as its name, the permission popover's current tier writes aria-checked, and the arrows are hidden from a reader.
|
|
99
|
+
- At phone width the line under the composer card and the statistics strip a mobile plugin draws of its own shared one 28px band, so the two rows of text printed over each other (52px of glyph-on-glyph on the permission label, 21px on the model label); the composer now measures that strip and lifts the line, the context ring with it, by the strip's own height, taking it up and letting it back down as the strip comes and goes.
|
|
100
|
+
|
|
101
|
+
### Security
|
|
102
|
+
|
|
103
|
+
- With no `connection` service on the host, the private routes' fallback fence read only the Host header the requester writes, so a LAN client claiming `localhost` passed. The peer address of the connection is checked first now, and anything outside loopback is refused. The host half's smoke run carries the check: a LAN connection claiming a loopback Host is refused.
|
|
104
|
+
- The session deletion's "directory stays inside the sessions root" check compares resolved paths now: with a project directory inside the root linked elsewhere, the removal no longer follows the link out of the root.
|
|
105
|
+
|
|
106
|
+
### Removals
|
|
107
|
+
|
|
108
|
+
- The Turn status line feature is removed: it moved the host's process control to the end of the turn's work and drew the plugin's own spark and text — elapsed time, output tokens, what the model was doing — for a running, stopped or failed turn. The host has long since drawn the running status as its own row at the end of the conversation (whale, wording and clock), and its process control appears only once the turn has closed, so the plugin's line was left rendering the stopped and failed cases alone, in a look of its own. The host's control now stays where the host puts it and reads as the host writes it: a stopped or failed turn shows the host's own Stopped / Failed with no elapsed time or output tokens, and the Turn status line row leaves the Conversation tab of the settings page, with any stored value no longer read.
|
|
109
|
+
|
|
110
|
+
### Chores
|
|
111
|
+
|
|
112
|
+
- The model mark's `cap`-height fallback was two `height` declarations in one rule, which made the end-to-end `!important` audit skip that rule whole; the two heights sit in two rules now, so every weight in them is audited.
|
|
113
|
+
- Two internal records are released properly: the scroll owner's table of which source is easing a container uses weak keys now, so a spring that arrives on its own no longer keeps a detached conversation subtree in memory, and the footer takeover's listeners on the host's own account row and menu come off with the feature's teardown instead of stacking on every switch.
|
|
114
|
+
|
|
7
115
|
## [0.13.1] - 2026-10-10
|
|
8
116
|
|
|
9
117
|
[中文](#cn-0.13.1) | [English](#en-0.13.1)
|
package/README.md
CHANGED
|
@@ -84,18 +84,9 @@ dsh plugin --profile web add dsh-claude-style # npm 包(推
|
|
|
84
84
|
|
|
85
85
|
同一时刻建议只启用一个主题。安装后推荐重启 `DeepSeek Harness`以获得完整能力。
|
|
86
86
|
|
|
87
|
-
## 功能与设置
|
|
88
|
-
|
|
89
|
-
本插件的功能与设置说明都在文档里:[功能一览](docs/FEATURES.md)、[设置说明](docs/SETTINGS.md)。
|
|
90
|
-
|
|
91
87
|
## 字体
|
|
92
88
|
|
|
93
|
-
> **重要:Anthropic
|
|
94
|
-
|
|
95
|
-
| 字体 | 用途 | 文件 |
|
|
96
|
-
|---|---|---|
|
|
97
|
-
| Anthropic Sans Web Text | 界面 / UI | [`packages/assets/src/fonts/anthropic/AnthropicSansWebText.ttf`](https://github.com/Nwflower/dsh-claude-style/raw/main/packages/assets/src/fonts/anthropic/AnthropicSansWebText.ttf) |
|
|
98
|
-
| Anthropic Serif Web Text | 对话正文 / Markdown | [`packages/assets/src/fonts/anthropic/AnthropicSerifWebText.ttf`](https://github.com/Nwflower/dsh-claude-style/raw/main/packages/assets/src/fonts/anthropic/AnthropicSerifWebText.ttf) |
|
|
89
|
+
> **重要:Anthropic 没有对其字体进行公开发行,[`点击此处可以查看`](https://github.com/Nwflower/dsh-claude-style/raw/main/packages/assets/src/fonts),请自行下载,仅供学习或研究用途**。
|
|
99
90
|
|
|
100
91
|
Anthropic 字体启用(二选一):
|
|
101
92
|
|
|
@@ -111,6 +102,8 @@ Anthropic 字体启用(二选一):
|
|
|
111
102
|
| [架构决策](docs/decisions/README.md) | 每条决策一个文件:构建与源码、宿主边界、运行时与各个功能的取舍,以及正在进行的架构迁移 |
|
|
112
103
|
| [更新日志](CHANGELOG.md) | 版本历史 |
|
|
113
104
|
| [贡献指南](CONTRIBUTING.md) | 如何从 `packages/client/src/` 构建、提交规范与截图/回归工具(英文) |
|
|
105
|
+
| [功能一览](docs/FEATURES.md) | 每一项功能做什么、在设置页哪里开关 |
|
|
106
|
+
| [设置说明](docs/SETTINGS.md) | 五个分页(通用、外观、输入区、侧栏、对话)的设置项与各档效果 |
|
|
114
107
|
|
|
115
108
|
## 鸣谢
|
|
116
109
|
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -4,7 +4,7 @@ This package includes material from the projects below. Each keeps its own licen
|
|
|
4
4
|
|
|
5
5
|
## dsh-better-display
|
|
6
6
|
|
|
7
|
-
The counted figures on a process group's header (`packages/client/src/features/chat-fold/process-summary.ts` and the `dsh-claude-process-summary-*` rules in its stylesheet) and the line while the model works (`packages/client/src/features/chat-wait/`, its stylesheet): their roll timing and curve, the shimmer sweep over the figures, the clock's type and colour and the overtime badge follow dsh-better-display's fold summary and live status line. The source files name it in their headers.
|
|
7
|
+
The counted figures on a process group's header (`packages/client/src/features/chat-fold/process-summary.ts` and the `dsh-claude-process-summary-*` rules in its stylesheet), the merged figures on a file-change row (`packages/client/src/features/chat-files/` and the `dsh-claude-file-roll-*` rules in its stylesheet) and the line while the model works (`packages/client/src/features/chat-wait/`, its stylesheet): their roll timing and curve, the shimmer sweep over the figures, the clock's type and colour and the overtime badge follow dsh-better-display's fold summary and live status line. The source files name it in their headers.
|
|
8
8
|
|
|
9
9
|
Source: <https://github.com/aa2246740/dsh-better-display>
|
|
10
10
|
|
package/docs/FEATURES.en.md
CHANGED
|
@@ -7,6 +7,7 @@ What each feature does and where its switch lives; the five tabs, their rows and
|
|
|
7
7
|
<!-- features:start — written by npm run features, not by hand -->
|
|
8
8
|
|
|
9
9
|
- **Selection colour while unfocused**: Selected text takes the unfocused colours while the window is in the background and the focused ones when it comes back, as other applications do.
|
|
10
|
+
- **Custom brand**: Puts your own brand name, mark and wordmark over the chosen brand: the top of the sidebar, the collapsed rail, the new-conversation page and the account row's fallback picture all take them, with the images in their own colours or inked in the text colour. An accent colour of your own can recolour buttons, selected marks, links and focus rings.
|
|
10
11
|
- **Composer**: The input card on the new-conversation page and in conversations is redrawn after Claude Code Desktop: attachments sit in one row of tiles, the context usage is a ring in the toolbar, a press anywhere on the card starts typing, and a conversation resting at the bottom moves up with the card as it grows. The Composer tab chooses the home page alone, the conversation alone, both, or neither.
|
|
11
12
|
- **Home layout**: Classic is the centred greeting over the input card. Studio moves the greeting to the top left, pins the input card to the window's bottom edge and fills the space between with a usage panel: a heat map of recent usage and the usage and cost of each model.
|
|
12
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.
|
|
@@ -23,13 +24,12 @@ What each feature does and where its switch lives; the five tabs, their rows and
|
|
|
23
24
|
- **One-frame theme switch**: Switching between light and dark changes borders, shadows and fills in the same frame, instead of the colours first and the borders easing in after.
|
|
24
25
|
- **In progress / Archived**: The sidebar's workspace section splits into In progress and Archived; Archived is one flat list whose rows can be restored or deleted.
|
|
25
26
|
- **Sidebar search**: A search box in the sidebar opens a palette that finds sessions (titles and content), projects, plugins, Skills and shortcuts, through the host's own dialog and navigation; picking a content hit lands on the turn holding that message rather than at the top of the session. Search box style places it: Cover the brand (the default) keeps it in the brand row, standing over the brand while the pointer is over the sidebar; Standalone gives it a row of its own under the brand row, shown always; Icon leaves the host's own search button in place and takes only its click over.
|
|
26
|
-
- **Turn status line**: A running, stopped or failed turn shows its status at the end of the turn's work: the elapsed time, the output tokens and what the model is doing now (or that it stopped or failed); while the turn runs the line rests above the composer for as long as the conversation follows its tail, so content arriving below no longer drags it around, and scrolling back yourself leaves it travelling with the content. Off restores the host's turn status.
|
|
27
27
|
- **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.
|
|
28
28
|
- **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 main scroller's own follow is walked along that curve too rather than written to the end in a single frame — with a fast stream the newest lines trail just below the fold and slide into place once it stops. 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.
|
|
29
29
|
- **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 every 0.84 s (half a second of travel) 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.
|
|
30
|
-
- **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. A wording that changes runs transitions.dev's "Text states swap": the old one blurs and fades upward, the new one rises from below (about 0.15 s). Where no state can be read (the model has written nothing and no tool is running) it falls back to the host's own "Deep diving", 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 and its screen-reader announcement stay; with Animation set to Reduced the wording is written at once, with none of those three phases.
|
|
30
|
+
- **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. A wording that changes runs transitions.dev's "Text states swap": the old one blurs and fades upward, the new one rises from below (about 0.15 s). Where no state can be read (the model has written nothing and no tool is running) it falls back to the host's own "Deep diving", 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 and its screen-reader announcement stay; 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.
|
|
31
31
|
- **New text fades in**: Characters arriving in a streaming answer start faint and settle over about 0.12 s, 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.
|
|
32
|
-
- **File change rows**: A write or edit dispatched from inside a run_code program carries the `+n -m` tail and an expandable diff card, and its path opens the file; a failed or interrupted row keeps its verdict.
|
|
32
|
+
- **File change rows**: A write or edit dispatched from inside a run_code program carries the `+n -m` tail and an expandable diff card, and its path opens the file; several changes to one file inside one process group stand as a single row whose tail is their total, rolling as each change lands, and opening that row reads every change; a failed or interrupted row keeps its verdict.
|
|
33
33
|
- **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.
|
|
34
34
|
- **Composer caret motion**: The composer's text caret is drawn by the plugin and glides when it moves; a question card's answer box and a queued message's inline editor are covered as well. The Conversation tab offers Every move (the default), Explicit moves and Off.
|
|
35
35
|
- **Chat / Trajectory tabs**: The Chat / Trajectory tab strip at the top of the conversation is redrawn as a segmented control and lifted onto the title's line when it fits.
|
package/docs/FEATURES.md
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
<!-- features:start — written by npm run features, not by hand -->
|
|
8
8
|
|
|
9
9
|
- **失焦时的选区颜色**:窗口失去焦点时,选中的文字换成失焦的配色,回到窗口时换回来,与系统里别的程序一致。
|
|
10
|
+
- **自定义品牌**:在所选品牌之上换上你自己的品牌名、标志图与文字标志,侧栏顶部、折叠栏、新会话页与账号行的兜底头像都跟着换;图可以保留原色,也可以按文字颜色着色。另可指定一个主色,按钮、选中标记、链接与焦点环随之变色。
|
|
10
11
|
- **输入区**:新会话页与对话页的输入卡片按 Claude Code Desktop 的样子重画:附件排成一行缩略图,上下文用量是工具栏里的一个圆环,点卡片的空白处就能开始输入,卡片变高时停在底部的对话跟着上移。设置页「输入区」可以选只改新会话页、只改对话页、两处都改或关闭。
|
|
11
12
|
- **首页版面**:「经典」是居中的问候语与输入卡片;「工作室」把问候语移到左上角、输入卡片贴着窗口底边,中间是用量面板:近期的用量热力图、各模型的用量与费用。
|
|
12
13
|
- **吉祥物**:输入框上沿站着一只像素小伙伴,随智能体的工作状态换动画(思考、写回答与调用工具、多个会话同时工作、子代理、等你操作、压缩上下文、完成、失败、睡着)。「跟随品牌」在 Claude 品牌下是像素螃蟹,在 DeepSeek 品牌下是小鲸鱼 Deepy,也可以固定选一个或者关闭;「出现位置」决定它只在新会话页出现,还是新会话页和对话页都出现。
|
|
@@ -23,13 +24,12 @@
|
|
|
23
24
|
- **亮暗切换一步到位**:切换亮色与暗色时,边框、阴影与底色在同一帧换好,不会先换颜色、再慢慢补上边框。
|
|
24
25
|
- **进行中 / 已归档**:侧栏的工作区分成「进行中」与「已归档」两档;已归档是一张平铺的列表,每一行可以恢复或删除。
|
|
25
26
|
- **侧栏搜索**:侧栏里有一个搜索框,打开的面板能找会话(标题与内容)、项目、插件、Skill 与快捷键,用宿主自己的对话框与导航;点开一条内容命中会落到那条消息所在的一轮,而不只是会话开头。「搜索框样式」选它的位置:覆盖品牌(默认)把它放在品牌行、指针移到侧栏时盖过品牌,独立在品牌行下方给它自己一行并一直显示,图标则保留宿主自己的搜索按钮、只把单击接管过来。
|
|
26
|
-
- **轮次状态行**:进行中、已停止与失败的轮次,状态移到这一轮工作的末尾:用时、输出的 tokens,以及模型此刻在做什么(或已停止、处理失败);进行中时,只要对话还在跟随末尾,这一行就停在输入框上方,不断追加的内容不再带着它上下移动,读者自己往回翻看时它照常随内容走。
|
|
27
27
|
- **对话导航**:对话区右侧那列短横线每一轮一条,跟着你读到的位置走。鼠标碰到它,它就展开成一张列表:每一行写着开启这一轮的那条消息,正好落在它那条短横线原来的位置上——你正在读的那一轮还在原处,鼠标下面还是刚才那一轮;滚轮上下翻,点一行页面滑到那一轮,还没加载的早期对话先加载再跳;指针停在列表上时,对话区顶部的对话 / 轨迹标签照常显示。Alt+↑ / Alt+↓ 跳到上一轮或下一轮,连按会一轮一轮接着走;输入框里有草稿时这两个键留给输入框。跳到的那一轮开头会闪一条短横线。同时装着 [dsh-plugin-msg-nav](https://github.com/SherUnlocked-4869/dsh-plugin-msg-nav) 时,Alt+↑ / Alt+↓ 留给它。
|
|
28
28
|
- **聊天区跟随**:思考行收起、工具调用行出现这些结构时刻,贴着底部的读者被交还给系统自己的跟随,内容成片到达时不再停在离底部几十像素的地方;「标准」与「简洁」档里封顶的过程组(思考与工具输出收在一个带滚动条的组体里)同样补到底部。补到底部走的是曲线:零散到达的字收得住尾巴,成片涌进的文字以一段稳速滑过去,再落到末尾。流式输出期间主滚动条的新内容也沿这条曲线推进,不再一帧写到底;输出很快时最新几行会短暂拖在屏幕下缘之外,流一停就滑到位。你自己发出的消息不走这条曲线:宿主把它滚进视野的那一下照旧一步到位。读者自己滚动离开底部之后,插件不再插手,直到他自己回到底部。
|
|
29
29
|
- **自动开合与卷帘门**:模型还在思考时思考行开着,思考停下就收回去;运行中的过程组自动展开,这一段结束再收起。读者自己按过的行或组在当时的阶段里不再被改动。开着的那段思考停在一个跟着它长高的窗口里:窗口先是和文本一样高,长到推理能到的最大高度就停在那里,只有到了这一刻文字才每 0.84 秒往上走两行(0.5 秒滑过去),走到最新一行就停住,上下边缘渐隐,也不再往下推整列对话;推理一停,窗口撤下,读者打开这一行读到的是完整文本,「动画」为「减弱」时不设这个窗口。过程组的标题改写成这一组装了什么:「执行 2 次思考,调用 1 次工具」,没有的项不写,数字随内容增加逐位滚动,这一段还在进行时整行带着宿主那样的扫光;放不下整句时改用「思考×2 · 工具×1」,位置宽回来再换回整句,控件的可访问名字始终是整句。点开或收起一行(工具卡片、思考行、命令卡片)以及过程组时,高度逐帧变化,下方内容被真的推开或收回;门只走读者看得见的那一段,内容再长也是同一速度,多张卡片的展开体整扇门一起走。
|
|
30
|
-
- **模型正在做什么的那一行**:轮次进行中,对话末尾那一行不再是固定的「深度求索中,用时 N 秒 ···」,而是写出这一轮此刻在做的事:「正在思考」「正在准备工具调用」「正在调用工具」「正在写回答」,后面跟着这一轮已用的时间(用宿主自己的单位)。说法换掉时旧的向上淡出、新的从下方升起(约 0.15 秒,来自 transitions.dev 的「Text states swap」);读不出状态时(模型还没写出任何内容、也没有工具在跑)回到宿主自己的「深度求索中」;模型连续 10
|
|
30
|
+
- **模型正在做什么的那一行**:轮次进行中,对话末尾那一行不再是固定的「深度求索中,用时 N 秒 ···」,而是写出这一轮此刻在做的事:「正在思考」「正在准备工具调用」「正在调用工具」「正在写回答」,后面跟着这一轮已用的时间(用宿主自己的单位)。说法换掉时旧的向上淡出、新的从下方升起(约 0.15 秒,来自 transitions.dev 的「Text states swap」);读不出状态时(模型还没写出任何内容、也没有工具在跑)回到宿主自己的「深度求索中」;模型连续 10 秒没有开口时,计时后面多一枚「暂未响应」。这一行带扫光,宿主的小鲸鱼与读屏播报照旧;「动画」设为「减弱」时说法直接换掉,不做上面那三段。只要对话还在跟随末尾,这一行就停在输入框上方,不断追加的内容不再带着它上下移动;读者自己往回翻看时它照常随内容走。
|
|
31
31
|
- **新文字淡入**:流式回答里新出现的字符先淡后实(约 0.12 秒),并按到达次序略作错开;整段一次到达的内容、几千字的突发与刚被折叠重排过的文字保持本色。
|
|
32
|
-
- **文件变更行**:run_code 程序里派发出去的写入与编辑带上行尾的 `+n -m`
|
|
32
|
+
- **文件变更行**:run_code 程序里派发出去的写入与编辑带上行尾的 `+n -m` 与可展开的改动卡片,路径可点开文件;同一个文件在同一个过程组里的多次改动读成一行,行尾的数字是这些改动的累计值、随每次改动到达滚动,展开这一行读到的是全部改动;失败与中断的行保留裁决信息。
|
|
33
33
|
- **聊天气泡动效**:提交消息时输入卡片浮起、一路收成那条气泡:飞行的这一份从第一帧就是气泡的颜色,草稿里的字跟着形状重新排,最后接上真实的消息行——真实气泡在下面先显示出来,飞行的那份淡出,文字逐渐变清晰。
|
|
34
34
|
- **输入框插入符动效**:输入框里的光标由插件自己绘制,移动时滑过去;提问卡片的作答框与排队消息的行内编辑框同样覆盖。设置页的「对话」页有三档:每一格(默认)、只在移动时、关闭。
|
|
35
35
|
- **对话 / 轨迹标签条**:对话区顶部的对话 / 轨迹标签条重画成分段控件,放得下时抬到标题那一行。
|
package/docs/SETTINGS.en.md
CHANGED
|
@@ -9,10 +9,10 @@ The settings page appears both in the settings dialog (the "Claude Style" tab) a
|
|
|
9
9
|
| Tab | Settings |
|
|
10
10
|
|---|---|
|
|
11
11
|
| General | Theme style, Username, Animation, Open popovers on hover, Account-hold easter egg language |
|
|
12
|
-
| Appearance | Colours, Typefaces, Mascot, Where it appears |
|
|
12
|
+
| Appearance | Colours, Typefaces, Mascot, Where it appears, Brand name, Brand mark, Wordmark, Image colours, Accent colour |
|
|
13
13
|
| Composer | Composer restyle, Home layout, Redraw the model picker (with Quick providers under it), Peak rate meter, Redraw the permission control |
|
|
14
|
-
| Sidebar | Collapse the sidebar settings area, Sidebar search, Search box style, In progress / Archived view, Float docked panels |
|
|
15
|
-
| Conversation |
|
|
14
|
+
| Sidebar | Collapse the sidebar settings area, Sidebar search, Search box style, Sidebar layout (Relaxed / Compact), In progress / Archived view, Float docked panels |
|
|
15
|
+
| Conversation | Conversation navigator, Chat-area animations (Off / Enhanced), Conversation statistics position (Inside the context popover / On its own line), Composer caret motion, Chat / Trajectory tabs |
|
|
16
16
|
|
|
17
17
|
Every feature that takes over part of the host's interface has its own switch; turning it off brings the host's original back at once, without a reload. The conversation area's effects — the follow, the automatic folding with its rolling door, the text fade, the file change rows, the send flight, the counted figures on each process group's header and the line saying what the model is doing — share the one Chat-area animations switch: on plays this plugin's set, off hands the conversation back to the host with the host's own words; the caret keeps its own three-way choice.
|
|
18
18
|
|
|
@@ -20,10 +20,14 @@ In the settings dialog, this page's heading row ends with a GitHub mark; pressin
|
|
|
20
20
|
|
|
21
21
|
**Opened from a remote address**: DSH saves settings only from a page opened at a local address such as localhost. A page reached through a LAN address or a tunnel (a phone, another computer) shows the look and the settings DSH holds, and the settings page opens with a line saying so, its controls disabled. Settings changed on the computer running DSH reach the remote page without a reload.
|
|
22
22
|
|
|
23
|
+
**Custom brand**: the last rows of the Appearance tab put your own brand over the one Theme style picks. Brand name replaces the brand text at the top of the sidebar; Brand mark replaces the mark at the top of the sidebar, on the collapsed rail, on the new-conversation page and as the account row's fallback picture; Wordmark replaces the name beside the mark, its width following the image's proportions at the row's height, and while it is in place the brand name is not shown. The images take PNG, SVG and WebP up to 2 MB each and are kept under `dsh-claude-style/brand/` in the DSH home directory; dropping `mark.png` (or `.svg`, `.webp`) and `wordmark.png` into that directory by hand works too, after a page reload. Image colours set to Original shows the images in their own colours; Text colour uses each image as a shape filled with the text colour where it stands, which suits a one-colour mark and reads in both light and dark. Accent colour recolours buttons, selected marks, links and focus rings, with the text on a button picked dark or light to read on it; unset, the chosen brand's accent stays, and while Colours is set to Follow the host the accent has no effect. Clearing or removing any of them puts the chosen brand's own back in its place.
|
|
24
|
+
|
|
23
25
|
**Peak rate meter**: every row of the model menu carries the rate in force for that model right now. Peak, off-peak and a dated promotion each get their own mark, the colour separates expensive from cheap, and the multiplier is followed by how long it lasts; hovering the badge prints the whole judgement and what it becomes. The judgement is made from each provider's own published schedule in that provider's own time zone: outside the weekday windows, and on weekends and public holidays in full, the rate is off-peak, and a window crossing midnight belongs to the day it starts. A model with no schedule published carries no badge. The schedules are one snapshot in the public [offpeakclock.com](https://offpeakclock.com) catalog: the host half — not the page — fetches it, keeps a copy on disk and refreshes it every 24 hours, and judges by the copy shipped in the package when it cannot be reached.
|
|
24
26
|
|
|
25
27
|
**Sidebar search**: with Sidebar search on, the sidebar carries a search box whose palette finds sessions (titles and content), projects, plugins, Skills and shortcuts; picking a content hit lands the page on the turn holding that message, paging that turn's records in first on a long history. Search box style places it: Cover the brand (the default) puts it in the brand row, standing over the brand while the pointer is anywhere over the sidebar and giving the brand back when the pointer leaves; Standalone gives it a row of its own under the brand row, shown always; Icon draws no box of the plugin's, keeping DSH's own search button where the host draws it and taking only its click over, so pressing it opens this plugin's palette. The content match reads your own messages and the model's answers alone: injected context, the Skill catalog and reasoning never reach the results.
|
|
26
28
|
|
|
29
|
+
**Sidebar layout**: Relaxed (the default) is how the sidebar looks now; Compact takes the spacing down alone — the gap between the top rows (New session, Plugins, Automation tasks, and the search box's own row when it stands alone) and the workspace, the workspace heading's own margins, the conversation rows' height and spacing, the distance between two sections, and the account area's padding and row margins. Control shapes, type sizes, icons and colours are untouched, so both layouts hold the same things to press.
|
|
30
|
+
|
|
27
31
|
**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 and Composer caret motion rows on the settings page's Conversation 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.
|
|
28
32
|
|
|
29
33
|
**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 main scroller's own follow is walked along that curve too rather than written to the end in a single frame — with a fast stream the newest lines trail just below the fold and slide into place once it stops. 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.
|
|
@@ -34,7 +38,7 @@ In the settings dialog, this page's heading row ends with a GitHub mark; pressin
|
|
|
34
38
|
|
|
35
39
|
**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.
|
|
36
40
|
|
|
37
|
-
**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. A wording that changes runs transitions.dev's "Text states swap": the old one blurs and fades upward, the new one rises from below (about 0.15 s). Where no state can be read (the model has written nothing and no tool is running) it falls back to the host's own "Deep diving", 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 and its screen-reader announcement stay; with Animation set to Reduced the wording is written at once, with none of those three phases.
|
|
41
|
+
**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. A wording that changes runs transitions.dev's "Text states swap": the old one blurs and fades upward, the new one rises from below (about 0.15 s). Where no state can be read (the model has written nothing and no tool is running) it falls back to the host's own "Deep diving", 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 and its screen-reader announcement stay; 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.
|
|
38
42
|
|
|
39
43
|
**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.
|
|
40
44
|
|
package/docs/SETTINGS.md
CHANGED
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
| 分页 | 设置项 |
|
|
10
10
|
|---|---|
|
|
11
11
|
| 通用 | 主题风格、用户名、动画效果、悬停展开弹层、封号彩蛋语言 |
|
|
12
|
-
| 外观 |
|
|
12
|
+
| 外观 | 配色、字体、吉祥物、出现位置、品牌名称、标志图片、文字标志、图片颜色、主色 |
|
|
13
13
|
| 输入区 | 输入区重绘范围、首页版面、重绘模型选择器(及其下的快捷供应商)、峰谷电表、重绘权限控件 |
|
|
14
|
-
| 侧栏 |
|
|
15
|
-
| 对话 |
|
|
14
|
+
| 侧栏 | 折叠侧栏设置区、侧栏搜索、搜索框样式、左侧栏布局(宽松 / 紧凑)、进行中 / 已归档视图、面板悬浮卡片 |
|
|
15
|
+
| 对话 | 对话导航、聊天区动画效果(关闭 / 增强)、对话统计信息位置(收进上下文 / 独立成行)、输入框插入符动效、对话 / 轨迹标签条 |
|
|
16
16
|
|
|
17
17
|
每一项接管宿主界面的功能都有自己的开关,关闭后宿主原来的界面原样回来,不需要刷新页面。对话区的那几项动效(跟随、自动开合与卷帘门、新文字淡入、文件变更行、聊天气泡动效、过程组标题上的计数、说明模型正在做什么的那一行)共用一个开关「聊天区动画效果」:开启时播放本插件的这一套,关闭后聊天区交回宿主,宿主自己的说法也一并回来;插入符动效仍是自己的三档。
|
|
18
18
|
|
|
@@ -20,10 +20,14 @@
|
|
|
20
20
|
|
|
21
21
|
**从远程地址打开**:DSH 只保存从 localhost 等本机地址打开的页面所做的设置改动。经局域网地址或隧道打开的页面(手机、另一台电脑)显示的是 DSH 当前的外观与设置,设置页开头有一行说明,控件全部禁用。在运行 DSH 的电脑上改动设置后,远程页面不需要刷新就会跟上。
|
|
22
22
|
|
|
23
|
+
**自定义品牌**:「外观」页末尾几行把你自己的品牌放到「主题风格」所选的品牌之上。「品牌名称」替换侧栏顶部的品牌文字;「标志图片」替换侧栏顶部、折叠栏、新会话页与账号行兜底头像上的标志;「文字标志」替换标志旁的名称,宽度按图片比例随高度换算,有它时不再显示品牌名称。图片收 PNG、SVG 与 WebP,单张不超过 2 MB,存在 DSH 主目录的 `dsh-claude-style/brand/` 下,也可以直接把 `mark.png`(或 `.svg`、`.webp`)与 `wordmark.png` 放进这个目录,刷新页面后生效。「图片颜色」选「原色」时图按自己的颜色显示;选「文字色」时图被当作形状,按所在位置的文字颜色上色,适合单色标志,亮色暗色下都看得清。「主色」改按钮、选中标记、链接与焦点环的颜色,按钮上的文字自动取深色或浅色;未指定时沿用所选品牌的主色,「配色」选「跟随宿主」时主色不生效。每一项留空或移除后,对应位置回到所选品牌的原样。
|
|
24
|
+
|
|
23
25
|
**峰谷电表**:模型菜单的每一行标出该模型此刻的倍率。峰价、谷价与限时活动三种状态各有自己的图标,颜色区分贵与便宜,倍数后面跟着距离切换还有多久;鼠标停在徽章上,悬停提示写出此刻的完整判定与切换后的状态。判定按各家供应商自己发布的作息表与自己的时区做,工作日窗口之外、周末与法定节假日整日都算谷价,跨零点的窗口归它开始的那一天。没有任何作息表的模型不显示徽章。作息表是公开目录 [offpeakclock.com](https://offpeakclock.com) 里的一份快照,由宿主半边(而不是页面)取一次、在本机留一份缓存并按 24 小时刷新;连不上时按插件包里带的那份判定。
|
|
24
26
|
|
|
25
27
|
**侧栏搜索**:开启后侧栏里多一个搜索框,打开的面板能找会话(标题与内容)、项目、插件、Skill 与快捷键;点开一条内容命中,页面落到那条消息所在的一轮,历史很长时先把这一轮的记录翻页读进来。「搜索框样式」决定它站在哪里:「覆盖品牌」(默认)把它放进品牌行,指针移到侧栏上时它盖过品牌,指针移开再把品牌让回来;「独立」在品牌行下方给它自己一行,一直显示;「图标」不画插件自己的搜索框,让 DSH 自己的搜索按钮留在原处,只把单击接管过来,点它打开的是本插件的面板。内容匹配只认你发出的消息与模型的回答,注入的环境提示、Skill 目录与推理过程都不进结果。
|
|
26
28
|
|
|
29
|
+
**左侧栏布局**:「宽松」(默认)是现在的样子;「紧凑」只把间距收小——上侧各行(新会话、插件、自动化任务,以及搜索框独立成行时的那一行)到工作区之间的空隙、工作区标题自身的上下留白、对话行的高度与行间距、两个分区之间的间隔,以及账号区内边距与它那一行的上下边距。控件的形状、字号、图标与配色都不动,因此两种布局下点得到的东西一样多。
|
|
30
|
+
|
|
27
31
|
**与其他主题插件同时使用**:「配色」与「字体」选「跟随宿主」后,本插件不再改写宿主的颜色与字体,只保留布局和控件;颜色交给 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 之后原样生效。
|
|
28
32
|
|
|
29
33
|
**聊天区跟随**:思考行收起、工具调用行出现这些结构时刻,贴着底部的读者被交还给系统自己的跟随,内容成片到达时不再停在离底部几十像素的地方;「标准」与「简洁」档里封顶的过程组(思考与工具输出收在一个带滚动条的组体里)同样补到底部。补到底部走的是曲线:零散到达的字收得住尾巴,成片涌进的文字以一段稳速滑过去,再落到末尾。流式输出期间主滚动条的新内容也沿这条曲线推进,不再一帧写到底;输出很快时最新几行会短暂拖在屏幕下缘之外,流一停就滑到位。你自己发出的消息不走这条曲线:宿主把它滚进视野的那一下照旧一步到位。读者自己滚动离开底部之后,插件不再插手,直到他自己回到底部。
|
|
@@ -34,7 +38,7 @@
|
|
|
34
38
|
|
|
35
39
|
**过程组标题上的计数**:过程组的标题不再只写「执行了命令,已读取文件,已调用工具等」,而是写这一组装了什么,例如「执行 2 次思考,调用 1 次工具」;没有的项不写,数字随内容增加逐位滚动,这一段还在进行时整行带着与宿主同样的扫光。这一行放不下整句时(窗口窄、过程组所在的行窄)改用简洁写法「思考×2 · 工具×1」,位置宽回来再换回整句;控件的可访问名字始终是整句。
|
|
36
40
|
|
|
37
|
-
**模型正在做什么的那一行**:轮次进行中,对话末尾那一行不再是固定的「深度求索中,用时 N 秒 ···」,而是写出这一轮此刻在做的事:「正在思考」「正在准备工具调用」「正在调用工具」「正在写回答」,后面跟着这一轮已用的时间(用宿主自己的单位)。说法换掉时旧的向上淡出、新的从下方升起(约 0.15 秒,来自 transitions.dev 的「Text states swap」);读不出状态时(模型还没写出任何内容、也没有工具在跑)回到宿主自己的「深度求索中」;模型连续 10
|
|
41
|
+
**模型正在做什么的那一行**:轮次进行中,对话末尾那一行不再是固定的「深度求索中,用时 N 秒 ···」,而是写出这一轮此刻在做的事:「正在思考」「正在准备工具调用」「正在调用工具」「正在写回答」,后面跟着这一轮已用的时间(用宿主自己的单位)。说法换掉时旧的向上淡出、新的从下方升起(约 0.15 秒,来自 transitions.dev 的「Text states swap」);读不出状态时(模型还没写出任何内容、也没有工具在跑)回到宿主自己的「深度求索中」;模型连续 10 秒没有开口时,计时后面多一枚「暂未响应」。这一行带扫光,宿主的小鲸鱼与读屏播报照旧;「动画」设为「减弱」时说法直接换掉,不做上面那三段。只要对话还在跟随末尾,这一行就停在输入框上方,不断追加的内容不再带着它上下移动;读者自己往回翻看时它照常随内容走。
|
|
38
42
|
|
|
39
43
|
**聊天气泡动效**:提交消息时输入卡片原样浮起、一路收成那条气泡,草稿里的字跟着形状重新排,落地正好接上真实的消息行:真实气泡在下面先显示出来,飞行的那份淡出,文字逐渐变清晰。
|
|
40
44
|
|
package/docs/STYLE.md
CHANGED
|
@@ -30,7 +30,7 @@ fish take it as their ink. The neutrals are the host's own cool family (its
|
|
|
30
30
|
blue-black in dark. User bubbles take a blue tint as the host's own do, and
|
|
31
31
|
inline code keeps the body ink as the host draws it. The skin's Claude marks
|
|
32
32
|
(the account row's
|
|
33
|
-
picture without an avatar
|
|
33
|
+
picture without an avatar) become DeepSeek's
|
|
34
34
|
whale (`packages/assets/src/brand/deepseek-mark.svg`, the host's `FISH_LOGO_PATH`); the
|
|
35
35
|
violet top rung of the reasoning slider stays.
|
|
36
36
|
|
|
@@ -197,8 +197,14 @@ and scrolls to its end.
|
|
|
197
197
|
|
|
198
198
|
## Shapes
|
|
199
199
|
|
|
200
|
-
- Radius: 4 / 8 / 16 px;
|
|
201
|
-
|
|
200
|
+
- Radius: 4 / 8 / 16 px; 12px for a popover card and 6px for its rows (the
|
|
201
|
+
popover table below); pills for CTAs (`9999px`). A shape copied from a host
|
|
202
|
+
control keeps that control's own geometry rather than the scale above: the
|
|
203
|
+
composer card's 18px (the host's 22px less 4), the inline composer's 14px and
|
|
204
|
+
11px, the permission and workspace segments' 7px, the view tabs' 5px, the
|
|
205
|
+
peak-rate and file pills' 999px.
|
|
206
|
+
- Borders: 1px warm hairline. The same host copies keep their own stroke: the
|
|
207
|
+
sidebar's 1.5px session-row ring, the inline composer's 1.6px stop square.
|
|
202
208
|
- Spacing: 4 px rhythm.
|
|
203
209
|
- Bottom edge: the transcript never fades behind the composer by shadow. The
|
|
204
210
|
composer seat paints an opaque `var(--dsw-alias-bg-base)` bar across its own
|
|
@@ -430,18 +436,24 @@ pass that stamps it) which `features/hero-menu/hero-menu.css` reads with
|
|
|
430
436
|
## Search · 搜索
|
|
431
437
|
|
|
432
438
|
**Sidebar box.** The box takes the brand's place in the logo row while the
|
|
433
|
-
pointer is over the sidebar:
|
|
439
|
+
pointer is over the sidebar: 28px tall, 8px radius, a 1px `#E8E6DC` hairline on
|
|
434
440
|
the ivory canvas fill (dark: `#2E2C29` on `#1E1E1D`), a 16px search glyph in the
|
|
435
441
|
secondary label, the "Search" label in the tertiary label at 14px, and the
|
|
436
|
-
host's search shortcut as 20px keycaps at the right end.
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
442
|
+
host's search shortcut as 20px keycaps at the right end. The New session row's
|
|
443
|
+
own shortcut wears that same keycap: a 20px box with a 1px hairline, 4px radius
|
|
444
|
+
and 12px secondary ink, and the `+` the host writes between the two keys goes,
|
|
445
|
+
the way the box leaves it out. It is a button like the New session and Plugins
|
|
446
|
+
rows below it: the pointer cursor, and on hover the same plate those rows take
|
|
447
|
+
(`--dsh-claude-hover-bg`, dark `rgba(255, 255, 255, 0.08)`) laid over its
|
|
448
|
+
opaque fill. Box and brand share one grid cell and cross-fade over 0.16s, the
|
|
449
|
+
timing the workspace heading and its segmented control trade places with; the
|
|
450
|
+
box is excluded from the window drag region. Standalone gives the box a row of
|
|
451
|
+
its own under the brand row, shown without a hover; that row adds no inline
|
|
452
|
+
padding, so the box's hairline stands on the two edges of the column's own
|
|
453
|
+
inset and is exactly as wide as the New session plate below it. In the desktop
|
|
454
|
+
titlebar mode the brand row rises 6px, since the sidebar column starts under
|
|
455
|
+
the 40px titlebar — as far as it goes with the box still wholly below that
|
|
456
|
+
edge, which clips the column.
|
|
445
457
|
|
|
446
458
|
**Palette.** A modal card set 8vh from the top, 760px wide at most, 16px radius,
|
|
447
459
|
on the same ivory fill (dark `#1E1E1D`) under the host's mask. From the top: a
|
|
@@ -459,20 +471,25 @@ and shows the Enter glyph; the others hide it. The card fades in and settles
|
|
|
459
471
|
from 6px above at 98.5% scale over 0.18s; on close card and mask fade out
|
|
460
472
|
together over 0.14s before the modal unmounts.
|
|
461
473
|
|
|
462
|
-
##
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
474
|
+
## The waiting line · 模型正在做什么的那一行
|
|
475
|
+
|
|
476
|
+
The host's running row — its whale tail, its divider and its live region — stays
|
|
477
|
+
as the host draws it; the host's own shimmering words step aside for the skin's
|
|
478
|
+
line beside the whale: the wording in the secondary label at 14px on a 24px line,
|
|
479
|
+
the turn's clock 8px later in the caption at 13px with tabular figures, and the
|
|
480
|
+
"No response yet" badge 8px after that (11px on a 16px line, 0 6px padding, a 5px
|
|
481
|
+
radius, the warning label over 16% of itself). The wording carries a highlight
|
|
482
|
+
band swept across it over 2s, and a wording that changes runs the three-phase
|
|
483
|
+
swap over 0.15s: the old one leaves upward with a 2px blur, the new one enters
|
|
484
|
+
from 4px below; under Reduced motion the band is left out and the wording is
|
|
485
|
+
written at once.
|
|
486
|
+
|
|
487
|
+
While the conversation follows its tail the row is pinned at the place the
|
|
488
|
+
follow's glide comes to rest — the composer's own height, the fade band above it
|
|
489
|
+
and the host's 16px transcript padding — the canvas painted behind it, since the
|
|
490
|
+
transcript's tail would otherwise show through. The pin stands only while the
|
|
491
|
+
host reports the tail (or the stream glide holds the position) and steps aside
|
|
492
|
+
for the reader's own scrolling.
|
|
476
493
|
|
|
477
494
|
## Home layouts · 首页版面
|
|
478
495
|
|
|
@@ -546,10 +563,10 @@ Claude Code's blue data ramp (`#3b6ecf` at 20/40/65/100 over the neutral empty
|
|
|
546
563
|
cell); because the columns are fractions of the panel's own width, the newest
|
|
547
564
|
week can never fall past the edge. Hovering a cell shows Claude Code's day tip at
|
|
548
565
|
once: a solid pill in the label ink with the canvas tone for text (so it inverts
|
|
549
|
-
with the theme), 13px medium, reading the day in the shell's language and
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
566
|
+
with the theme), 13px medium, reading the day in the shell's language and the
|
|
567
|
+
tokens that day spent ("Sep 9 — 15.9k tokens"), the same figure the cell's heat
|
|
568
|
+
is bucketed from; over the three columns at either end the pill lines
|
|
569
|
+
up with the cell's outer edge so it stays inside the panel.
|
|
553
570
|
Models is Claude Code's own shape: one column
|
|
554
571
|
per day of the chart's thirty-day window, stacked from the axis up with each
|
|
555
572
|
model's slice in its rank's colour (ranks past the ramp share its last, grey
|
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
|
|
7
7
|
## 决定
|
|
8
8
|
|
|
9
|
-
- 宿主半边的私有路由(`/username`、`/usage`、`/session-search`、`/hdsl`、`/hdsl-skin.png`、`POST /session-delete`)处理前先调 `connection.requestRejection(req)`,拒绝即回 401/403
|
|
9
|
+
- 宿主半边的私有路由(`/username`、`/usage`、`/session-search`、`/hdsl`、`/hdsl-skin.png`、`POST /session-delete`)处理前先调 `connection.requestRejection(req)`,拒绝即回 401/403。宿主没有这个服务时,插件自带的替代只放行回环请求:连接的对端地址在本机回环口上、回环 Host、无跨站标记、Origin 与 Host 一致。四项里前三项都要成立,其中对端地址是请求方写不了的那一项,回环 Host 只是附带条件。
|
|
10
10
|
- 公开静态资产不经栅栏,但请求里的文件名必须符合固定格式,读取只落在固定表给出名字的目录里:模型文案取自构建输出;字体的名字先查 `$DSH_HOME/dsh-claude-style/fonts/`,没有再看包内的 `lib/fonts/`;走路由的资源是构建清单(`lib/assets/manifest.json`,D38)里的哈希加扩展名。
|
|
11
|
-
- 删除会话另加四道:只接受 POST;id 符合宿主的会话 id
|
|
11
|
+
- 删除会话另加四道:只接受 POST;id 符合宿主的会话 id 格式;正在打开的会话拒绝;解析符号链接之后的目录必须留在会话根目录内。删除发生在宿主半边,浏览器只提交 id。请求体超过上限时先答 400,应答送出之后再结束这条连接。
|
|
12
12
|
- 删除成功时宿主半边经 `workspaceRegistry.unarchiveSession` 把 id 移出归档集合;归档集合里存储目录已消失的条目同样按删除成功应答并移出,否则归档列表会一直留着这一行。会话根目录读不了是故障,答 500。
|
|
13
13
|
- 用量汇总只读:别的插件的账本只读不写,自己的缓存放在 `$DSH_HOME/cache/dsh-claude-style/`,两个来源按日期合并(D53)。
|
|
14
14
|
- 浏览器半边:来自设置、账号服务、系统或其他插件的字符串只用 `textContent` 或元素属性写入;图标复制节点,不重新解析标记。
|
|
@@ -12,13 +12,15 @@
|
|
|
12
12
|
- 需要隔离、但错误必须可见的地方用 `reportError`:`notifyAll` 逐个通知监听函数,观察总线逐个通知订阅、帧管线逐个运行任务(D40),某个出错就报告、其余照常;卸载时单个功能失败报告后继续;功能开关(D29)关闭某个功能时它的 teardown 抛错,同样报告,这个功能在本代内不再装回。
|
|
13
13
|
- 浏览器半边允许的 catch,每处写明原因:
|
|
14
14
|
- 上述隔离。
|
|
15
|
-
- 宿主以抛错表达的预期状态:设置表单的 `set()` 拒绝不属于该配置的字段;`modelDirectories.directoryFor` 对还没建立的会话抛错,下一轮重试;`sessionQuery
|
|
15
|
+
- 宿主以抛错表达的预期状态:设置表单的 `set()` 拒绝不属于该配置的字段;`modelDirectories.directoryFor` 对还没建立的会话抛错,下一轮重试;`sessionQuery` 的观察(`observeSession`)与按 id 读(`readSession`)以 `SESSION_QUERY_CORRUPT_SESSION` / `SESSION_QUERY_SESSION_NOT_FOUND` 表示某个存档读不了或已被删,内容搜索与用量汇总把这一个会话记为空并记一条警告,其余会话照旧。
|
|
16
16
|
- 文件变更行解析流式工具的原始参数:参数逐块到达,半截 JSON 是正常的中途状态,解析不了就交回宿主的输入 / 输出卡片(`features/chat-files/file-row-model.ts`)。
|
|
17
17
|
- Promise 上表示「宿主半边没有应答」或「宿主自己会提示」的失败回调。
|
|
18
|
+
- 读者自己的品牌图加载失败(D64):这一张记一条警告并当作没有,另一张照常显示。
|
|
18
19
|
- 宿主半边允许的 catch,每处写明原因:
|
|
19
20
|
- `webServer.register` 以抛错拒绝已被别的插件占用的路径:逐条注册,被拒的记警告,其余照常(宿主半边的纤程失败会连带撤下浏览器半边的整个包)。
|
|
20
21
|
- 卸载时逐个运行路由的撤销函数,单个失败记警告后继续。
|
|
21
22
|
- 删除会话的请求体不是 JSON 时答 400;删除过程中的任何故障答 500 并带错误信息。
|
|
23
|
+
- 写入或删除品牌图过程中的任何故障答 500 并带错误信息(D64)。
|
|
22
24
|
- 宿主半边 `lib/assets/manifest.json` 读不了或不是 JSON 时答 404:那是构建没跑完的状态,记一次警告即可,不必让路由本身失败。
|
|
23
25
|
- 成本计量插件的账本是别的插件的文件,读取与它的写入没有协调,解析不了时当作没有账本、改用本地折算。
|
|
24
26
|
- 用量汇总自己的缓存只省工作量:读不了时记警告并整体重算覆盖,写不进时记警告、本轮结果照常返回。
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
- 数据读宿主的客户端服务:`sessions.list` 与 `workspaces.list`(去掉已归档、子代理与空白占位)、`remote.pluginInventory` 与 `remote.pluginManager`、当前会话的 `remote.skills`、`shortcuts.catalog`。远程命名空间在面板打开时用 `ctx.get('remote.<名字>')` 读(在根上下文直接读 `remote` 的子属性会被 cordis 以「没有 inject」拒绝)。
|
|
13
13
|
- 导航用宿主自己的:`uiWorkspace.openSession` / `startSession`、`pluginNavigation.openBundle`、`layout.selectPanel`;Skill 经会话输入的 `setDraft` 与 `focus`;设置页与快捷键列表经它们在插槽登记里声明的 store(`slots.entries(key)` 条目上的 `store.create()`)打开。快捷键行打开快捷键列表,不代为执行命令(宿主的快捷键命令没有公开的执行入口)。内容命中还要落到那条消息所在的一轮:面板开完会话,等这一轮进了窗口再按命中消息的事件序号定位(按 `turnOutline` 找轮次,跳转本身走 D34 那一套,按宿主的刻度跳)。
|
|
14
14
|
- 匹配沿用宿主侧栏搜索的子串规则,排序为:标题开头、标题中的词开头、标题其他位置、第二个键(路径、包名、描述、别名)。
|
|
15
|
-
- 消息内容由宿主半边的 `/session-search` 路由搜(`packages/host/src/search.ts`):日志经共享的 `session-events.ts`
|
|
15
|
+
- 消息内容由宿主半边的 `/session-search` 路由搜(`packages/host/src/search.ts`):日志经共享的 `session-events.ts` 读(宿主的观察接口,按 id 读起,不先列整份存档),只收人类发出的 `user/message`(按 `data.source.kind === 'user'` 排除注入的环境快照、Skill 目录、AGENTS.md 与压缩检查点)与助手消息里的 text 块,`reasoning`、`tool-call`、`tool/result` 都不进语料;匹配照搬 `sessionQuery` 的 `text` 过滤(字面、不分大小写、空白可伸缩)。每个会话的语料落一份 `$DSH_HOME/cache/dsh-claude-style/search/<会话 id>.json`(走共享的 `cache-file.ts`,与峰谷目录、用量缓存同目录):热启动读这些文件,只重读修订号变了的存档会话;宿主开着的会话按 `seq` 只读新增的那一段。存档会话的清单每 3 秒列一次(列一次要开每个日志的头部帧,是这条路上最贵的一步);面板打开时先发一次不带查询的请求预热;每个会话只回最新的一处命中,附摘录与命中位置。
|
|
16
16
|
|
|
17
17
|
## 理由
|
|
18
18
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
- **状态**:已实施
|
|
4
4
|
- **分组**:功能
|
|
5
|
-
- **关联**:D26、D29、D40、D41、D44
|
|
5
|
+
- **关联**:D26、D29、D40、D41、D44、D62
|
|
6
6
|
- **迁移**:聊天区契约表并入契约模块(D44,待实施)
|
|
7
7
|
|
|
8
8
|
## 决定
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
- 它们只读宿主自己写的属性;聊天区的整份宿主契约(流式容器、工具调用行、过程组、思考行的推理正文槽位、会话滚动条、输入框与回显气泡等)集中在 `packages/contracts/src/dom.ts` 一张表里。
|
|
12
12
|
- 功能自己写出的标记(DOM 标记、类名、`::highlight()` 名称、自定义属性、关键帧名称)一律用 `data-dsh-claude-` 前缀,与上游包同时装着时两套实现读不到对方的状态。
|
|
13
13
|
- 不止读标记的三处:
|
|
14
|
-
- 文件变更行接管宿主 `tool.call.toolview` 座位上的 `edit` 与 `write` 两个键位(优先级 -1
|
|
14
|
+
- 文件变更行接管宿主 `tool.call.toolview` 座位上的 `edit` 与 `write` 两个键位(优先级 -1,低于宿主自己那两个),改动派生与宿主的卡片模型只差「不排除子调用」这一条;同一个文件在同一个过程组里的多次改动读成一行,规则见 D62。
|
|
15
15
|
- 聊天气泡动效在 `<body>` 末尾挂一个临时替身,带 `inert` 与 `aria-hidden`,摘掉身份标记但保留样式钩子;飞行期间给真实那一行写标记把它藏起来(保留布局盒),到达后真实行先显示、替身淡出。
|
|
16
16
|
- 增强跟随在流式输出期间接管会话滚动条的跟随:宿主每次内容增长都把位置写到最底,跟随在同一帧绘制之前把这次位移撤回、交给滚动主人(D41)滑过去。宿主写这一下的地方是它挂上消息列时新建的 ResizeObserver(观察消息列、会话滚动条、输入框座位),浏览器按建立先后调用回调,所以跟随的观察者每遇到一条新的消息列就重建一次,排在宿主之后、观察同样三个元素。跟随期间把宿主自己的「回到底部」按钮临时藏起来(只写自己的标记,宿主的状态不动);读者自己发出的消息到达时跟随让开一段,宿主把新消息滚进视野的那一下照旧一步到位。
|
|
17
17
|
- 设置:这些功能共用皮肤自己的偏好条目与设置页,不动上游 `dsh-chat-ux` 的配置。对话区各项共用一个开关 `chatAnimations`(「聊天区动画效果」):开启时安装,关闭时这些功能一起卸载、各自把界面交还宿主。各功能的清单用 `pref` 声明自己挂在哪个偏好上,用 `prefValues` 声明一项选择偏好下自己运行的取值(D42);插入符动效是自己的三选一(`caretMotion`)。随偏好出现的样式规则由功能把标记写到 `<body>` 上(如 `data-dsh-claude-chat-follow`)。
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
- 读者自己的滚轮是浏览器的:滚动主人不接管这个事件,只把滚轮、触摸、指针按下、滚动键与页内查找记成「读者动过」,跟随与流式滑行的请求因此被拒绝。指针按下落在滚动条自己的条带上才算(会话滚动条与过程组主体用同一个判据),落在内容上是读者在打开什么。滚轮的减速曲线、触控板的惯性、边界处的表现都由平台自己画。
|
|
18
18
|
- 仲裁规则:
|
|
19
19
|
- 容器上正在滑行的来源优先级更高时,请求被拒绝;同级或更高的请求照常执行,直接写入还会结束正在滑行的低优先级来源。
|
|
20
|
-
- 读者接管一个容器后,`follow`、`stream`、`process` 的请求被拒绝,正在进行的滑行在下一帧结束;读者回到这个容器底部的阈值以内(会话 25px,过程组主体 4px),接管结束。结束由滚动事件当场判定,内容在读者回到底部之后才增长也不会留下接管。对话导航跳到某一轮时同样取一次接管(`holdReader`):跳转是读者自己选定的阅读位置,跟随在这一期间让开。接管期间容器带着 `data-dsh-claude-reader-hold
|
|
20
|
+
- 读者接管一个容器后,`follow`、`stream`、`process` 的请求被拒绝,正在进行的滑行在下一帧结束;读者回到这个容器底部的阈值以内(会话 25px,过程组主体 4px),接管结束。结束由滚动事件当场判定,内容在读者回到底部之后才增长也不会留下接管。对话导航跳到某一轮时同样取一次接管(`holdReader`):跳转是读者自己选定的阅读位置,跟随在这一期间让开。接管期间容器带着 `data-dsh-claude-reader-hold`,等待行的固定读这个标记(`packages/client/src/features/chat-wait/chat-wait.css`),只在跟随自己移动位置时成立,读者往回翻看时该行留在文档位置。
|
|
21
21
|
- 读者自己发出的消息(或宿主替它挂上的回显)到达后的 1.2 秒内,`stream` 的请求被拒绝、滑行结束,宿主把新消息滚进视野的那一下照旧一步到位。这段时间属于一个会话:会话一换当场作废,因为打开会话本身就会挂上这一轮自己的消息行。
|
|
22
22
|
- 减少动态效果时,滑行请求直接写目标位置。
|
|
23
23
|
- 读者的滚动意图在 `packages/client/src/shared/reader-intent.ts` 判定。功能问「读者在某一时刻之后动过没有」用 `readerMovedSince`。
|