chore: rebuild release package
This commit is contained in:
139
.codex/skills/create-cc-web-theme/SKILL.md
Normal file
139
.codex/skills/create-cc-web-theme/SKILL.md
Normal file
@@ -0,0 +1,139 @@
|
||||
---
|
||||
name: create-cc-web-theme
|
||||
description: 为 cc-web 创建、复刻、重做或审计视觉主题,从参考图、概念图、背景图、图标板或素材板完成需求澄清、源素材归档、主题隔离、可复现切图、CSS/DOM 接入、响应式、回归和真实浏览器视觉验收。用户提到新建主题、换肤、复刻设计稿、主题高保真、主题对比、切图、图标重做、欢迎卡、输入框装饰框、消息气泡磨砂、视觉错位或主题返工时使用。
|
||||
---
|
||||
|
||||
# 创建 cc-web 主题
|
||||
|
||||
把参考设计转成一个独立、可切换、可维护并经过真实浏览器验收的 cc-web 主题。保留设计证据和生成链路,避免只留下无法继续扩展的最终切片。
|
||||
|
||||
## 按需读取参考
|
||||
|
||||
- 开始定位主题系统前,读取 [cc-web-theme-architecture.md](references/cc-web-theme-architecture.md)。
|
||||
- 收到背景、图标板、边框板或概念图时,读取 [asset-workflow.md](references/asset-workflow.md)。
|
||||
- 遇到“不像设计图”“改了没变化”“边框/图标/透明度/居中反复不对”时,读取 [lessons-learned.md](references/lessons-learned.md)。
|
||||
- 准备声明完成前,完整读取并执行 [acceptance-checklist.md](references/acceptance-checklist.md)。
|
||||
|
||||
## 遵守硬约束
|
||||
|
||||
1. 为新主题创建新的稳定主题 ID 和独立资产目录。除非用户明确要求,禁止覆盖、重命名或删除现有主题。
|
||||
2. 修改前检查工作树与相关文件差异。保留用户和其他任务的未提交改动,不格式化或重排无关大文件。
|
||||
3. 先归档所有源概念图、素材板和背景,再生成派生资产。保留裁剪脚本、坐标、manifest 和来源哈希。
|
||||
4. 把参考图当作构图与层级契约,不只提取颜色和“氛围”。先量化,再编码。
|
||||
5. 只使用本地主题资产。禁止让产品运行时依赖参考站点、临时附件 URL 或远程图片。
|
||||
6. 同步维护静态首屏 DOM 与动态渲染 DOM。动态项目名、Agent、会话标题等内容禁止写死在静态模板中。
|
||||
7. 只修改用户指出的层级。用户说“气泡背景”时,不得顺手重做所有卡片、工具层或布局。
|
||||
8. 自动化通过不等于视觉完成。没有真实浏览器对照、动态状态检查和多视口验收时,不得声明完成。
|
||||
9. 不删除源图、概念图、素材板、切片或提取脚本;后续功能可能需要重新切片。
|
||||
10. 需要重启 cc-web 时,先按仓库 `AGENTS.md` 检查其他运行中会话;不满足条件时不重启。
|
||||
|
||||
## 执行工作流
|
||||
|
||||
### 1. 固定需求和完成标准
|
||||
|
||||
明确并记录:
|
||||
|
||||
- 新建、复刻、扩展还是修复主题。
|
||||
- 主题稳定 ID、显示名、是否与旧主题并存、默认主题是否变化。
|
||||
- 参考图、背景图、图标板、边框板、字体和其他输入素材的角色。
|
||||
- 用户要求保留的既有视觉与明确禁止改动的区域。
|
||||
- 参考图原始视口、桌面目标视口和移动端目标视口。
|
||||
- 必须覆盖的动态状态:空会话、长消息、多行输入、工具调用、展开菜单、运行/停止、弹层和窄屏。
|
||||
|
||||
在任务资料中建立资产表和验收清单。输入素材含义不明确且会影响构图或切片时,先向用户确认。
|
||||
|
||||
### 2. 建立代码与改动基线
|
||||
|
||||
优先使用 `codebase-memory-mcp`:
|
||||
|
||||
1. 调用 `list_projects` 和 `index_status(project="home-cc-web")`。
|
||||
2. 使用 `search_graph` / `search_code` 定位主题注册、应用、静态 bootstrap、动态 welcome 和回归入口。
|
||||
3. 需要调用关系时使用 `trace_path`,需要源码时先取得 `qualified_name` 再调用 `get_code_snippet`。
|
||||
4. 最后使用 `rg` 和 `git diff` 校验文本、行号与未索引资源。
|
||||
|
||||
记录主题相关脏文件、既有主题 ID、缓存版本、共享选择器和任务开始时的资产清单。只在明确边界内修改。
|
||||
|
||||
### 3. 把参考图拆成可验证规格
|
||||
|
||||
先输出“参考区域 → 实际 DOM → 资产 → CSS 责任”的映射,再实施。
|
||||
|
||||
至少量化:
|
||||
|
||||
- 侧栏、顶栏、消息区、输入区的比例和基线。
|
||||
- 主视觉安全区、文字阅读区和背景裁切/遮罩策略。
|
||||
- 面板层级、透明度感知、边线宽度、阴影和切角使用范围。
|
||||
- 每类控件的容器尺寸、图标视觉主体、间距和光学中心。
|
||||
- 固定尺寸与动态高度组件的区别。
|
||||
- 静态空页面和有内容页面的布局差异。
|
||||
|
||||
先处理背景与大布局,再处理容器层级、边框、图标和微交互。禁止从局部颜色微调开始掩盖结构偏差。
|
||||
|
||||
### 4. 建立可复现资产链路
|
||||
|
||||
把源素材复制到当前主题任务的 `references/source-assets/`,不要只引用会话附件路径。为每个派生资产保存:
|
||||
|
||||
- 源文件名和哈希。
|
||||
- 源裁剪框、规格或素材板单元格。
|
||||
- 输出尺寸、格式和用途。
|
||||
- alpha/颜色分离方法和必要的光学校正。
|
||||
- 生成脚本与 manifest。
|
||||
|
||||
按用途选择实现:
|
||||
|
||||
- 背景保留构图和清晰度,遮罩只服务可读性。
|
||||
- 主交互小图标优先使用干净 mask 或对应尺寸切片;多色状态、头像和装饰图标保留原色。
|
||||
- 非对称图标按 alpha 加权重心校正,不按透明画布机械居中。
|
||||
- 固定尺寸框可使用完整切片;动态高度框优先使用 `border-image`/九宫格或拆分稳定边角,禁止把固定比例整图放在伪元素上随内容拉伸。
|
||||
|
||||
具体方法见 [asset-workflow.md](references/asset-workflow.md)。
|
||||
|
||||
### 5. 分层、隔离地接入主题
|
||||
|
||||
按以下顺序实现:
|
||||
|
||||
1. 在 `THEME_OPTIONS` 新增主题元数据,保持单一数据源。
|
||||
2. 检查首屏 bootstrap、`normalizeTheme()`、`applyTheme()` 和本地持久化是否接受新 ID。
|
||||
3. 在 `html[data-theme='<id>']` 变量块中先定义语义 token。
|
||||
4. 把新暗色主题加入确实需要复用的共享 completion selector。
|
||||
5. 把高风险视觉放在文件后部的主题专属组件层,所有选择器都限定主题 ID。
|
||||
6. 把资产放入 `public/assets/themes/<id>/`,避免根目录同名覆盖。
|
||||
7. 同步静态 `index.html` 和动态构建函数中的 welcome/装饰 DOM。
|
||||
8. 检查真实 DOM 内原生文字、SVG、图片和主题伪元素,防止加号、头像、图标或边框重复。
|
||||
9. 更新 CSS/JS cache bust,并同步回归契约。
|
||||
|
||||
不要为了视觉方便复制第二套业务逻辑、主题列表或交互组件。
|
||||
|
||||
### 6. 用真实浏览器形成短反馈环
|
||||
|
||||
先按参考图原始尺寸验收,再检查常规桌面和窄屏。每轮只解决一个明确层级,并记录修改前后证据。
|
||||
|
||||
遇到异常时按顺序排查:
|
||||
|
||||
1. 浏览器是否实际加载了最新缓存版本和资源。
|
||||
2. 选择器是否命中真实 DOM,伪元素或原生子节点是否重复。
|
||||
3. computed style 的最终来源和 specificity,特别检查 `:is()` 与旧 `!important`。
|
||||
4. 外层看似透明时,内层工具块、标题层或伪元素是否仍不透明。
|
||||
5. 动态高度、文字换行、菜单展开和运行状态是否改变真实尺寸。
|
||||
6. 几何中心、文字基线和图标 alpha 重心是否一致。
|
||||
|
||||
优先测量,不盲调数值。把“看着偏”转换为中心差、边距、主体 bbox、computed background 或溢出量。
|
||||
|
||||
### 7. 完成工程与视觉验收
|
||||
|
||||
执行 [acceptance-checklist.md](references/acceptance-checklist.md) 的全部强制项,至少包含:
|
||||
|
||||
- JS 语法检查、主题专项回归、相关旧主题回归、全量回归和 `git diff --check`。
|
||||
- 本地资产存在性、格式、尺寸、hash/manifest 与 HTTP 200。
|
||||
- 参考视口、常规桌面和窄屏的真实浏览器检查。
|
||||
- 空页面、长内容、多行输入、菜单、工具块、按钮状态和动态文案检查。
|
||||
- 与参考图逐组件对照,确认没有多余边框、重复图标、视觉实心层或明显错位。
|
||||
|
||||
最后报告实际视觉证据、验证命令和保留的源资产/脚本路径。测试失败、浏览器不可用或视觉证据不足时明确说明,保持任务未完成状态。
|
||||
|
||||
## 交付要求
|
||||
|
||||
- 列出新增主题 ID、资产目录、源资产归档和提取脚本。
|
||||
- 列出修改过的主题链路文件与隔离边界。
|
||||
- 给出真实浏览器实测结果,不只写“回归通过”。
|
||||
- 说明仍未覆盖的视口、状态或素材限制。
|
||||
- 保留所有主题概念图、素材板、切片、manifest 和生成脚本。
|
||||
4
.codex/skills/create-cc-web-theme/agents/openai.yaml
Normal file
4
.codex/skills/create-cc-web-theme/agents/openai.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
interface:
|
||||
display_name: "创建 cc-web 主题"
|
||||
short_description: "从参考设计图到本地切片、主题隔离实现与真实浏览器视觉验收"
|
||||
default_prompt: "使用 $create-cc-web-theme 根据参考图创建一个独立、可切换并经过真实浏览器验收的 cc-web 主题。"
|
||||
@@ -0,0 +1,127 @@
|
||||
# cc-web 主题完成验收清单
|
||||
|
||||
把本清单作为完成门禁。任一强制项未验证时,保持任务未完成并说明原因。
|
||||
|
||||
## 1. 范围与隔离
|
||||
|
||||
- [ ] 新主题使用独立稳定 ID,未覆盖现有主题。
|
||||
- [ ] `THEME_OPTIONS`、bootstrap、持久化和 picker 的语义一致。
|
||||
- [ ] 现有主题仍可选择/迁移,并通过其专项回归。
|
||||
- [ ] 所有专属 selector 都限定新主题 ID。
|
||||
- [ ] 未修改主题无关业务逻辑、交互或大文件格式。
|
||||
- [ ] 已复核相关脏文件,没有覆盖用户或并行任务改动。
|
||||
|
||||
## 2. 源素材与派生资产
|
||||
|
||||
- [ ] 概念图、完整参考、背景和素材板已归档到任务目录。
|
||||
- [ ] 归档文件与原始输入 hash 已核对。
|
||||
- [ ] 生成脚本和 manifest 已保留且可重放。
|
||||
- [ ] 派生资产记录源文件、裁剪框、规格、尺寸和用途。
|
||||
- [ ] 透明 PNG 无棋盘格、黑边或被裁掉的尖角。
|
||||
- [ ] 图标 alpha 主体尺寸和光学中心符合控件层级。
|
||||
- [ ] 所有运行时资产位于 `public/assets/themes/<id>/`。
|
||||
- [ ] 主题实现与 manifest 不包含远程图片 URL。
|
||||
|
||||
## 3. DOM 与组件实现
|
||||
|
||||
- [ ] 静态 `index.html` 与动态 welcome 构建函数结构同步。
|
||||
- [ ] 项目名、Agent、会话标题等动态内容没有写死。
|
||||
- [ ] 新主题图标未与原生文字、SVG、图片或旧伪元素重叠。
|
||||
- [ ] 新会话加号、下拉、操作菜单和设置入口仍可见、可点击。
|
||||
- [ ] 菜单展开不被父级 overflow 裁切。
|
||||
- [ ] 固定框与动态尺寸框使用了合适的切片策略。
|
||||
- [ ] 输入框单行、多行、聚焦、拖拽和特殊模式都没有双边框或错位。
|
||||
- [ ] 工具块、协作卡、弹层和消息嵌套层没有意外不透明底色。
|
||||
- [ ] `prefers-reduced-motion` 能关闭主题动画/过渡。
|
||||
|
||||
## 4. 视觉对照
|
||||
|
||||
### 参考视口
|
||||
|
||||
- [ ] 在参考图原始尺寸或同等宽高比下截图/检查。
|
||||
- [ ] 背景主体、人物、纹理和安全区与参考构图一致。
|
||||
- [ ] 侧栏、顶栏、消息区和输入区比例无明显偏差。
|
||||
- [ ] 面板层级清楚,没有全页面卡片化或遮罩过暗。
|
||||
- [ ] 边框轻重、切角范围和阴影符合参考层级。
|
||||
- [ ] 主文字可读,用户指定的颜色与对比度已满足。
|
||||
- [ ] 没有重复图标、莫名边框、虚线、色块或“一坨”叠层。
|
||||
|
||||
### 几何证据
|
||||
|
||||
- [ ] 主卡片中心与实际聊天画布中心误差可接受。
|
||||
- [ ] 图标以 alpha 主体/光学重心居中,不只看画布。
|
||||
- [ ] 文字与图标基线一致。
|
||||
- [ ] 欢迎卡、输入框和菜单没有横向溢出或裁切。
|
||||
- [ ] 记录关键 bbox、中心差、间距或 computed style。
|
||||
|
||||
### 透明与磨砂
|
||||
|
||||
- [ ] 背景纹理在设计要求透明的层中实际可见。
|
||||
- [ ] 外层气泡与内层工具块分别检查背景。
|
||||
- [ ] blur 没有把背景细节抹成实心色块。
|
||||
- [ ] computed style 的最终 background/backdrop-filter 来自预期 selector。
|
||||
|
||||
## 5. 动态状态
|
||||
|
||||
- [ ] 新建空会话欢迎页。
|
||||
- [ ] 当前项目名称/其他动态文案刷新正确。
|
||||
- [ ] 短消息、长消息、代码块和工具调用。
|
||||
- [ ] 用户/助手/系统/跨会话气泡。
|
||||
- [ ] 单行与多行输入。
|
||||
- [ ] 附件、笔记、队列、发送和停止状态。
|
||||
- [ ] 会话 hover、active、操作菜单展开。
|
||||
- [ ] 设置页、主题选择器、弹层和移动端侧栏。
|
||||
|
||||
## 6. 多视口
|
||||
|
||||
至少检查:
|
||||
|
||||
- [ ] 参考设计原始视口,例如 1672×941。
|
||||
- [ ] 常规桌面,例如 1440×900。
|
||||
- [ ] 窄屏,例如 500px 宽。
|
||||
- [ ] 移动端,例如 390×844。
|
||||
- [ ] 各视口横向溢出为 0 或有明确设计原因。
|
||||
- [ ] 背景定位、侧栏宽度、输入框和欢迎卡在断点处连续。
|
||||
|
||||
## 7. 自动化与静态检查
|
||||
|
||||
根据实际主题 target 调整 `<theme>`:
|
||||
|
||||
```bash
|
||||
timeout 60s node --check public/app.js
|
||||
timeout 60s node --check scripts/regression.js
|
||||
timeout 60s npm run regression -- --target <theme>-theme
|
||||
timeout 60s npm run regression -- --target <related-existing-theme>-theme
|
||||
timeout 60s npm run regression
|
||||
git diff --check
|
||||
```
|
||||
|
||||
- [ ] 新主题专项回归通过。
|
||||
- [ ] 相关旧主题专项回归通过。
|
||||
- [ ] 全量回归通过。
|
||||
- [ ] JS 语法检查通过。
|
||||
- [ ] `git diff --check` 通过。
|
||||
- [ ] 回归覆盖注册、隔离、静态/动态 DOM、资产、响应式、对比度、reduced-motion 和 cache bust。
|
||||
|
||||
## 8. 在线与浏览器校验
|
||||
|
||||
- [ ] 先用 `curl http://127.0.0.1:<port>/` 确认本地服务。
|
||||
- [ ] 如远程浏览器不能访问 localhost,使用 `hostname -I` 中的 `11.144.144.*` 地址。
|
||||
- [ ] CSS、JS 和每个新增资产请求返回 200。
|
||||
- [ ] 浏览器实际加载的 cache-busted URL 是最新版本。
|
||||
- [ ] 使用 Firefox/Playwright/Selenium 读取关键 computed style 和几何值。
|
||||
- [ ] 浏览器截图或实测记录已写入任务进度。
|
||||
|
||||
不要仅因浏览器访问 `127.0.0.1` 失败就判断服务未启动。
|
||||
|
||||
## 9. 交付与保留
|
||||
|
||||
- [ ] 列出新主题 ID、显示名和资产目录。
|
||||
- [ ] 列出修改文件和未触碰的旧主题边界。
|
||||
- [ ] 列出源素材归档、manifest 和提取脚本路径。
|
||||
- [ ] 报告真实浏览器结果和多视口数据。
|
||||
- [ ] 报告专项/全量回归结果。
|
||||
- [ ] 说明任何未验收状态或环境限制。
|
||||
- [ ] 未删除概念图、素材板、切片或生成脚本。
|
||||
|
||||
只有工程检查、真实浏览器视觉和参考图对照全部满足后,才能把主题标记为完成。
|
||||
172
.codex/skills/create-cc-web-theme/references/asset-workflow.md
Normal file
172
.codex/skills/create-cc-web-theme/references/asset-workflow.md
Normal file
@@ -0,0 +1,172 @@
|
||||
# 主题素材归档与切片工作流
|
||||
|
||||
## 目录
|
||||
|
||||
1. 建立素材台账
|
||||
2. 归档源素材
|
||||
3. 分析构图与安全区
|
||||
4. 提取背景、边框、图标和纹理
|
||||
5. 处理动态组件装饰框
|
||||
6. 保存 manifest 和生成脚本
|
||||
7. 资产质量门禁
|
||||
|
||||
## 1. 建立素材台账
|
||||
|
||||
收到素材后立即记录:
|
||||
|
||||
| 字段 | 说明 |
|
||||
|---|---|
|
||||
| 角色 | 完整参考、背景、图标板、边框板、欢迎卡、纹理或字体 |
|
||||
| 原始路径 | 会话附件或用户提供位置 |
|
||||
| 归档路径 | 当前主题任务的 `references/source-assets/` |
|
||||
| 尺寸/格式 | 像素尺寸、RGB/RGBA、PNG/WebP/JPEG 等 |
|
||||
| SHA-256 | 防止后续误换源图 |
|
||||
| 是否含 alpha | 决定是否需要背景分离 |
|
||||
| 允许用途 | 背景、切片源、对照图或仅参考 |
|
||||
|
||||
不要把完整参考图直接当产品背景,也不要把带标题、尺寸标签和卡片底的图标板当 CSS sprite。
|
||||
|
||||
## 2. 归档源素材
|
||||
|
||||
优先归档到:
|
||||
|
||||
```text
|
||||
.trellis/tasks/<date>-<theme-task>/references/source-assets/
|
||||
```
|
||||
|
||||
保留原始文件名或建立清晰映射。归档后核对源附件与归档文件 hash 一致。后续脚本只读取归档路径,避免依赖可能清理的会话附件。
|
||||
|
||||
禁止删除:
|
||||
|
||||
- 完整概念图。
|
||||
- 背景源图。
|
||||
- 图标/边框/欢迎卡素材板。
|
||||
- 视觉对照截图。
|
||||
- 提取脚本和 manifest。
|
||||
|
||||
## 3. 分析构图与安全区
|
||||
|
||||
按原始像素尺寸记录:
|
||||
|
||||
- 主视觉主体 bbox。
|
||||
- 适合侧栏和正文的低干扰区域。
|
||||
- 不能被消息、遮罩或输入区压住的高权重区域。
|
||||
- 顶部、底部和移动端裁切风险。
|
||||
- 参考图中的真实视口与组件坐标。
|
||||
|
||||
遮罩的目标是稳定文字对比,不是继续压暗整张背景。先让背景主体可见,再由局部面板解决可读性。
|
||||
|
||||
## 4. 提取背景、边框、图标和纹理
|
||||
|
||||
### 背景
|
||||
|
||||
- 优先保留用户提供的原图和构图比例。
|
||||
- 使用 WebP/PNG/JPEG 等项目已支持格式。
|
||||
- 记录 `background-size`、`background-position` 和各视口裁切策略。
|
||||
- 不对主视觉背景使用 blur,除非设计稿明确如此。
|
||||
|
||||
### 边框
|
||||
|
||||
- 从参考图提取时保留角线、短高光和必要装饰,清除烘焙背景与棋盘格。
|
||||
- 先确认边框属于固定尺寸还是动态尺寸组件。
|
||||
- 固定尺寸按钮可使用完整透明 PNG。
|
||||
- 动态高度输入框、长工具块或可伸缩卡片使用 `border-image`/九宫格,或拆成角、边和独立装饰。
|
||||
- 不把固定宽高比整框放在 `::before` 后强行覆盖动态内容。
|
||||
|
||||
### 图标
|
||||
|
||||
区分四个概念:
|
||||
|
||||
1. 设计目标尺寸。
|
||||
2. 素材板中的物理像素尺寸。
|
||||
3. 输出透明画布尺寸。
|
||||
4. 实际 alpha 主体 bbox。
|
||||
|
||||
按控件用途选择源规格,不要所有图标统一从最大档裁出后再缩到同一个 CSS 尺寸。
|
||||
|
||||
- 小动作按钮:优先干净单色 mask,主体通常比容器小。
|
||||
- 主操作按钮:使用更高规格源图,允许更大视觉主体。
|
||||
- 多色状态、头像和主题装饰:保留原色,单独处理尺寸。
|
||||
- 非方形图标:保持比例并放入统一画布,不拉伸。
|
||||
- 非对称图标:按 alpha 加权重心校正光学中心。
|
||||
|
||||
alpha 加权中心:
|
||||
|
||||
```text
|
||||
cx = sum(x * alpha) / sum(alpha)
|
||||
cy = sum(y * alpha) / sum(alpha)
|
||||
offset = canvas_center - (cx, cy)
|
||||
```
|
||||
|
||||
### RGB 素材板分离 alpha
|
||||
|
||||
RGB WebP 常含有损压缩噪点,不能只用单一亮度阈值。推荐:
|
||||
|
||||
1. 按主体外扩 2–4px 裁剪。
|
||||
2. 从边缘 flood-fill 识别与暗背景相连区域。
|
||||
3. 结合亮度、色相和局部差值识别金色/浅色/状态色。
|
||||
4. 去除小连通域噪点。
|
||||
5. 对 alpha 轻微羽化,避免黑边。
|
||||
6. 在深色、浅色和半透明背景上人工复核。
|
||||
|
||||
阈值必须针对当前素材板调试,不跨主题硬编码。
|
||||
|
||||
## 5. 处理动态组件装饰框
|
||||
|
||||
### 先问三个问题
|
||||
|
||||
1. 组件宽高是否随内容变化?
|
||||
2. 哪些区域可以拉伸,哪些角/徽记必须保持比例?
|
||||
3. 聚焦、拖拽、笔记、运行等状态是否改变 border 或尺寸?
|
||||
|
||||
### 推荐选择
|
||||
|
||||
| 场景 | 推荐 |
|
||||
|---|---|
|
||||
| 固定 48px 按钮 | 完整透明框图或 mask |
|
||||
| 宽度变化、高度固定 | 水平三段切片或 `border-image` |
|
||||
| 宽高都变化 | 九宫格 `border-image` |
|
||||
| 底部中心徽记不能拉伸 | 框体九宫格 + 独立徽记,或通过不拉伸 slice 保留 |
|
||||
| 装饰只是短角线 | CSS border + 小伪元素,不加载整张框 |
|
||||
|
||||
测试最短、常规和最长内容。只验证单行输入不能证明动态框正确。
|
||||
|
||||
## 6. 保存 manifest 和生成脚本
|
||||
|
||||
每个派生资产至少记录:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "send",
|
||||
"source": "icon-sheet.webp",
|
||||
"source_sha256": "...",
|
||||
"source_box": [x, y, width, height],
|
||||
"variant": "24px",
|
||||
"detected_box": [x, y, width, height],
|
||||
"output": "icons/send.png",
|
||||
"size": [32, 32],
|
||||
"usage": "composer primary action"
|
||||
}
|
||||
```
|
||||
|
||||
生成脚本应:
|
||||
|
||||
- 使用项目已有依赖,避免为一次切图引入重量级包。
|
||||
- 只读取归档源素材。
|
||||
- 可重复运行并稳定覆盖派生资产。
|
||||
- 写出 manifest,失败时指出具体资产。
|
||||
- 用中文注释说明当前素材板特有的阈值、区域和校正。
|
||||
|
||||
Wasteland 案例脚本位于 `.trellis/tasks/07-17-gilded-wasteland-theme/research/extract_reference_chrome.py`,只可作为方法参考,不要直接复用其坐标和颜色阈值。
|
||||
|
||||
## 7. 资产质量门禁
|
||||
|
||||
- 文件格式、尺寸和 alpha 通道符合用途。
|
||||
- 背景 hash 与归档源一致,或记录过转换原因。
|
||||
- manifest 与实际文件一一对应,没有遗漏或多余派生图。
|
||||
- 透明图在深/浅/半透明背景上无黑边和棋盘格。
|
||||
- 尖角、纸飞机尾部、气泡尾巴和状态色未被裁掉。
|
||||
- 图标实际主体尺寸符合控件层级,不以画布尺寸代替可见尺寸。
|
||||
- 光学中心误差可解释并在按钮中实测。
|
||||
- 浏览器请求所有资产返回 200,MIME 正确。
|
||||
- 源素材、manifest 和提取脚本仍然存在。
|
||||
@@ -0,0 +1,158 @@
|
||||
# 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.*` 地址排除网络命名空间问题。
|
||||
185
.codex/skills/create-cc-web-theme/references/lessons-learned.md
Normal file
185
.codex/skills/create-cc-web-theme/references/lessons-learned.md
Normal file
@@ -0,0 +1,185 @@
|
||||
# 主题创作经验教训
|
||||
|
||||
## 目录
|
||||
|
||||
1. 完成标准
|
||||
2. 构图与装饰
|
||||
3. 边框与动态尺寸
|
||||
4. 图标与重复来源
|
||||
5. 透明度与选择器
|
||||
6. 居中、菜单与动态 DOM
|
||||
7. 范围控制与缓存
|
||||
|
||||
## 1. 完成标准
|
||||
|
||||
### 教训:自动化通过不代表像设计图
|
||||
|
||||
症状:资产存在、选择器命中、回归全绿,但用户第一眼认为“完全不是一个东西”。
|
||||
|
||||
根因:回归只能证明结构契约,不能证明构图比例、边框轻重、视觉层级和图标质感。
|
||||
|
||||
做法:
|
||||
|
||||
- 把真实浏览器视觉对照列为独立完成阶段。
|
||||
- 按参考图原始视口先验收,再做响应式。
|
||||
- 为关键区域记录截图、几何值和 computed style。
|
||||
- 用户未确认或对照差异明显时,回滚“完成”状态。
|
||||
|
||||
## 2. 构图与装饰
|
||||
|
||||
### 教训:参考图不是配色板
|
||||
|
||||
症状:颜色接近,但人物被遮罩压黑、侧栏比例不对、卡片堆叠、整体质感跑偏。
|
||||
|
||||
根因:只抽取黑、金、棕等颜色,没有量化参考图的空间、留白和主视觉安全区。
|
||||
|
||||
做法:先量化侧栏/顶栏/输入区比例、主视觉 bbox、阅读安全区和面板覆盖范围。
|
||||
|
||||
### 教训:主题感不是“给所有组件加边框”
|
||||
|
||||
症状:搜索框、消息、列表、弹层、工具块全都厚金边和切角,界面像重型游戏皮肤。
|
||||
|
||||
根因:把局部装饰语言泛化到所有组件。
|
||||
|
||||
做法:建立装饰预算。只让主按钮、输入框和少数工具框承担强边框;普通消息、列表和小标签使用轻线或无边框。
|
||||
|
||||
### 教训:先删重,再加细节
|
||||
|
||||
症状:越修越多伪元素、渐变、阴影和粒子,参考主体反而更弱。
|
||||
|
||||
做法:按“背景 → 大布局 → 面板 → 边框 → 图标 → 微交互”排序。发现层级错误时先删除多余装饰,不继续叠覆盖规则。
|
||||
|
||||
## 3. 边框与动态尺寸
|
||||
|
||||
### 教训:固定比例伪元素不适合动态输入框
|
||||
|
||||
症状:单行看似正确,多行内容后边框、底线或徽记偏移;窄屏出现非等比压缩。
|
||||
|
||||
根因:把固定 `width/height` 比例的整框放在 `::before`/`::after`,它不跟随真实内容盒的边界语义。
|
||||
|
||||
做法:
|
||||
|
||||
- 动态宽高使用 `border-image`/九宫格。
|
||||
- 把不能拉伸的徽记和可拉伸边线分开。
|
||||
- 测试最短、常规和最大高度。
|
||||
- focus/drag/note 状态不要用 `border: 0` 破坏 frame。
|
||||
|
||||
### 教训:莫名边框通常来自叠层,不是主框
|
||||
|
||||
症状:按钮旁多出框、输入区出现虚线、聚焦后冒出第二层边。
|
||||
|
||||
根因:旧 focus ring、按钮 `::after`、背景素材烘焙线、主框图片内外双线同时存在。
|
||||
|
||||
做法:在 DevTools 逐个关闭伪元素、border、outline、box-shadow 和背景图,确定真实来源后只删那一层。
|
||||
|
||||
## 4. 图标与重复来源
|
||||
|
||||
### 教训:统一画布不等于统一视觉尺寸
|
||||
|
||||
症状:CSS 都是 24px,但图标仍显得过小、过大或偏心。
|
||||
|
||||
根因:透明画布内的 alpha 主体 bbox 不同;不同形状的光学重心也不同。
|
||||
|
||||
做法:记录源规格、输出画布、alpha bbox 和实际 CSS 尺寸;非对称图标按 alpha 重心校正。
|
||||
|
||||
### 教训:最大档切图缩小不一定更清晰
|
||||
|
||||
症状:64px 原色 PNG 缩到 18–24px 后灰边、糊、材质脏。
|
||||
|
||||
根因:有损素材板中的半透明暗边和高光被浏览器重采样到很小区域。
|
||||
|
||||
做法:主交互控件重切对应规格并制作干净 mask;多色状态和头像保留原色但独立裁切。
|
||||
|
||||
### 教训:新图标可能叠在旧图标上
|
||||
|
||||
症状:头像两个图、新会话加号消失/重复、发送按钮出现“一坨”。
|
||||
|
||||
根因:真实 DOM 已有文字、SVG 或 `<img>`,主题又添加了背景图或伪元素。
|
||||
|
||||
做法:先检查 DOM。每个语义只保留一个视觉来源;只在目标主题下隐藏原生子节点。
|
||||
|
||||
## 5. 透明度与选择器
|
||||
|
||||
### 教训:RGBA 很低仍可能看起来不透明
|
||||
|
||||
症状:外层气泡改为 2%–10% alpha,页面仍像实心黑卡片。
|
||||
|
||||
根因可能包括:
|
||||
|
||||
- 内层 tool-call/content/title 仍是 90% 黑底。
|
||||
- blur 太高,把背景细节抹成均匀色块。
|
||||
- 旧规则用更高 specificity 锁住 background。
|
||||
- 伪元素仍覆盖整层。
|
||||
|
||||
做法:从最外层到最内层检查 computed background、background-image、opacity、backdrop-filter 和伪元素。用背景纹理是否可辨判断“透”,不用数值自我证明。
|
||||
|
||||
### 教训:`backdrop-filter` 变了不代表背景色也变了
|
||||
|
||||
症状:DevTools 显示 blur 已更新,但气泡底色完全不变。
|
||||
|
||||
根因:共享 `:is()` 规则的最高参数 specificity 超过后置主题规则。
|
||||
|
||||
做法:查看每个 computed 属性的获胜规则;使用同级 selector 或只对冲突属性精确增加 `!important`。不要把 `!important` 扩散到整个主题。
|
||||
|
||||
### 教训:模糊强度不是越高越有磨砂感
|
||||
|
||||
症状:提高 blur 后背景更像不透明色块。
|
||||
|
||||
根因:暗场细节被平均,透景消失。
|
||||
|
||||
做法:先降低染色层,再用较小 blur 配合适度 saturate/brightness;最终数值按当前背景实测,不把某个主题的 `blur(3px)` 当通用常量。
|
||||
|
||||
## 6. 居中、菜单与动态 DOM
|
||||
|
||||
### 教训:CSS “居中”需要测量证据
|
||||
|
||||
症状:代码有 flex/absolute 50%,视觉仍偏。
|
||||
|
||||
根因:容器本身不在画布中心、baseline 不一致、图片 alpha 主体偏心或滚动条改变内容区中心。
|
||||
|
||||
做法:分别测容器中心、画布中心、图标 alpha 中心和文字 line box;记录像素差后修正。
|
||||
|
||||
### 教训:菜单没显示可能是被父级裁切
|
||||
|
||||
症状:点击后状态正确,菜单 DOM 也存在,但看不到。
|
||||
|
||||
根因:列表项 `overflow: hidden`、错误 stacking context 或按钮被 flex 挤出。
|
||||
|
||||
做法:检查展开态 overflow、定位基准、z-index 和操作区尺寸。只在菜单打开时解除必要裁切。
|
||||
|
||||
### 教训:静态与动态 welcome 会漂移
|
||||
|
||||
症状:首次打开显示旧文案,刷新/切会话后才正确;结构修了一处另一处仍旧。
|
||||
|
||||
根因:`index.html` 与 `buildWelcomeMarkup()` 是两条渲染路径。
|
||||
|
||||
做法:结构同步,动态文案使用同一 formatter/hydration 节点;回归同时读取静态与动态源码。
|
||||
|
||||
## 7. 范围控制与缓存
|
||||
|
||||
### 教训:用户圈的是哪层,就只改哪层
|
||||
|
||||
症状:用户要求气泡透明,却修改了所有卡片、工具层或整页背景,导致更多视觉偏差。
|
||||
|
||||
做法:先用 DOM/DevTools 确认用户所指层级,明确 selector 列表;超出范围的发现只记录,不顺手实施。
|
||||
|
||||
### 教训:选择器写错会让正确元素消失
|
||||
|
||||
症状:加号消失或旧规则继续生效。
|
||||
|
||||
根因:假定 class 名,没有检查真实 DOM;新 selector 命中不存在节点,旧隐藏规则仍命中真实节点。
|
||||
|
||||
做法:实现前用 `rg` 和浏览器检查实际 class,回归断言真实节点保持所需显示状态。
|
||||
|
||||
### 教训:缓存会制造“完全没变化”的假象
|
||||
|
||||
做法:
|
||||
|
||||
- 修改 CSS/JS 后推进 cache-busting query。
|
||||
- 用浏览器读取实际 `<link>`/`<script>` URL。
|
||||
- 用 HTTP 请求确认最新资源内容与 200。
|
||||
- 确认缓存后再判断 CSS 是否无效。
|
||||
|
||||
### 教训:并行会话会反复覆盖共享主题文件
|
||||
|
||||
做法:开始前审计活跃会话和脏文件;为子任务划分不重叠写入面。发现相同区块连续回写时停止互相覆盖,协调后再合并。
|
||||
Reference in New Issue
Block a user