dsh-style-tweaks 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/LICENSE +21 -0
  2. package/README.en.md +114 -0
  3. package/README.md +113 -0
  4. package/cordis.patch.yml +12 -0
  5. package/lib/client.js +2379 -0
  6. package/lib/client.js.map +1 -0
  7. package/lib/config.js +90 -0
  8. package/lib/config.js.map +1 -0
  9. package/lib/index.js +28 -0
  10. package/lib/index.js.map +1 -0
  11. package/lib/types/client/conversation-width.d.ts +81 -0
  12. package/lib/types/client/conversation-width.d.ts.map +1 -0
  13. package/lib/types/client/index.d.ts +104 -0
  14. package/lib/types/client/index.d.ts.map +1 -0
  15. package/lib/types/client/tweak-config.d.ts +55 -0
  16. package/lib/types/client/tweak-config.d.ts.map +1 -0
  17. package/lib/types/client/tweak-types.d.ts +32 -0
  18. package/lib/types/client/tweak-types.d.ts.map +1 -0
  19. package/lib/types/client/tweaks/code-block-flush-top.d.ts +91 -0
  20. package/lib/types/client/tweaks/code-block-flush-top.d.ts.map +1 -0
  21. package/lib/types/client/tweaks/locate-current-session.d.ts +62 -0
  22. package/lib/types/client/tweaks/locate-current-session.d.ts.map +1 -0
  23. package/lib/types/client/tweaks/project-running-indicator.d.ts +61 -0
  24. package/lib/types/client/tweaks/project-running-indicator.d.ts.map +1 -0
  25. package/lib/types/client/tweaks/registry.d.ts +22 -0
  26. package/lib/types/client/tweaks/registry.d.ts.map +1 -0
  27. package/lib/types/client/tweaks/settings-nav-scroll.d.ts +168 -0
  28. package/lib/types/client/tweaks/settings-nav-scroll.d.ts.map +1 -0
  29. package/lib/types/client/tweaks/stable-table.d.ts +3 -0
  30. package/lib/types/client/tweaks/stable-table.d.ts.map +1 -0
  31. package/lib/types/client/tweaks/stable-turn-rail.d.ts +53 -0
  32. package/lib/types/client/tweaks/stable-turn-rail.d.ts.map +1 -0
  33. package/lib/types/config.d.ts +149 -0
  34. package/lib/types/config.d.ts.map +1 -0
  35. package/lib/types/index.d.ts +19 -0
  36. package/lib/types/index.d.ts.map +1 -0
  37. package/lib/types/web.d.ts +55 -0
  38. package/lib/types/web.d.ts.map +1 -0
  39. package/lib/web.js +169 -0
  40. package/lib/web.js.map +1 -0
  41. package/package.json +111 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 zhj9709
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.en.md ADDED
@@ -0,0 +1,114 @@
1
+ # dsh-style-tweaks
2
+
3
+ > Dependency version: deepseek-harness v0.1.2-rc.1
4
+
5
+ A [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (DSH) web plugin that bundles a precise conversation column-width control with a collection of opt-in style tweaks for DSH's UI — including small fixes for the sidebar and the settings panel.
6
+
7
+ ## Features
8
+
9
+ ### Layout
10
+
11
+ - **Plugin width control (default on)** — when ON, the plugin's width input / presets drive the conversation column and DSH's native drag handles are hidden; when OFF, DSH's native handles own the column and the width input mirrors their value.
12
+ - **Dialog width** — any value between 600 and 1600 px; includes presets 748 (default) / 880 (Wide) / 1024 (Extra wide).
13
+ - **Side margin** — whitespace in px kept on each side of the conversation area. The column is clamped to the dialog width and narrows when the sidebar opens or the window shrinks, never hugging the edges. Minimum 32 px.
14
+
15
+ ### Tweaks
16
+
17
+ - **Stable table layout (default on)** — locks table layout on hover so surrounding content does not reflow ("text jumps when I hover a table").
18
+ - **Stable turn-navigation rail (default on)** — keeps the turn-navigation rail at a stable position when scrolling up past the first message into the system prompt area (no longer drops by ~16 px).
19
+ - **Flush code-block top (default on)** — removes the 16 px gap above highlighted code blocks so the code sits flush with the preceding paragraph, list item, or heading.
20
+ - **Project running indicator (default on)** — shows the conversation title's animated running dot on the right side of each project directory in the sidebar, so a running conversation stays visible even when its group is collapsed.
21
+ - **Locate current session (default on)** — adds a "locate" button to the left of the native search button in the sidebar's "Workspaces" section header. Clicking it expands the current session's workspace directory (if collapsed) and its "Show {n} more sessions" overflow, then scrolls the session into the sidebar's visible area. Disabled with the tooltip "Open a session first" when no session is open.
22
+ - **Scrollable settings nav (default on)** — lets the settings dialog's left menu scroll when its entries outgrow the panel, instead of silently clipping the ones at the bottom (the panel has a fixed height and `overflow: hidden`; stock CSS only gave the right content column a scroll treatment). The scrollbar is an overlay-style thin strip: parked in the rail's spare right padding so it never squeezes the menu, and visible only while the list is actually scrolling, fading out ~0.8 s after scrolling stops.
23
+
24
+ ```yaml
25
+ style-tweaks:
26
+ # Layout
27
+ usePluginWidth: true # default true; false hands the column back to native handles
28
+ dialogWidth: 748 # 600–1600 px
29
+ sideMargin: 50 # ≥ 32 px
30
+ # Tweaks
31
+ stableTable: true # default true; false disables the tweak
32
+ stableTurnRail: true # default true; false disables the tweak
33
+ codeBlockFlushTop: true # default true; false disables the tweak
34
+ projectRunningIndicator: true # default true; false disables the tweak
35
+ locateCurrentSession: true # default true; false hides the sidebar locate button
36
+ settingsNavScroll: true # default true; false disables the settings-nav scrolling
37
+ ```
38
+
39
+ Settings entry: **Settings → Style tweaks**.
40
+
41
+ ## Install
42
+
43
+ ```bash
44
+ # from npm (recommended, prebuilt)
45
+ npx -y @deepseek-ai/dsh plugin --profile web add dsh-style-tweaks
46
+
47
+ # from GitHub (source; runs the self-contained prepare build)
48
+ npx -y @deepseek-ai/dsh plugin --profile web add github:zhj9709/dsh-style-tweaks
49
+ ```
50
+
51
+ The package spec after `add` is forwarded to pnpm verbatim, so versions can be
52
+ pinned — `@version` for the npm package, `#tag` for the GitHub source:
53
+
54
+ ```bash
55
+ npx -y @deepseek-ai/dsh plugin --profile web add dsh-style-tweaks@0.1.0 # pin the npm version
56
+ npx -y @deepseek-ai/dsh plugin --profile web add github:zhj9709/dsh-style-tweaks#v0.1.0 # pin a git tag
57
+ ```
58
+
59
+ Restart DSH web once after installing (bundle plugins are scanned at process start).
60
+
61
+ ## Development
62
+
63
+ ### Build
64
+
65
+ ```bash
66
+ pnpm install
67
+ pnpm build # tsc (server) + tsc (client) + bundle lib/client.js
68
+ pnpm typecheck
69
+ ```
70
+
71
+ Load against a running DSH with an overlay, or install as a bundle:
72
+
73
+ ```bash
74
+ npx -y @deepseek-ai/dsh web --patch ./cordis.patch.yml # dev overlay
75
+ npx -y @deepseek-ai/dsh plugin --profile web add . # bundle install from this checkout
76
+ ```
77
+
78
+ ### Hot Reload (no reinstall needed)
79
+
80
+ Only the client plugin (`lib/client.js`) needs to be loaded by the DSH runtime. After each code change:
81
+
82
+ 1. **Build**:
83
+ ```bash
84
+ pnpm build
85
+ ```
86
+
87
+ 2. **Copy to the profile directory**:
88
+ ```bash
89
+ cp lib/client.js ~/.dsh/profiles/web/node_modules/dsh-style-tweaks/lib/client.js
90
+ ```
91
+
92
+ 3. **DSH's client-plugin HMR receiver** detects the change and automatically reloads the plugin — no reinstall required.
93
+
94
+ > Note: Sometimes the GUI process caches the old bundle, making it appear that changes have no effect. In this case, restart the `dsh web` process.
95
+
96
+ Only client plugins (`client.js`) support hot reloading. Changes to the `apps/web` shell or plain packages still require rebuilding web artifacts and a page refresh.
97
+
98
+ ## How it works
99
+
100
+ - **Server** (`src/index.ts`) registers the `style-tweaks` settings namespace and mounts a same-origin route (`/_dsh/style-tweaks/settings`).
101
+ - **Browser** (`src/client/index.tsx`) reads/writes that route, renders the Settings section, and mounts / unmounts each tweak live based on its toggle (pure-CSS tweaks inject runtime `<style>` elements; JS-level tweaks also read the app's own state stores and patch the DOM).
102
+ - **Column-width engine** (`src/client/conversation-width.ts`) writes the `--dsh-chat-user-width` CSS variable and hides DSH's native `[data-width-handle]` drag strips while plugin width control is on; the chosen px is also mirrored into the localStorage slot the native handles read, so flipping the switch round-trips cleanly.
103
+ - **Tweak registry** (`src/client/tweaks/registry.ts`) centralises each tweak's metadata (id, settings field name, default value, i18n keys); adding a new tweak means appending one entry here and dropping a new injector file under `src/client/tweaks/`.
104
+ - **Project running indicator** (`src/client/tweaks/project-running-indicator.ts`) reads session running state and directory membership from `ctx.get('sessions')` / `ctx.get('workspaces')`, and uses a MutationObserver to mount the app's own `StateDot` (re-using `@deepseek-ai/dsh-client-ui-primitives` so the animation keyframes and style tokens are byte-identical to the conversation title's dot) inside each project directory header row (`role="treeitem"[aria-expanded]`, a stable hand-written attribute).
105
+ - **Locate current session** (`src/client/tweaks/locate-current-session.ts`) injects a new button into the sidebar's workspaces section header, to the left of the native search button. All anchors are i18n-safe: the search button's aria-label and the breadcrumb nav's aria-label are resolved through `ctx.locale.bind()` (the `workspace` / `conversation` namespace keys DSH itself uses), with structural class-fragment fallbacks (`searchButton`, `crumbs`) when the locale service is unavailable. Clicking it reads the current session title from the breadcrumb's disabled crumb, resolves the parent workspace via `ctx.get('sessions')` / `ctx.get('workspaces')` app stores (works even when the workspace's sidebar group is collapsed), finds the workspace row by exact title match, then pierces both collapse layers — clicking the collapsed workspace row to expand it, and auto-clicking the "Show {n} more sessions" overflow button (`[class*="sessionOverflowButton"][aria-expanded="false"]`) when the target row hides behind it — before `scrollIntoView({ block: 'center' })`. The hover tooltip replicates DSH's native `<Tooltip>` primitive (fixed-position bubble, theme tokens, 500 ms delay, viewport flip) instead of the browser-native `title`. A MutationObserver watches `aria-selected` / `aria-expanded` attribute changes to keep the button's enabled state and mount in sync.
106
+ - **Scrollable settings nav** (`src/client/tweaks/settings-nav-scroll.ts`) turns the settings dialog's left nav list into the scroll container of the nav rail: DSH's settings panel (`SettingsRoot`) has one fixed height with `overflow: hidden` and only gave the right content column (`.options`) an `overflow-y: auto`; the left `.navList` has neither `min-height: 0` nor an overflow treatment, so extra entries spill out and get clipped. Two CSS rules plus a small JS driver do it: the base rule `flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding-bottom: 12px; margin-inline-end: -12px` makes the list scrollable and parks the classic scrollbar in the nav rail's full 12px right padding gutter (8px gap + 4px strip), so the thumb floats over the spare padding 8px clear of the entries; a cell cap `max-width: 164px` (DSH's stock 188 nav − 2×12 padding) pins the entries to stock width in every state — bar present or not, hovering or scrolling — and `::-webkit-scrollbar { width: 4px }` is two notches thinner than DSH's global skin. The show timing is JS-driven: the first cut used `:not(:hover)` to blank the thumb, but Chromium does not reliably repaint custom scrollbar pseudo-elements when only the host's `:hover` state changes (in practice the bar appeared when clicking a nav cell — the React re-render forced the repaint), so the driver listens for `scroll` events on the list instead: scrolling adds a `cst-nav-scroll-show` class that reveals the thumb (coloured from the panel's inherited l2 tokens), and the class is removed ~0.8 s after scrolling stops; a MutationObserver re-attaches the listener whenever the dialog unmounts and reopens. The selector pairs the modal structure with a CSS Modules class fragment (DSH hashes classes as `[hash]_[local]`; the `navList` local name is unique across DSH), and needs no `!important`.
107
+
108
+ ## Acknowledgements
109
+
110
+ This plugin was inspired by and built with reference to [wlj521/dsh-ui-tweaks](https://github.com/wlj521/dsh-ui-tweaks) — a more comprehensive DSH UI customisation plugin covering fonts, tables, timeline, Git, and more. If this plugin does not cover what you need, check that one out.
111
+
112
+ ## License
113
+
114
+ MIT
package/README.md ADDED
@@ -0,0 +1,113 @@
1
+ # dsh-style-tweaks
2
+
3
+ > 依赖版本:deepseek-harness v0.1.2-rc.1
4
+
5
+ [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(DSH)Web UI 插件:为 DSH 界面提供一套可选的样式调整——精确的对话列宽控制,以及侧边栏与设置面板的一系列小幅度修复。
6
+
7
+ ## 功能
8
+
9
+ ### 布局
10
+
11
+ - **插件宽度控制**(默认开启):开启时插件自带的列宽输入 / 预设接管列宽,并隐藏 DSH 原生的拖拽手柄;关闭时原生手柄接管列宽,插件同步显示当前值。
12
+ - **对话框宽度**:600–1600 px 之间任意值;含 748(默认)/ 880(稍宽)/ 1024(更宽)三个预设按钮。
13
+ - **两侧边距**:对话区域两侧保留的空白(px),列宽被钳制为对话框宽度,侧边栏打开或窗口缩小时内容会收窄,不会贴住边缘。最低 32 px。
14
+
15
+ ### 调整项
16
+
17
+ - **表格布局稳定(默认开启)**:锁住 markdown 表格 hover 时的布局,避免周围内容发生回流("鼠标移到表格上时下方文本会跳动")。
18
+ - **轮次导航栏稳定(默认开启)**:向上滚动到第一条消息上方的系统提示词区域时,让右侧轮次导航栏保持在原位(不再下移约 16 像素)。
19
+ - **代码块顶部贴齐(默认开启)**:去掉高亮代码块上方的 16 px 空白,让代码块紧贴在前面的段落、列表项或标题下方。
20
+ - **项目目录运行指示(默认开启)**:在侧边栏项目目录右侧显示与对话标题一致的运行动画圆点,目录收起时也能一眼看出里面有对话正在进行。
21
+ - **定位当前会话(默认开启)**:在侧边栏"工作区"段头部的搜索按钮左边新增一个定位按钮;点击后自动展开当前会话所属的工作区目录(包括"展开其余 x 个会话"的折叠层),将该会话滚动到侧边栏视口中央。无当前会话时按钮禁用并提示"请先打开一个会话"。
22
+ - **设置菜单可滚动(默认开启)**:设置项较多时,让设置面板左侧菜单可以上下滚动,而不是把放不下的项直接裁掉(面板高度固定且 `overflow: hidden`,原生样式只给右侧内容列加了滚动)。滚动条为悬浮式细条:停靠在菜单右侧的留白里、不挤压菜单宽度,只在列表实际滚动时出现,停止滚动约 0.8 秒后淡出。
23
+
24
+ ```yaml
25
+ style-tweaks:
26
+ # 布局
27
+ usePluginWidth: true # 默认 true;false 时由原生拖拽手柄接管
28
+ dialogWidth: 748 # 600–1600 px
29
+ sideMargin: 50 # ≥ 32 px
30
+ # 调整项
31
+ stableTable: true # 默认 true;false 则关闭
32
+ stableTurnRail: true # 默认 true;false 则关闭
33
+ codeBlockFlushTop: true # 默认 true;false 则关闭
34
+ projectRunningIndicator: true # 默认 true;false 则关闭
35
+ locateCurrentSession: true # 默认 true;false 则隐藏侧边栏定位按钮
36
+ settingsNavScroll: true # 默认 true;false 则关闭设置左侧菜单滚动
37
+ ```
38
+
39
+ 设置入口:**设置 → 样式调整**。
40
+
41
+ ## 安装
42
+
43
+ ```bash
44
+ # 方式一:从 npm 安装(推荐,预构建产物)
45
+ npx -y @deepseek-ai/dsh plugin --profile web add dsh-style-tweaks
46
+
47
+ # 方式二:从 GitHub 仓库安装(源码,会运行自包含的 prepare 构建)
48
+ npx -y @deepseek-ai/dsh plugin --profile web add github:zhj9709/dsh-style-tweaks
49
+ ```
50
+
51
+ `add` 后面的包说明会**原样转发给 pnpm**,因此可以指定版本——npm 包用 `@版本号`,GitHub 源码用 `#tag`:
52
+
53
+ ```bash
54
+ npx -y @deepseek-ai/dsh plugin --profile web add dsh-style-tweaks@0.1.0 # 锁定 npm 版本
55
+ npx -y @deepseek-ai/dsh plugin --profile web add github:zhj9709/dsh-style-tweaks#v0.1.0 # 锁定 git tag
56
+ ```
57
+
58
+ 安装完成后**重启一次 `dsh web`**(bundle 插件在进程启动时扫描)。
59
+
60
+ ## 开发
61
+
62
+ ### 构建
63
+
64
+ ```bash
65
+ pnpm install
66
+ pnpm build # tsc(服务端)+ tsc(客户端)+ 打包 lib/client.js
67
+ pnpm typecheck
68
+ ```
69
+
70
+ 本地加载(覆盖层)或作为 bundle 安装:
71
+
72
+ ```bash
73
+ npx -y @deepseek-ai/dsh web --patch ./cordis.patch.yml # 开发覆盖层
74
+ npx -y @deepseek-ai/dsh plugin --profile web add . # 从本目录作为 bundle 安装
75
+ ```
76
+
77
+ ### 热重载(免安装)
78
+
79
+ 构建产物只有客户端插件(`lib/client.js`)需要被 DSH 运行时加载。每次修改代码后:
80
+
81
+ 1. **构建**:
82
+ ```bash
83
+ pnpm build
84
+ ```
85
+
86
+ 2. **复制到 profile 目录**:
87
+ ```bash
88
+ cp lib/client.js ~/.dsh/profiles/web/node_modules/dsh-style-tweaks/lib/client.js
89
+ ```
90
+
91
+ 3. **DSH 的 client-plugin HMR receiver** 会检测文件变更并自动重新加载插件,无需重新安装。
92
+
93
+ > 注意:有时 GUI 进程会缓存旧 bundle,表现为改动未生效。此时需要重启 `dsh web` 进程。
94
+
95
+ 只有客户端插件(`client.js`)支持热重载。修改 `apps/web` shell 或普通 package 后仍需重新构建 Web 产物并刷新页面。
96
+
97
+ ## 工作原理
98
+
99
+ - **服务端**(`src/index.ts`):注册 `style-tweaks` 设置命名空间,并挂载同源路由 `/_dsh/style-tweaks/settings`。
100
+ - **浏览器端**(`src/client/index.tsx`):读写该路由、渲染设置页,并根据每个开关的状态实时挂载 / 卸载对应的调整项(纯 CSS 调整项注入运行时 `<style>` 元素;JS 级调整项还会读写应用自身的状态 store 并修补 DOM)。
101
+ - **列宽样式引擎**(`src/client/conversation-width.ts`):写入 `--dsh-chat-user-width` CSS 变量,并在插件接管列宽时隐藏原生 `[data-width-handle]` 拖拽手柄;宽度值同时镜像到原生手柄读取的 localStorage 槽位,开关切换时无缝往返。
102
+ - **调整项注册表**(`src/client/tweaks/registry.ts`):每个调整项的元数据(id、settings 字段名、默认值、i18n 键)集中登记;新增调整项只需在注册表里加一条,并在 `src/client/tweaks/` 下新增一个注入文件。
103
+ - **项目目录运行指示**(`src/client/tweaks/project-running-indicator.ts`):从 `ctx.get('sessions')` / `ctx.get('workspaces')` 读取会话运行状态与目录归属,用 MutationObserver 在项目目录头行(`role="treeitem"[aria-expanded]`,稳定手写属性)内挂载应用自身的 `StateDot`(复用 `@deepseek-ai/dsh-client-ui-primitives` 的同一份模块,动画 keyframes 与样式 token 与对话标题处完全一致)。
104
+ - **定位当前会话**(`src/client/tweaks/locate-current-session.ts`):在 DSH 侧边栏"工作区"段头部的搜索按钮左边注入一个新按钮。锚点全部走 i18n 与语义片段:通过 `ctx.locale.bind()` 解析当前语言的搜索按钮 aria-label(`workspace` 命名空间的 `search.sessions.aria` 键)与顶部面包屑的 aria-label(`conversation` 命名空间的 `session.hierarchy` 键),locale 服务不可用时退回 `[class*="searchButton"]` / `[class*="crumbs"]` 语义片段兜底。点击后从面包屑(`button[disabled]` 的当前项)读出会话标题,用 `ctx.get('sessions')` 与 `ctx.get('workspaces')` 两个应用级 store 反查所在工作区标题(即使其工作区目录收起也能定位),再按标题匹配工作区行;依次穿透两级折叠——工作区收起时 click 展开、"展开其余 x 个会话"溢出按钮(`[class*="sessionOverflowButton"][aria-expanded="false"]`)挡住目标行时自动点开——然后 `scrollIntoView({ block: 'center' })` 滚动居中。悬停提示复刻了 DSH 原生 `<Tooltip>` 的自研气泡(fixed 定位 + 主题 token + 500ms 延迟 + 视口翻转),而非浏览器原生 `title`。MutationObserver 监听 `aria-selected` / `aria-expanded` 属性变化同步按钮可用性与挂载状态。
105
+ - **设置菜单可滚动**(`src/client/tweaks/settings-nav-scroll.ts`):DSH 设置面板(`SettingsRoot`)高度固定且 `overflow: hidden`,原生样式只让右侧内容列(`.options`)滚动;左侧菜单列表 `.navList` 没有 `min-height: 0` 与 overflow 处理,条目多时被面板直接裁掉。本调整项用"两条 CSS 规则 + 一个小型 JS 驱动"实现:基础规则 `flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding-bottom: 12px; margin-inline-end: -12px` 让列表成为滚动容器,并把滚动条"停靠"进导航栏右侧的 12px 留白里(8px 间距 + 4px 条位,恰好占满留白),滑块悬浮在留白上、与菜单项保持 8px 间距;菜单项上限 `max-width: 164px`(DSH 原生 188 导航 − 2×12 padding)钉住原生宽度,无论滚动条出现与否、悬停还是滚动,菜单项都与原生完全同宽;`::-webkit-scrollbar { width: 4px }` 比全局皮肤细两档。显示时机由 JS 驱动:第一版用 `:not(:hover)` 隐藏滑块,但 Chromium 在宿主 `:hover` 变化时不会可靠重绘自定义滚动条伪元素(实测表现为"点击菜单才出现"),因此改为监听列表 `scroll` 事件——滚动时给列表加 `cst-nav-scroll-show` 类显示滑块(颜色沿用面板继承的 l2 主题 token),停止滚动约 0.8 秒后移除类淡出;MutationObserver 在设置弹窗卸载/重开时保持监听器挂在当前列表上。选择器用"弹窗结构 + CSS Modules 语义片段"双保险(DSH 类名按 `[hash]_[local]` 哈希,`navList` 局部名全 DSH 唯一),无需 `!important`。
106
+
107
+ ## 致谢
108
+
109
+ 本插件的灵感来自并参考了 [wlj521/dsh-ui-tweaks](https://github.com/wlj521/dsh-ui-tweaks)——一个更全面的 DSH UI 个性化插件,覆盖字体、表格、时间线、Git 等更多维度。如果本插件的功能不够用,欢迎前往看看。
110
+
111
+ ## 协议
112
+
113
+ MIT
@@ -0,0 +1,12 @@
1
+ # dsh-style-tweaks bundle patch
2
+ #
3
+ # Declared by `dsh.bundle.patch` in package.json: when the plugin is installed
4
+ # through the official CLI —
5
+ #
6
+ # dsh plugin --profile <name> add dsh-style-tweaks
7
+ #
8
+ # — the command appends `dsh-style-tweaks` to the profile's bundle
9
+ # stack and this patch mounts the server-side plugin row.
10
+ - insert:
11
+ - id: style-tweaks
12
+ name: 'dsh-style-tweaks'