From 5b20893c273284fa0cc3d0a144d6e6f59c280f16 Mon Sep 17 00:00:00 2001 From: Daizhdd <1249767897@qq.com> Date: Wed, 16 Sep 2026 10:10:08 +0800 Subject: [PATCH 1/5] workbuddy: add 5.5.6 field notes on opaque backplates, appearance pairing, and diagnosis Expanded documentation on UI elements, themes, and appearance handling. Added details on wallpaper brightness and diagnosing rendering issues. --- .../codedrobe-theme/references/workbuddy.md | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/skills/codedrobe-theme/references/workbuddy.md b/skills/codedrobe-theme/references/workbuddy.md index 4575ef0..f7096ca 100644 --- a/skills/codedrobe-theme/references/workbuddy.md +++ b/skills/codedrobe-theme/references/workbuddy.md @@ -27,3 +27,65 @@ Capture separate home and conversation snapshots before adapting `assets/theme-s 2. A conversation with long text, tables or code, scrolling, and the conversation composer shell. 3. Sidebar selection, hover states, menus, input, microphone, model selector, and send controls. 4. No horizontal overflow or hidden native actions. + +## Opaque backplates that hide the wallpaper + +An apply can report complete success while the window looks untouched: the renderer paints its own solid surfaces on top of the injected background. On **5.5.6** the wallpaper reaches the screen only after these are cleared. + +| Element | What it painted | +| ------------------------------------------------------------ | ---------------------------------------------------------------------------------- | +| `.conversation-shell` | solid white | +| `[class*="gridView"]`, `[class*="_grid_"]` | solid white — CSS-Module hash classes for the grid layout cells | +| `main.wb-home-route` | solid white — **home route only** | +| `#workbuddy-menubar-container` | `rgb(242, 242, 242)`, the top 30 px strip | +| `.workbuddy-window-controls` | `--cb-panel-bg-primary` — the strip behind the minimise / maximise / close buttons | +| `.cr-input-container`, `.cr-input-toolbar__right` | solid white, inside the composer | +| `.collapsible-section-header`, `.conversation-section-label` | `rgb(242, 242, 242)` — sidebar group headers | +| `[class*="cb-agent-card"]` | white / `rgb(230, 230, 230)` — sidebar conversation cards | + +Two traps found while deriving this list: + +- **`.wb-home-route` is home-only.** Because that plate does not exist on the conversation route, a theme can look correct in a conversation and washed out on the home screen. Verify both routes. +- **Do not use `[class*="grid_"]`.** It also matches unrelated class names such as `artifact-slot-panel__grid`. + +The list is version-bound. When the app updates, re-derive it rather than trusting the table. + +## Routes and appearance + +- The conversation container is `.conversation-shell` and the home route is `main.wb-home-route`. `.chat-container` no longer exists. +- Appearance is driven by the **`data-theme` attribute on ``** (`light` / `dark`) plus a semantic token set (`--cb-text-primary`, `--cb-panel-bg-primary`, `--cb-bg-secondary`, `--sk-*`, several thousand custom properties in total). Swapping only the `light` / `cb-light` classes changes nothing. +- A theme can therefore follow the host appearance with `html[data-theme="dark"] { … }`, which outranks a plain host selector — so a single package can adapt instead of hard-coding one appearance. + +## Wallpaper brightness has to match the host appearance + +Text colour follows the host appearance, so when a wallpaper sits behind the UI its brightness decides whether the text survives: a dark image with the light appearance gives dark text on dark artwork, and the reverse. Matched pairs need no treatment at all; mismatched pairs need a scrim. + +Solving for the scrim is more predictable than guessing. Sample the wallpaper's mean luminance `L` (scale to roughly 48×48, average `0.2126R + 0.7152G + 0.0722B`), then + +- white scrim `a = (196 − L) / (255 − L)` when `L < 196` +- black scrim `a = 1 − 82 / L` when `L > 82` + +clamp to ≤ 0.82, and emit one value per appearance. Two notes from practice: + +- Mean luminance does not describe how *busy* a wallpaper is. A bright but finely detailed illustration still needs a small white scrim (~0.40), because fine detail behind text reads as noise. +- Because the pairing is what matters, the computed values are a good basis for telling the user which appearance their image wants — and for flagging when it does not match the one they are using. + +## Diagnosing "apply succeeded but nothing changed" + +A passing apply only proves the style reached the renderer. If the window looks untouched, an ancestor is painting an opaque background. Rather than guessing: + +1. Walk up from `document.elementFromPoint(x, y)`, printing `backgroundColor` for each ancestor — this shows which layer covers the image. +2. Enumerate every element whose `backgroundColor` alpha exceeds 0.85 and that intersects the viewport, sorted by visible area. **Do not filter by area threshold** — a size filter misses small chrome such as the window-control strip. + +## Do not verify colours through a scripted appearance switch + +Setting `data-theme` by hand (or swapping the appearance classes) does not update colours the app writes during its own render pass. Reading them straight afterwards returns the *previous* appearance's value, which looks exactly like "this colour ignores the theme" and invites a wrong conclusion. Scripted switches are fine for previewing background and layout; verify text contrast by switching appearance through the app (avatar → 外观) and measuring after that. + +## Surfaces to leave opaque + +Clearing backgrounds is not a blanket operation. Keep these as they are: + +- **Right detail panel** (`detail-panel`, `detail-main`, `sidebar-next`, `detail-layout`). It exists to preview documents and artefacts; with a transparent background the artwork sits behind the content and hurts reading. +- **Conversation content cards** (`.cr-tool-exp__content`, `.cr-code-like-box`, …), buttons and avatars — content and controls, not window chrome. + +Clear chrome only: sidebar, top bar, menu bar, window controls, composer shell. From 125e4479d3011fbb2a7bb14f4bf1f1580fed5950 Mon Sep 17 00:00:00 2001 From: Daizhdd <1249767897@qq.com> Date: Wed, 16 Sep 2026 10:22:06 +0800 Subject: [PATCH 2/5] workbuddy: add Chinese version of the 5.5.6 field notes --- .../references/workbuddy.zh.md | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 skills/codedrobe-theme/references/workbuddy.zh.md diff --git a/skills/codedrobe-theme/references/workbuddy.zh.md b/skills/codedrobe-theme/references/workbuddy.zh.md new file mode 100644 index 0000000..5cd020c --- /dev/null +++ b/skills/codedrobe-theme/references/workbuddy.zh.md @@ -0,0 +1,93 @@ +# WorkBuddy 适配目标 + +> 本文件是 [`workbuddy.md`](./workbuddy.md) 的中文版,内容一一对应。 + +使用 app id `workbuddy`。用 `codedrobe apps --json` 读取当前默认值与最近验证过的应用版本。内置默认 CDP 端口目前是 `9336`,但显式传入的 `--port` 必须优先。 + +## 应用行为 + +WorkBuddy 目前只做渲染层主题,不需要 Codex 那套宿主外观设置。只要能连上渲染进程,通常无需重启应用即可换肤。 + +- 非标准安装路径用 `--app-path`。 +- 不要修改 `WorkBuddy.app`、它的 Electron 资源或 `app.asar`。 +- 一律通过 Core 应用与还原,这样图片 object URL、observer、样式与根节点标记才能被一致地清理干净。 + +## 验证面 + +适配器只保留稳定的跨路由地标: + +- root:teams 容器 +- sidebar:会话侧栏 / 列表 +- workspace:teams 主内容区、主内容区,或 chat 容器 +- composer:可编辑文本框 + +首页的布局规则留在主题包里。对于一个同时样式化 WorkBuddy 首页与会话页的主题,至少要验证: + +在改写 `assets/theme-starter/workbuddy.css` 或 `assets/examples/miku-future-beats/workbuddy.css` 之前,先分别截取首页与会话页的快照。优先采用界面上现存的语义类名,而不是任何可能已过时的示例选择器。 + +1. 首页标题/hero、场景标签、快捷动作、首页输入框,以及具名图片。 +2. 一个包含长文本、表格或代码、可滚动内容的会话,以及会话输入框外壳。 +3. 侧栏选中态、悬停态、菜单、输入框、麦克风、模型选择器、发送按钮。 +4. 无横向溢出,原生操作项没有被遮挡。 + +## 会盖住壁纸的不透明底板 + +一次 apply 可以完整报告成功,而窗口看起来毫无变化:渲染进程在注入的背景之上又画了自己的实色表面。在 **5.5.6** 上,只有清掉下面这些,壁纸才能真正显示出来。 + +| 元素 | 它原来的颜色 | +| --- | --- | +| `.conversation-shell` | 实色白 | +| `[class*="gridView"]`、`[class*="_grid_"]` | 实色白 —— 网格布局单元,CSS Module 生成的哈希类 | +| `main.wb-home-route` | 实色白 —— **仅首页路由有** | +| `#workbuddy-menubar-container` | `rgb(242, 242, 242)`,顶部 30px 的条 | +| `.workbuddy-window-controls` | `--cb-panel-bg-primary` —— 最小化 / 最大化 / 关闭按钮下面的那条 | +| `.cr-input-container`、`.cr-input-toolbar__right` | 实色白,在输入框内层 | +| `.collapsible-section-header`、`.conversation-section-label` | `rgb(242, 242, 242)` —— 侧栏分组标题 | +| `[class*="cb-agent-card"]` | 白 / `rgb(230, 230, 230)` —— 侧栏会话卡片 | + +梳理这张表时踩到两个坑: + +- **`.wb-home-route` 只有首页有。** 会话页没有这层,所以一个主题可能「会话页正常、首页发白」。两条路由都要验证。 +- **不要用 `[class*="grid_"]`。** 它会误伤 `artifact-slot-panel__grid` 这类无关类名。 + +这张表是绑定版本的。应用升级后要重新推导,不要直接照信。 + +## 路由与外观 + +- 会话容器是 `.conversation-shell`,首页路由是 `main.wb-home-route`。`.chat-container` 已不存在。 +- 外观由 **`` 上的 `data-theme` 属性**驱动(`light` / `dark`),配套一整套语义 token(`--cb-text-primary`、`--cb-panel-bg-primary`、`--cb-bg-secondary`、`--sk-*`,合计数千个自定义属性)。只换 `light` / `cb-light` 这些 class 是没有任何效果的。 +- 因此主题可以用 `html[data-theme="dark"] { … }` 跟随宿主外观 —— 它的特异性高于普通宿主选择器,所以**一个主题包就能自适应,而不是把某一种外观写死**。 + +## 壁纸明暗必须与宿主外观匹配 + +文字颜色跟着宿主外观走,所以当壁纸铺在界面之后时,它的明暗决定了文字还能不能读:深色图配浅色外观,就是深色文字压在深色画面上,反过来同理。**配对时零处理;不配对时才需要一层纱。** + +把纱「解」出来比凭感觉调更可控。取壁纸的平均亮度 `L`(缩到约 48×48,按 `0.2126R + 0.7152G + 0.0722B` 求平均),然后 + +- 白纱 `a = (196 − L) / (255 − L)`,当 `L < 196` 时 +- 黑纱 `a = 1 − 82 / L`,当 `L > 82` 时 + +上限截到 0.82,并为每种外观各输出一个值。实践中有两点补充: + +- 平均亮度描述不了壁纸有多**繁密**。一张很亮但细节细碎的插画,仍然需要一层薄白纱(约 0.40),因为文字背后的细密花纹读起来就是噪点。 +- 既然关键在「配对」,那么算出来的这组值正好可以用来告诉用户:**他这张图想要哪种外观** —— 以及当他正在用的外观不匹配时给出提醒。 + +## 诊断「apply 成功但界面没变化」 + +apply 通过只能证明样式到达了渲染进程。如果窗口看起来毫无变化,那一定是有祖先元素在画不透明背景。不要猜: + +1. 从 `document.elementFromPoint(x, y)` 逐级向上回溯,打印每一层的 `backgroundColor` —— 这样就能看出是哪一层盖住了图。 +2. 枚举所有 `backgroundColor` 的 alpha 大于 0.85、且与视口相交的元素,按可见面积排序。**不要用面积阈值去过滤** —— 尺寸过滤会漏掉窗口按钮条这类小组件。 + +## 不要用脚本切换外观来验证颜色 + +手动设置 `data-theme`(或替换外观 class)**不会**更新应用在自己那一趟渲染里写上去的颜色。紧接着读它们,拿到的还是**上一个外观的值** —— 看起来就像「这个颜色不跟随主题」,从而导出错误结论。脚本切换用来看背景和布局没问题;要验证文字对比度,请**在应用里真正切换外观**(头像 → 外观)之后再测量。 + +## 应当刻意保持不透明的表面 + +清背景不是一个「一刀切」的操作。下面这些要保持原样: + +- **右侧详情面板**(`detail-panel`、`detail-main`、`sidebar-next`、`detail-layout`)。它的用途是预览文档与工件;背景一透明,画面就压在内容下面,反而影响阅读。 +- **会话内的内容卡片**(`.cr-tool-exp__content`、`.cr-code-like-box` 等)、按钮与头像 —— 这些是内容与控件,不是窗口 chrome。 + +只清 chrome:侧栏、顶栏、菜单栏、窗口按钮条、输入框外壳。 From 1909f691d81331c2da7d4d4109198b2e48c7539f Mon Sep 17 00:00:00 2001 From: Daizhdd <1249767897@qq.com> Date: Wed, 16 Sep 2026 19:43:20 +0800 Subject: [PATCH 3/5] workbuddy: correct the wb-home-route note, add two more 5.5.6 findings - `.wb-home-route` is a real `
` but not an ancestor of the home content: it is a sibling underlay, so walking up from `elementFromPoint` never reaches it. That is the mechanism behind "right in a conversation, white on home". Write the selector without a tag name. - The ancestor walk has that blind spot in general; enumerate opaque elements whenever it comes back clean and the result is still wrong. Verify clears by reading the computed background, not by reading the CSS. - `.collapsible-section-header` cannot be cleared from a theme: the app's own important rule wins against a (0,4,1) important override, and redefining --cb-sidebar-bg / --wb-sidebar-bg does not help. Leave it native. - New section: a wallpaper-only theme contains no geometry. The home hero is a centred title painted over by the plate, so any width / max-width / gap / min-height / padding on .wb-home-page or .wb-home-header clips it and detaches the scene tabs. Symptom, cause, and the minimal shape of the file. - New scrim caveat: an over-heavy veil inverts a bimodal image's tonality. At .93 the light half landed at 28 while the dark half sat at 46 under a lighter .62, collapsing the sidebar into a flat black band. Pick the floor so the light-art region matches the rest of the window, and measure a row of the screenshot rather than eyeballing it. Docs only; no runtime code, no new Skill, no adapter selectors. --- .../codedrobe-theme/references/workbuddy.md | 56 +++++++++++++++++- .../references/workbuddy.zh.md | 58 +++++++++++++++++-- 2 files changed, 107 insertions(+), 7 deletions(-) diff --git a/skills/codedrobe-theme/references/workbuddy.md b/skills/codedrobe-theme/references/workbuddy.md index f7096ca..9628442 100644 --- a/skills/codedrobe-theme/references/workbuddy.md +++ b/skills/codedrobe-theme/references/workbuddy.md @@ -36,18 +36,22 @@ An apply can report complete success while the window looks untouched: the rende | ------------------------------------------------------------ | ---------------------------------------------------------------------------------- | | `.conversation-shell` | solid white | | `[class*="gridView"]`, `[class*="_grid_"]` | solid white — CSS-Module hash classes for the grid layout cells | -| `main.wb-home-route` | solid white — **home route only** | +| `.wb-home-route` | solid white, 972×734 — **home route only** | | `#workbuddy-menubar-container` | `rgb(242, 242, 242)`, the top 30 px strip | | `.workbuddy-window-controls` | `--cb-panel-bg-primary` — the strip behind the minimise / maximise / close buttons | | `.cr-input-container`, `.cr-input-toolbar__right` | solid white, inside the composer | -| `.collapsible-section-header`, `.conversation-section-label` | `rgb(242, 242, 242)` — sidebar group headers | +| `.collapsible-section-header`, `.conversation-section-label` | `rgb(242, 242, 242)` — sidebar group headers (**see the note below: not clearable**) | | `[class*="cb-agent-card"]` | white / `rgb(230, 230, 230)` — sidebar conversation cards | Two traps found while deriving this list: -- **`.wb-home-route` is home-only.** Because that plate does not exist on the conversation route, a theme can look correct in a conversation and washed out on the home screen. Verify both routes. +- **`.wb-home-route` is home-only, and it is not an ancestor of the home content.** It really is `
`, but on 5.5.6 it is painted as a *sibling underlay* — below the home UI, above your background. Walking up from `document.elementFromPoint` never reaches it, so the ancestor walk returns a clean stack while the window stays washed out. Only full enumeration finds it. This is the exact mechanism behind "looks correct in a conversation, white on home". - **Do not use `[class*="grid_"]`.** It also matches unrelated class names such as `artifact-slot-panel__grid`. +Write the selector without a tag name — `.wb-home-route`, not `main.wb-home-route`. The element happens to be a `
`, but the plate is worth clearing whether or not that stays true across releases. + +`.collapsible-section-header` is the one plate on this list that **cannot be cleared from a theme**. The app paints it from `.conversation-section-content [class^="collapsible-section"] > [class*="header"] { background: var(--wb-sidebar-bg, var(--cb-sidebar-bg, var(--vscode-sideBar-background, #fff))) !important }`. Raising your own selector past that — a `(0,4,1)` `!important` was tried — still loses, and redefining `--cb-sidebar-bg` / `--wb-sidebar-bg` does not help either, so specificity alone is not the deciding factor. Leave it native and say so in the theme, rather than shipping a rule that silently does nothing. + The list is version-bound. When the app updates, re-derive it rather than trusting the table. ## Routes and appearance @@ -69,6 +73,9 @@ clamp to ≤ 0.82, and emit one value per appearance. Two notes from practice: - Mean luminance does not describe how *busy* a wallpaper is. A bright but finely detailed illustration still needs a small white scrim (~0.40), because fine detail behind text reads as noise. - Because the pairing is what matters, the computed values are a good basis for telling the user which appearance their image wants — and for flagging when it does not match the one they are using. +- **Do not let the scrim go so heavy that it inverts the image's own tonality.** On a bimodal wallpaper this bites in the dark appearance. A left-to-right ramp heavy enough to crush the image's light half (`.93`) took it from 253 down to 28, while the image's dark half — under a much lighter `.62` — landed at 46. The light half ended up *darker* than the dark half, and the sidebar, which sits over that light half, collapsed into a flat near-black band with no texture left in it. The user reads that as a rendering bug, not as a wallpaper. Pick the floor so the light-art region lands in roughly the same tone band as the rest of the window: at `.83` the left end sits at 52 against 52–60 across the content area, and the band disappears. Measure this rather than eyeballing it — sample one horizontal row of the screenshot across the side bar and content, and check the step between them. + + Rough target for light text on a dark theme: keep the whole window under ~110 luminance with the darkest and lightest areas within ~10–15 of each other, or the wallpaper's own structure starts reading as a UI defect. ## Diagnosing "apply succeeded but nothing changed" @@ -76,6 +83,9 @@ A passing apply only proves the style reached the renderer. If the window looks 1. Walk up from `document.elementFromPoint(x, y)`, printing `backgroundColor` for each ancestor — this shows which layer covers the image. 2. Enumerate every element whose `backgroundColor` alpha exceeds 0.85 and that intersects the viewport, sorted by visible area. **Do not filter by area threshold** — a size filter misses small chrome such as the window-control strip. +3. Do not trust step 1 on its own. The ancestor walk has a blind spot: a solid **sibling** layer painted below the content but above the background is invisible to it, and its stack comes back clean while the window is still washed out. Whenever step 1 comes back clean and the result is still wrong, run step 2 — that is what surfaces `.wb-home-route`. + +Confirm the fix the same way: after applying, read the computed `backgroundColor` of every plate on your clear list and check it is actually `rgba(0, 0, 0, 0)`. A rule can look right in the source and still be losing a cascade fight; only the computed value proves it landed. ## Do not verify colours through a scripted appearance switch @@ -89,3 +99,43 @@ Clearing backgrounds is not a blanket operation. Keep these as they are: - **Conversation content cards** (`.cr-tool-exp__content`, `.cr-code-like-box`, …), buttons and avatars — content and controls, not window chrome. Clear chrome only: sidebar, top bar, menu bar, window controls, composer shell. + +## A wallpaper-only theme contains no geometry + +Not every request wants the UI re-skinned. "Change the wallpaper, leave my interface alone" is a normal ask, and it is a *different* theme shape: paint the root, clear the plates, stop there. + +Keep sizing and spacing out of the file entirely. A theme that also sets `width`, `max-width`, `gap`, `min-height`, `padding`, `border-radius`, `box-shadow`, `transform`, or `border` on app chrome will visibly restructure surfaces the user never asked you to touch. On 5.5.6 the home screen is where it shows first, because the hero is a centred title that the plate paints behind: + +- `.wb-home-page` — `width` / `max-width` / `gap` resize the whole column. +- `.wb-home-header` — `min-height` / `padding` / `overflow` grow the hero and clip its content. +- `.wb-home-header__title` — a `width` constraint re-wraps the centred title. +- `.teams-content-wrapper`, `.wb-scene-tabs`, `.quick-actions__item` — border radius, borders and shadows relocate and restyle chips that were already fine. + +The symptom is distinctive: the hero title gets **cut off at the top edge** and the scene tabs appear **detached from the card**, floating over the wallpaper. If you see that, you are not looking at a clearing bug — there is a geometry declaration in the theme. Delete it; the layout returns by itself. + +So the whole file reduces to two jobs, and it is worth keeping it that small: + +```css +/* 1. paint the wallpaper on the window root, with one veil per appearance */ +html.codedrobe-host-workbuddy, +html.codedrobe-host-workbuddy body, +html.codedrobe-host-workbuddy #root { + background-color: #fbfbfa !important; + background-image: var(--ink-veil), var(--codedrobe-image-wallpaper, none) !important; + background-repeat: no-repeat, no-repeat !important; + background-position: center center, center 20% !important; + background-size: 100% 100%, cover !important; + background-attachment: fixed, fixed !important; +} + +/* 2. clear the plates from the table above, and nothing else */ +html.codedrobe-host-workbuddy .teams-container, +html.codedrobe-host-workbuddy [class*="_gridViewItem_"], +html.codedrobe-host-workbuddy .conversation-shell, +html.codedrobe-host-workbuddy .wb-home-route { + background-color: transparent !important; + background-image: none !important; +} +``` + +Crop note: a 1236×764 window is wider than a 1186×856 reference image, so `cover` scales by width in both directions and there is no horizontal freedom — `background-position` can only move the image vertically. Anchor it to keep the focal point (`center 20%` held the face) and accept that the bottom is what gets cut. diff --git a/skills/codedrobe-theme/references/workbuddy.zh.md b/skills/codedrobe-theme/references/workbuddy.zh.md index 5cd020c..fbd86b1 100644 --- a/skills/codedrobe-theme/references/workbuddy.zh.md +++ b/skills/codedrobe-theme/references/workbuddy.zh.md @@ -38,23 +38,27 @@ WorkBuddy 目前只做渲染层主题,不需要 Codex 那套宿主外观设置 | --- | --- | | `.conversation-shell` | 实色白 | | `[class*="gridView"]`、`[class*="_grid_"]` | 实色白 —— 网格布局单元,CSS Module 生成的哈希类 | -| `main.wb-home-route` | 实色白 —— **仅首页路由有** | +| `.wb-home-route` | 实色白,972×734 —— **仅首页路由有** | | `#workbuddy-menubar-container` | `rgb(242, 242, 242)`,顶部 30px 的条 | | `.workbuddy-window-controls` | `--cb-panel-bg-primary` —— 最小化 / 最大化 / 关闭按钮下面的那条 | | `.cr-input-container`、`.cr-input-toolbar__right` | 实色白,在输入框内层 | -| `.collapsible-section-header`、`.conversation-section-label` | `rgb(242, 242, 242)` —— 侧栏分组标题 | +| `.collapsible-section-header`、`.conversation-section-label` | `rgb(242, 242, 242)` —— 侧栏分组标题(**注意:这一条清不掉**,见下) | | `[class*="cb-agent-card"]` | 白 / `rgb(230, 230, 230)` —— 侧栏会话卡片 | 梳理这张表时踩到两个坑: -- **`.wb-home-route` 只有首页有。** 会话页没有这层,所以一个主题可能「会话页正常、首页发白」。两条路由都要验证。 +- **`.wb-home-route` 只有首页有,而且它不是首页内容的祖先。** 它确实是 `
`,但在 5.5.6 上它是作为**兄弟层垫在下面的** —— 在首页界面之下、在你的背景之上。从 `document.elementFromPoint` 往上回溯永远到不了它,于是回溯链看起来干干净净、窗口却照样发白。只有全量枚举才能把它揪出来。这正是「会话页正常、首页发白」的准确机理。 - **不要用 `[class*="grid_"]`。** 它会误伤 `artifact-slot-panel__grid` 这类无关类名。 +选择器**不要带标签名** —— 写 `.wb-home-route`,不要写 `main.wb-home-route`。它碰巧是个 `
`,但要不要清掉这层,跟标签名能不能跨版本稳住是两回事。 + +`.collapsible-section-header` 是这张表里**唯一清不掉**的一条。应用方是用这条规则画它的:`.conversation-section-content [class^="collapsible-section"] > [class*="header"] { background: var(--wb-sidebar-bg, var(--cb-sidebar-bg, var(--vscode-sideBar-background, #fff))) !important }`。把自己的选择器提权越过去 —— 实测提到 `(0,4,1)` 加 `!important` —— 依然压不动;重新定义 `--cb-sidebar-bg` / `--wb-sidebar-bg` 同样无效。可见**优先级并不是唯一的决定因素**。保持原生,并在主题里写明这一点,而不是留一条静默失效的规则。 + 这张表是绑定版本的。应用升级后要重新推导,不要直接照信。 ## 路由与外观 -- 会话容器是 `.conversation-shell`,首页路由是 `main.wb-home-route`。`.chat-container` 已不存在。 +- 会话容器是 `.conversation-shell`,首页路由是 `.wb-home-route`(是个 `
`,但选择器里不要带标签名)。`.chat-container` 已不存在。 - 外观由 **`` 上的 `data-theme` 属性**驱动(`light` / `dark`),配套一整套语义 token(`--cb-text-primary`、`--cb-panel-bg-primary`、`--cb-bg-secondary`、`--sk-*`,合计数千个自定义属性)。只换 `light` / `cb-light` 这些 class 是没有任何效果的。 - 因此主题可以用 `html[data-theme="dark"] { … }` 跟随宿主外观 —— 它的特异性高于普通宿主选择器,所以**一个主题包就能自适应,而不是把某一种外观写死**。 @@ -71,6 +75,9 @@ WorkBuddy 目前只做渲染层主题,不需要 Codex 那套宿主外观设置 - 平均亮度描述不了壁纸有多**繁密**。一张很亮但细节细碎的插画,仍然需要一层薄白纱(约 0.40),因为文字背后的细密花纹读起来就是噪点。 - 既然关键在「配对」,那么算出来的这组值正好可以用来告诉用户:**他这张图想要哪种外观** —— 以及当他正在用的外观不匹配时给出提醒。 +- **不要让纱重到把图片自身的明暗关系反转掉。** 在双峰分布的壁纸上,这个坑会在深色外观下咬人。一条从左往右递增的纱,如果左端重到把图片的亮部按死(`.93`),那一侧会从 253 掉到 28;而图片的暗部在轻得多的 `.62` 之下落在 46。**亮部反而比暗部更暗**,而侧栏正好压在那片亮部上,于是塌成一条没有纹理的近乎纯黑带。用户会把这种现象读成渲染 bug,而不是壁纸。左端的取值要让亮部落在与窗口其余部分大致同档的亮度上:取 `.83` 时左端是 52,主内容区是 52–60,那条带就消失了。**这件事要测,不要靠眼睛估** —— 在截图上横着采一行像素,横跨侧栏与内容区,看两者之间的台阶。 + + 深色主题配浅色文字的粗略目标:整窗压在 110 亮度以下,且最亮与最暗区域相互差距控制在 10–15 以内,否则壁纸自身的结构就会被读成界面缺陷。 ## 诊断「apply 成功但界面没变化」 @@ -78,6 +85,9 @@ apply 通过只能证明样式到达了渲染进程。如果窗口看起来毫 1. 从 `document.elementFromPoint(x, y)` 逐级向上回溯,打印每一层的 `backgroundColor` —— 这样就能看出是哪一层盖住了图。 2. 枚举所有 `backgroundColor` 的 alpha 大于 0.85、且与视口相交的元素,按可见面积排序。**不要用面积阈值去过滤** —— 尺寸过滤会漏掉窗口按钮条这类小组件。 +3. **不要只信第 1 步。** 回溯法有个盲区:一块垫在内容之下、背景之上的实色**兄弟层**,它回溯不出来 —— 栈是干净的,窗口却照样发白。只要第 1 步查下来没问题但结果依然不对,就去跑第 2 步;`.wb-home-route` 就是这么被揪出来的。 + +修完之后用同样的方式确认:把清底清单上每个元素的实际 `backgroundColor` 读出来,确认它**真的**变成了 `rgba(0, 0, 0, 0)`。一条规则在源码里看着没问题,却可能输掉一场层叠博弈;只有计算值能证明它生效了。 ## 不要用脚本切换外观来验证颜色 @@ -91,3 +101,43 @@ apply 通过只能证明样式到达了渲染进程。如果窗口看起来毫 - **会话内的内容卡片**(`.cr-tool-exp__content`、`.cr-code-like-box` 等)、按钮与头像 —— 这些是内容与控件,不是窗口 chrome。 只清 chrome:侧栏、顶栏、菜单栏、窗口按钮条、输入框外壳。 + +## 「只换壁纸」的主题里没有几何属性 + +不是每个需求都想重做界面。「把壁纸换掉,别动我的界面」是个很正常的诉求,而它对应的是**另一种主题形态**:铺根节点、清底板、到此为止。 + +把尺寸和间距属性彻底挡在文件之外。一个主题如果在应用 chrome 上还写了 `width`、`max-width`、`gap`、`min-height`、`padding`、`border-radius`、`box-shadow`、`transform` 或 `border`,就会明显重构用户根本没要求你碰的表面。在 5.5.6 上,最先出问题的就是首页 —— 因为那块 hero 是一个**居中标题**,而底板就在它背后画底: + +- `.wb-home-page` —— `width` / `max-width` / `gap` 会把整列重新定尺。 +- `.wb-home-header` —— `min-height` / `padding` / `overflow` 会把 hero 撑大并裁掉它的内容。 +- `.wb-home-header__title` —— 给一个 `width` 约束就会让居中标题重新折行。 +- `.teams-content-wrapper`、`.wb-scene-tabs`、`.quick-actions__item` —— 圆角、边框和阴影会把本来好好的芯片挪位、改样。 + +症状很有辨识度:hero 标题**被上边缘裁掉**,场景标签**脱离卡片**飘在壁纸上。看到这个,就不是清底的问题 —— 是主题里有一条几何声明。删掉它,布局自己就回来了。 + +于是整个文件缩成两件事,而且值得就保持这么小: + +```css +/* 1. 在窗口根节点铺壁纸,每种外观一层纱 */ +html.codedrobe-host-workbuddy, +html.codedrobe-host-workbuddy body, +html.codedrobe-host-workbuddy #root { + background-color: #fbfbfa !important; + background-image: var(--ink-veil), var(--codedrobe-image-wallpaper, none) !important; + background-repeat: no-repeat, no-repeat !important; + background-position: center center, center 20% !important; + background-size: 100% 100%, cover !important; + background-attachment: fixed, fixed !important; +} + +/* 2. 只清上面那张表里的底板,别的一律不动 */ +html.codedrobe-host-workbuddy .teams-container, +html.codedrobe-host-workbuddy [class*="_gridViewItem_"], +html.codedrobe-host-workbuddy .conversation-shell, +html.codedrobe-host-workbuddy .wb-home-route { + background-color: transparent !important; + background-image: none !important; +} +``` + +裁切补充:1236×764 的窗口比 1186×856 的参考图更宽,所以 `cover` 两个方向都由宽度定尺,横向没有自由度 —— `background-position` 只能纵向移动画面。按焦点去锚定(`center 20%` 保住了脸部),并接受被裁掉的是底部。 From 7af8fa29ed9b0cc991095309ab16c93eb1d41314 Mon Sep 17 00:00:00 2001 From: Daizhdd <1249767897@qq.com> Date: Wed, 16 Sep 2026 19:47:57 +0800 Subject: [PATCH 4/5] =?UTF-8?q?workbuddy:=20correct=20the=20collapsible-se?= =?UTF-8?q?ction-header=20finding=20=E2=80=94=20it=20is=20clearable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous commit claimed `.collapsible-section-header` cannot be cleared from a theme. That was wrong, and it was wrong because of how it was measured. The app paints it from `.conversation-section-content [class^="collapsible-section"] > [class*="header"]` at (0,3,0) with !important, so the obvious (0,2,1) selector loses. Adding [data-theme] and a container class reaches (0,4,1) and clears all five headers. The real trap: injecting a style and reading getComputedStyle in the SAME JS evaluation returns the stale value. That looks exactly like "this plate cannot be overridden" and is how the working override got written off. Inject in one call, let a frame pass, read in the next. Also record that redefining --cb-sidebar-bg / --wb-sidebar-bg does not work (the app defines them at higher specificity), so overriding the conflicting property directly is the simpler route. Dark appearance makes the difference unmistakable: the native rgb(31,31,31) header against a veiled sidebar of ~72 is five flat black bars. Docs only. --- .../codedrobe-theme/references/workbuddy.md | 25 +++++++++++++++++-- .../references/workbuddy.zh.md | 25 +++++++++++++++++-- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/skills/codedrobe-theme/references/workbuddy.md b/skills/codedrobe-theme/references/workbuddy.md index 9628442..845babb 100644 --- a/skills/codedrobe-theme/references/workbuddy.md +++ b/skills/codedrobe-theme/references/workbuddy.md @@ -40,7 +40,7 @@ An apply can report complete success while the window looks untouched: the rende | `#workbuddy-menubar-container` | `rgb(242, 242, 242)`, the top 30 px strip | | `.workbuddy-window-controls` | `--cb-panel-bg-primary` — the strip behind the minimise / maximise / close buttons | | `.cr-input-container`, `.cr-input-toolbar__right` | solid white, inside the composer | -| `.collapsible-section-header`, `.conversation-section-label` | `rgb(242, 242, 242)` — sidebar group headers (**see the note below: not clearable**) | +| `.collapsible-section-header`, `.conversation-section-label` | `rgb(242, 242, 242)` — sidebar group headers (**needs a higher-specificity selector, see below**) | | `[class*="cb-agent-card"]` | white / `rgb(230, 230, 230)` — sidebar conversation cards | Two traps found while deriving this list: @@ -50,7 +50,28 @@ Two traps found while deriving this list: Write the selector without a tag name — `.wb-home-route`, not `main.wb-home-route`. The element happens to be a `
`, but the plate is worth clearing whether or not that stays true across releases. -`.collapsible-section-header` is the one plate on this list that **cannot be cleared from a theme**. The app paints it from `.conversation-section-content [class^="collapsible-section"] > [class*="header"] { background: var(--wb-sidebar-bg, var(--cb-sidebar-bg, var(--vscode-sideBar-background, #fff))) !important }`. Raising your own selector past that — a `(0,4,1)` `!important` was tried — still loses, and redefining `--cb-sidebar-bg` / `--wb-sidebar-bg` does not help either, so specificity alone is not the deciding factor. Leave it native and say so in the theme, rather than shipping a rule that silently does nothing. +`.collapsible-section-header` is the one plate on this list that needs a **higher-specificity selector**. The app paints it from + +```css +.conversation-section-content [class^="collapsible-section"] > [class*="header"] { + background: var(--wb-sidebar-bg, var(--cb-sidebar-bg, var(--vscode-sideBar-background, #fff))) !important; +} +``` + +That is `(0,3,0)` and important, so the obvious `html.codedrobe-host-workbuddy .collapsible-section-header` (`(0,2,1)`) loses and the five headers keep their native surface. Reach past it by adding the appearance attribute and a container class: + +```css +html.codedrobe-host-workbuddy[data-theme] .conversation-list .collapsible-section-header { + background-color: transparent !important; + background-image: none !important; +} +``` + +`(0,4,1)` clears all five. In the dark appearance the difference is not subtle: the native `rgb(31, 31, 31)` header against a veiled sidebar around 72 reads as five flat black bars, which looks like a rendering fault rather than a wallpaper. + +**The trap worth remembering is how this is measured, not how it is written.** Injecting a style and reading `getComputedStyle` in the *same* JS evaluation returns the stale value. That failure mode is indistinguishable from "this plate cannot be overridden", and it is how a `(0,4,1)` override got written off as ineffective here. Inject in one call, let a frame or two pass, then read in a second call. + +Also note that redefining `--cb-sidebar-bg` / `--wb-sidebar-bg` on `html.codedrobe-host-workbuddy` does *not* work: the app defines those variables at a higher specificity, so the variable you set is not the one it reads. Overriding the conflicting *property* directly is simpler than chasing its inputs. The list is version-bound. When the app updates, re-derive it rather than trusting the table. diff --git a/skills/codedrobe-theme/references/workbuddy.zh.md b/skills/codedrobe-theme/references/workbuddy.zh.md index fbd86b1..45791fd 100644 --- a/skills/codedrobe-theme/references/workbuddy.zh.md +++ b/skills/codedrobe-theme/references/workbuddy.zh.md @@ -42,7 +42,7 @@ WorkBuddy 目前只做渲染层主题,不需要 Codex 那套宿主外观设置 | `#workbuddy-menubar-container` | `rgb(242, 242, 242)`,顶部 30px 的条 | | `.workbuddy-window-controls` | `--cb-panel-bg-primary` —— 最小化 / 最大化 / 关闭按钮下面的那条 | | `.cr-input-container`、`.cr-input-toolbar__right` | 实色白,在输入框内层 | -| `.collapsible-section-header`、`.conversation-section-label` | `rgb(242, 242, 242)` —— 侧栏分组标题(**注意:这一条清不掉**,见下) | +| `.collapsible-section-header`、`.conversation-section-label` | `rgb(242, 242, 242)` —— 侧栏分组标题(**需要更高优先级的选择器,见下**) | | `[class*="cb-agent-card"]` | 白 / `rgb(230, 230, 230)` —— 侧栏会话卡片 | 梳理这张表时踩到两个坑: @@ -52,7 +52,28 @@ WorkBuddy 目前只做渲染层主题,不需要 Codex 那套宿主外观设置 选择器**不要带标签名** —— 写 `.wb-home-route`,不要写 `main.wb-home-route`。它碰巧是个 `
`,但要不要清掉这层,跟标签名能不能跨版本稳住是两回事。 -`.collapsible-section-header` 是这张表里**唯一清不掉**的一条。应用方是用这条规则画它的:`.conversation-section-content [class^="collapsible-section"] > [class*="header"] { background: var(--wb-sidebar-bg, var(--cb-sidebar-bg, var(--vscode-sideBar-background, #fff))) !important }`。把自己的选择器提权越过去 —— 实测提到 `(0,4,1)` 加 `!important` —— 依然压不动;重新定义 `--cb-sidebar-bg` / `--wb-sidebar-bg` 同样无效。可见**优先级并不是唯一的决定因素**。保持原生,并在主题里写明这一点,而不是留一条静默失效的规则。 +`.collapsible-section-header` 是这张表里唯一需要**更高优先级选择器**的一条。应用方是这样画它的: + +```css +.conversation-section-content [class^="collapsible-section"] > [class*="header"] { + background: var(--wb-sidebar-bg, var(--cb-sidebar-bg, var(--vscode-sideBar-background, #fff))) !important; +} +``` + +特异性 `(0,3,0)` 且带 `!important`,所以最直观的 `html.codedrobe-host-workbuddy .collapsible-section-header`(`(0,2,1)`)会输,那 5 条标题就保留原生底色。加上外观属性与一个容器类就能越过去: + +```css +html.codedrobe-host-workbuddy[data-theme] .conversation-list .collapsible-section-header { + background-color: transparent !important; + background-image: none !important; +} +``` + +`(0,4,1)` 即可清掉全部 5 条。深色外观下这个差别一点不含糊:原生 `rgb(31, 31, 31)` 的标题条压在蒙过纱的侧栏(约 72)上,就是 5 条平黑带,看起来像渲染故障,不像壁纸。 + +**真正值得记住的坑在「怎么测」,而不是「怎么写」。** 在**同一次 JS 求值里**「注入样式 + 读 `getComputedStyle`」会读到旧值。这个失效模式和「这条根本覆盖不了」长得一模一样 —— 这里那条 `(0,4,1)` 覆盖就是这么被误判为无效的。要分两次调用:先注入,隔一两帧,再读。 + +另外,在 `html.codedrobe-host-workbuddy` 上重定义 `--cb-sidebar-bg` / `--wb-sidebar-bg` **不起作用**:应用是在更高的优先级上定义这两个变量的,你设的那个不是它读的那个。直接覆盖起冲突的**属性**,比追着它的输入变量跑要简单。 这张表是绑定版本的。应用升级后要重新推导,不要直接照信。 From a435df82bb1d32b1d1aa4adb0c35cefd8dbf025b Mon Sep 17 00:00:00 2001 From: Daizhdd <1249767897@qq.com> Date: Sat, 19 Sep 2026 21:43:32 +0800 Subject: [PATCH 5/5] workbuddy: record the 5.6.0 backplate changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The content plate was renamed and a second one appeared, so a theme that clears 5.5.6 correctly paints nothing on 5.6.0: * `_gridViewItem_` is now `_gridView_7xbcw_9` * `.teams-grid-scroll-content` is new, also 1256x746 of solid white Neither is reachable by the ancestor walk, so the window just goes white and looks identical to "the theme never applied". The lesson is to match the stable prefix (`[class*="gridView"]`) instead of a full name, and specifically not to narrow a documented prefix for the sake of precision — the narrowed form is what caused this here. Note that `_gridView_` does not match `_gridViewItem_` nor the reverse, because the trailing underscore is part of the substring, so both spellings are needed to span both releases. Add two pre-checks to the diagnosis section, because both cost real time before the plate was found: * whether this launch injected anything at all — a bare relaunch after an update carries no debug port, so nothing was ever applied * whether the image and stylesheet are fine — read the wallpaper property, fetch its blob, decode it with Image(); if all three pass, the only remaining explanation is occlusion, which skips a detour into CSP and object-URL-lifetime theories that were all wrong Also record the home composer plate (`.cr-input-box__main`): it paints a gradient on `background-image` while `background-color` reads transparent, so checking only the colour channel declares it clear when it is not. Docs only. --- .../codedrobe-theme/references/workbuddy.md | 20 ++++++++++++++----- .../references/workbuddy.zh.md | 20 ++++++++++++++----- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/skills/codedrobe-theme/references/workbuddy.md b/skills/codedrobe-theme/references/workbuddy.md index 845babb..8fe5400 100644 --- a/skills/codedrobe-theme/references/workbuddy.md +++ b/skills/codedrobe-theme/references/workbuddy.md @@ -30,23 +30,28 @@ Capture separate home and conversation snapshots before adapting `assets/theme-s ## Opaque backplates that hide the wallpaper -An apply can report complete success while the window looks untouched: the renderer paints its own solid surfaces on top of the injected background. On **5.5.6** the wallpaper reaches the screen only after these are cleared. +An apply can report complete success while the window looks untouched: the renderer paints its own solid surfaces on top of the injected background. On **5.5.6 and 5.6.0** the wallpaper reaches the screen only after these are cleared. | Element | What it painted | | ------------------------------------------------------------ | ---------------------------------------------------------------------------------- | | `.conversation-shell` | solid white | | `[class*="gridView"]`, `[class*="_grid_"]` | solid white — CSS-Module hash classes for the grid layout cells | +| `.teams-grid-scroll-content` | solid white, 1256×746 — **an extra layer introduced in 5.6.0**, absent on 5.5.6 | | `.wb-home-route` | solid white, 972×734 — **home route only** | | `#workbuddy-menubar-container` | `rgb(242, 242, 242)`, the top 30 px strip | | `.workbuddy-window-controls` | `--cb-panel-bg-primary` — the strip behind the minimise / maximise / close buttons | -| `.cr-input-container`, `.cr-input-toolbar__right` | solid white, inside the composer | +| `.cr-input-container`, `.cr-input-toolbar__right` | solid white, inside the composer (conversation route) | +| `.cr-input-box__main` | `linear-gradient(rgb(235,235,235), rgb(245,245,245))` — the **home** composer plate; it paints on `background-image`, so `background-color` reads transparent | | `.collapsible-section-header`, `.conversation-section-label` | `rgb(242, 242, 242)` — sidebar group headers (**needs a higher-specificity selector, see below**) | | `[class*="cb-agent-card"]` | white / `rgb(230, 230, 230)` — sidebar conversation cards | -Two traps found while deriving this list: +Three traps found while deriving this list: - **`.wb-home-route` is home-only, and it is not an ancestor of the home content.** It really is `
`, but on 5.5.6 it is painted as a *sibling underlay* — below the home UI, above your background. Walking up from `document.elementFromPoint` never reaches it, so the ancestor walk returns a clean stack while the window stays washed out. Only full enumeration finds it. This is the exact mechanism behind "looks correct in a conversation, white on home". - **Do not use `[class*="grid_"]`.** It also matches unrelated class names such as `artifact-slot-panel__grid`. +- **CSS-Module hash classes change between builds. Never match them by full name, and never narrow a documented prefix "for precision".** On 5.5.6 the content plate was `_gridViewItem_`; on 5.6.0 it is `_gridView_7xbcw_9`. Written as `[class*="_gridViewItem_"]` — which is exactly what a narrowed version of this note once recommended — nothing matches after the update and two 1256×746 white plates cover the window again, with symptoms indistinguishable from "the theme never applied". Match the stable prefix, `[class*="gridView"]`. + - Substring matching has no word boundaries: `_gridView_` does **not** match `_gridViewItem_`, nor the reverse. Write both if you have to cover both releases. + - This one was self-inflicted: rewriting this note's `[class*="gridView"]` as `[class*="_gridViewItem_"]` looked more rigorous and only shrank the selector's coverage down to a single release. Write the selector without a tag name — `.wb-home-route`, not `main.wb-home-route`. The element happens to be a `
`, but the plate is worth clearing whether or not that stays true across releases. @@ -100,7 +105,12 @@ clamp to ≤ 0.82, and emit one value per appearance. Two notes from practice: ## Diagnosing "apply succeeded but nothing changed" -A passing apply only proves the style reached the renderer. If the window looks untouched, an ancestor is painting an opaque background. Rather than guessing: +A passing apply only proves the style reached the renderer. If the window looks untouched, rule out two more fundamental causes first — it takes about thirty seconds: + +- **Did this launch even inject anything?** Theming is runtime injection. After an app update, or after the app relaunches itself, the new process is typically started **bare** (no `--remote-debugging-port` on the command line), so no injection ever happens and the UI is back to its native skin — which reads exactly like "the theme broke". Checking the process command line is faster than inspecting the theme: `Get-CimInstance Win32_Process -Filter "Name='WorkBuddy.exe'"` on Windows (`ps -ax -o command` on macOS). No debug port means do not touch the CSS — relaunch once with the port first. +- **Are the image and the CSS actually fine?** Read the wallpaper custom property, `fetch()` its `blob:` URL to confirm the byte count, and decode it with `new Image()` to confirm the dimensions. If all three pass, the asset and the stylesheet are good and the only remaining explanation is occlusion — go straight on. These three steps save a detour into CSP and object-URL-lifetime theories; every one of those was suspected here and every one was wrong. + +If both check out, an ancestor really is painting an opaque background. Rather than guessing: 1. Walk up from `document.elementFromPoint(x, y)`, printing `backgroundColor` for each ancestor — this shows which layer covers the image. 2. Enumerate every element whose `backgroundColor` alpha exceeds 0.85 and that intersects the viewport, sorted by visible area. **Do not filter by area threshold** — a size filter misses small chrome such as the window-control strip. @@ -151,7 +161,7 @@ html.codedrobe-host-workbuddy #root { /* 2. clear the plates from the table above, and nothing else */ html.codedrobe-host-workbuddy .teams-container, -html.codedrobe-host-workbuddy [class*="_gridViewItem_"], +html.codedrobe-host-workbuddy [class*="gridView"], html.codedrobe-host-workbuddy .conversation-shell, html.codedrobe-host-workbuddy .wb-home-route { background-color: transparent !important; diff --git a/skills/codedrobe-theme/references/workbuddy.zh.md b/skills/codedrobe-theme/references/workbuddy.zh.md index 45791fd..9b77468 100644 --- a/skills/codedrobe-theme/references/workbuddy.zh.md +++ b/skills/codedrobe-theme/references/workbuddy.zh.md @@ -32,23 +32,28 @@ WorkBuddy 目前只做渲染层主题,不需要 Codex 那套宿主外观设置 ## 会盖住壁纸的不透明底板 -一次 apply 可以完整报告成功,而窗口看起来毫无变化:渲染进程在注入的背景之上又画了自己的实色表面。在 **5.5.6** 上,只有清掉下面这些,壁纸才能真正显示出来。 +一次 apply 可以完整报告成功,而窗口看起来毫无变化:渲染进程在注入的背景之上又画了自己的实色表面。在 **5.5.6 与 5.6.0** 上,只有清掉下面这些,壁纸才能真正显示出来。 | 元素 | 它原来的颜色 | | --- | --- | | `.conversation-shell` | 实色白 | | `[class*="gridView"]`、`[class*="_grid_"]` | 实色白 —— 网格布局单元,CSS Module 生成的哈希类 | +| `.teams-grid-scroll-content` | 实色白,1256×746 —— **5.6.0 新增的一层**,5.5.6 上没有 | | `.wb-home-route` | 实色白,972×734 —— **仅首页路由有** | | `#workbuddy-menubar-container` | `rgb(242, 242, 242)`,顶部 30px 的条 | | `.workbuddy-window-controls` | `--cb-panel-bg-primary` —— 最小化 / 最大化 / 关闭按钮下面的那条 | -| `.cr-input-container`、`.cr-input-toolbar__right` | 实色白,在输入框内层 | +| `.cr-input-container`、`.cr-input-toolbar__right` | 实色白,在输入框内层(会话页) | +| `.cr-input-box__main` | `linear-gradient(rgb(235,235,235), rgb(245,245,245))` —— **首页**输入框的底板,注意它画在 `background-image` 上,`background-color` 读出来是透明的 | | `.collapsible-section-header`、`.conversation-section-label` | `rgb(242, 242, 242)` —— 侧栏分组标题(**需要更高优先级的选择器,见下**) | | `[class*="cb-agent-card"]` | 白 / `rgb(230, 230, 230)` —— 侧栏会话卡片 | -梳理这张表时踩到两个坑: +梳理这张表时踩到三个坑: - **`.wb-home-route` 只有首页有,而且它不是首页内容的祖先。** 它确实是 `
`,但在 5.5.6 上它是作为**兄弟层垫在下面的** —— 在首页界面之下、在你的背景之上。从 `document.elementFromPoint` 往上回溯永远到不了它,于是回溯链看起来干干净净、窗口却照样发白。只有全量枚举才能把它揪出来。这正是「会话页正常、首页发白」的准确机理。 - **不要用 `[class*="grid_"]`。** 它会误伤 `artifact-slot-panel__grid` 这类无关类名。 +- **CSS Module 的哈希类名随构建变化,永远不要按全名匹配,也不要为了「更精确」而收窄成前缀更长的写法。** 5.5.6 上那块内容区白板是 `_gridViewItem_`,到 5.6.0 变成了 `_gridView_7xbcw_9`。如果当初写的是 `[class*="_gridViewItem_"]`,升级后一条都不命中,两块 1256×746 的纯白重新盖住整窗 —— 症状和「主题没生效」一模一样。按 `[class*="gridView"]` 这种稳定前缀匹配才跨版本。 + - 子串匹配没有"单词边界":`_gridView_`(尾部带下划线)**匹配不到** `_gridViewItem_`,反之亦然。要同时兼容两个版本就两条都写。 + - 顺带一提,这条坑最早是**人为制造**的:把这份笔记里的 `[class*="gridView"]` 改写成 `[class*="_gridViewItem_"]` 看起来更严谨,实际是把选择器的覆盖面缩到了某一个版本。 选择器**不要带标签名** —— 写 `.wb-home-route`,不要写 `main.wb-home-route`。它碰巧是个 `
`,但要不要清掉这层,跟标签名能不能跨版本稳住是两回事。 @@ -102,7 +107,12 @@ html.codedrobe-host-workbuddy[data-theme] .conversation-list .collapsible-sectio ## 诊断「apply 成功但界面没变化」 -apply 通过只能证明样式到达了渲染进程。如果窗口看起来毫无变化,那一定是有祖先元素在画不透明背景。不要猜: +apply 通过只能证明样式到达了渲染进程。如果窗口看起来毫无变化,先花 30 秒排除两种更根本的可能,再去抓遮挡: + +- **这一次启动到底注入了没有?** 主题是运行时注入的。应用升级、或它自己重启之后,新进程往往是**裸启动**的(命令行里没有 `--remote-debugging-port`),注入根本无从发生 —— 界面会完全回到原生皮肤,看起来就像「主题失效了」。这时看进程命令行比看主题快:`Get-CimInstance Win32_Process -Filter "Name='WorkBuddy.exe'"`(macOS 用 `ps -ax -o command`)。没有调试端口就别去改 CSS,先带端口重启一次。 +- **图和 CSS 是不是好的?** 读壁纸自定义属性 → 对它的 `blob:` URL 发一次 `fetch` 确认字节数 → 用 `new Image()` 解码确认尺寸。三项全过就说明素材和样式都没问题,剩下的只能是遮挡,直接往下走。这三步能省掉在 CSP 和 object URL 生命周期上瞎猜的弯路 —— 那几条我都怀疑过,全是错的。 + +如果上面都正常,那就是有祖先元素在画不透明背景。不要猜: 1. 从 `document.elementFromPoint(x, y)` 逐级向上回溯,打印每一层的 `backgroundColor` —— 这样就能看出是哪一层盖住了图。 2. 枚举所有 `backgroundColor` 的 alpha 大于 0.85、且与视口相交的元素,按可见面积排序。**不要用面积阈值去过滤** —— 尺寸过滤会漏掉窗口按钮条这类小组件。 @@ -153,7 +163,7 @@ html.codedrobe-host-workbuddy #root { /* 2. 只清上面那张表里的底板,别的一律不动 */ html.codedrobe-host-workbuddy .teams-container, -html.codedrobe-host-workbuddy [class*="_gridViewItem_"], +html.codedrobe-host-workbuddy [class*="gridView"], html.codedrobe-host-workbuddy .conversation-shell, html.codedrobe-host-workbuddy .wb-home-route { background-color: transparent !important;