Files
cc-web/.codex/skills/create-cc-web-theme/references/cc-web-theme-architecture.md
2026-07-18 10:14:38 +08:00

159 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# cc-web 主题架构与修改边界
## 目录
1. 代码定位顺序
2. 主题运行链路
3. CSS 分层
4. DOM 双路径
5. 资产与回归
6. 脏工作树与服务约束
## 1. 代码定位顺序
不要依赖固定行号。按符号和稳定文本定位:
1. `public/app.js`
- `THEME_OPTIONS`
- `normalizeTheme`
- `applyTheme`
- `buildThemePickerHtml` / `mountThemePicker`
- `buildWelcomeMarkup`
2. `public/index.html`
- CSS 加载前的主题 bootstrap
- 静态 welcome DOM
- CSS/JS cache-busting query
3. `public/style.css`
- `html[data-theme='<id>']` 语义变量
- 共享暗色 `:is(...)` completion selectors
- 文件后部的主题专属组件层
- 响应式与 `prefers-reduced-motion`
4. `scripts/regression.js`
- `assertFrontend<Theme>ThemeContract`
- `--target <theme>-theme`
- 全量回归入口
5. `public/assets/themes/<id>/`
- background、frames、icons、textures、manifest
先用 codebase-memory 找符号和调用关系,再用 `rg` 核对资源文本与最终位置。
## 2. 主题运行链路
```text
THEME_OPTIONS
├── 设置页主题候选 / label / desc / swatches
├── normalizeTheme() 判断持久化值是否合法
└── applyTheme()
├── document.documentElement.dataset.theme
└── localStorage['cc-web-theme']
index.html bootstrap
└── CSS 加载前写入 data-theme避免首屏闪烁
html[data-theme='<id>']
└── 语义变量 → 共享组件 → 主题专属组件层
```
主题列表只维护一份。不要在设置页或其他弹层硬编码第二份主题候选。
### 新主题 ID
- 使用稳定、小写、可长期保留的 ID。
- 新主题默认新建 ID不要借用隐藏主题、历史主题或另一个风格的 ID。
- 保留旧主题用于对比时,不修改其 label、资产和 selector。
- 如需迁移旧 ID明确写出 `旧值 → 新值`,并增加回归断言。
## 3. CSS 分层
按以下层次组织:
1. **语义变量层**:背景、文字、边线、强调色、面板色。
2. **共享 completion 层**:只放多个暗色主题确实共用的组件补齐。
3. **基础 UI 层**:不因单个主题改变业务布局或交互。
4. **主题专属层**背景、边框、图标、welcome、特殊响应式。
专属层应放在共享规则之后,并限定 `html[data-theme='<id>']`。当后置规则仍无效时,检查 specificity而不是继续追加更宽泛的选择器。
### `:is()` 风险
`:is()` 的 specificity 取参数中最高值。共享规则例如:
```css
:is(
html[data-theme='a'] .msg.assistant .msg-bubble,
html[data-theme='b'] .msg.system .msg-bubble[data-tone='info']
) { ... }
```
可能比后面的普通主题规则更强。出现“backdrop-filter 变了但 background 没变”时,必须查看 computed style 的规则来源;必要时使用同级 specificity 或只对冲突声明使用精确 `!important`
## 4. DOM 双路径
welcome 页面同时存在:
- `public/index.html` 的静态首屏结构。
- `public/app.js``buildWelcomeMarkup()` 动态结构。
新增图层、class、无障碍属性、文案节点或图片时必须同步两处。
动态数据必须由 JS 统一填充,例如:
- 当前项目名称来自 `cwd`
- 当前 Agent 名称来自运行时状态。
- 当前会话标题来自 snapshot。
静态 HTML 只保留可定位的空节点或不依赖运行时的数据。回归必须断言静态模板没有写死动态名称。
### 重复视觉来源
实现主题图标前检查实际 DOM
- 文本 `+``▾``…`
- 内联 SVG。
- `<img>` 头像。
- 基础主题已有的 `::before` / `::after`
- 新主题 background/mask。
同一语义只保留一个可见来源,并只在当前主题下隐藏旧来源。
## 5. 资产与回归
推荐目录:
```text
public/assets/themes/<theme-id>/
├── background.webp
├── frames/
│ ├── manifest.json
│ └── *.png
├── icons/
│ ├── manifest.json
│ └── *.png
└── textures/
└── *.webp
```
专项回归至少覆盖:
- 主题注册、可见性和迁移策略。
- 变量块和专属组件层存在。
- 新主题加入必要共享 selectors。
- 静态/动态 welcome 同步。
- 本地资产格式、尺寸、hash 或 manifest。
- 禁止远程 URL。
- 动态组件的结构契约,例如可伸缩输入框不依赖固定伪元素。
- 响应式、reduced-motion、文字对比度。
- cache bust 与在线加载版本一致。
- 旧主题专项回归继续通过。
回归验证结构和不变量,不替代像素与构图验收。
## 6. 脏工作树与服务约束
- 实施前执行 `git status --short` 和主题相关精确 diff。
- 记录相关文件的起始状态;只修改目标区块。
- 不使用 `git reset --hard``git checkout --` 或整文件还原保护自己生成的改动。
- 多会话可能同时修改 `app.js``style.css``index.html``regression.js`。发现反复回写时停止覆盖,先协调写入边界。
- 修改静态文件通常不需要重启服务。需要重启 cc-web 时,严格执行仓库 `AGENTS.md` 的运行会话检查。
- 浏览器访问失败时先用 `curl http://127.0.0.1:<port>` 检查本地服务,再按 `hostname -I` 使用 `11.144.144.*` 地址排除网络命名空间问题。