首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >OpenSpec 项目实战(五) | UI 视觉打磨 + 改 template 让 AI 写出规范任务

OpenSpec 项目实战(五) | UI 视觉打磨 + 改 template 让 AI 写出规范任务

原创
作者头像
运维有术
发布2026-05-19 09:35:39
发布2026-05-19 09:35:39
1810
举报
文章被收录于专栏:运维有术运维有术

OpenSpec 项目实战(五) | UI 视觉打磨 + 改 template 让 AI 写出规范任务

🚩 2026 年「术哥无界」系列实战文档 X 篇原创计划 第 115 篇,OpenSpec 项目实战「2026」系列第 5

大家好,欢迎来到 术哥无界 | ShugeX | 运维有术

我是术哥,一名专注于 AI 编程、AI 智能体、Agent Skills、MCP、云原生、AIOps、Milvus 向量数据库的技术实践者与开源布道者

Talk is cheap, let's explore。无界探索,有术而行。

封面图
封面图

封面:UI 视觉打磨 + 改 template 让 AI 写出规范任务

说明:本文内容基于 OpenSpec(Fission-AI/OpenSpec)v1.3.1 和 React 19 + TypeScript + Tailwind CSS v4 的实际操作记录整理而成。文中的配置模板和参数建议仅供参考,实际效果请以你的业务数据和环境测试结果为准。如果有实际使用经验,欢迎在评论区分享交流。

1. 视觉要升级,但更重要的是一个实验

第 4 期做了布局骨架。首页有了 Tab 分类导航,5 个工具、4 个分类,点 Tab 切分类,不用再在长列表里滚来滚去。

但页面打开一看——灰白一片。品牌色是 Tailwind 默认蓝(#3B82F6),没有图标,卡片和导航样式单调,没有动效。说好听叫「简洁」,说直白就是「没做完」。

这期做两件事。

第一件:视觉层真正的升级。基于第 3 期搭好的 CSS 变量体系和第 4 期的布局骨架,把配色、组件样式、图标、动效做上去,让页面从「脚手架」变成「产品」。change name: ui-visual-polish

第二件更重要,也是这期文章的重点。前 4 期的 tasks.md 格式一直有问题——schema instruction 里明明要求用 ### 任务 N:[名称] + 涉及文件 + TDD 五步结构,但 AI 每次生成的都是 ## 1. 任务名称 + - [ ] 1.1 这种格式。改了好几次 instruction,没用。

后来读了 OpenSpec 源码,找到根因:template 的优先级高于 instruction。旧 template 用 ## 1. 格式,LLM 就跟 template 走。这期把 template 改了,今天是第一次验证效果。

完整流程不变:

工作流总览:5 步从探索到归档
工作流总览:5 步从探索到归档

2. 为什么前 4 期的 tasks.md 格式都不对

先看问题。第 1 期到第 4 期的 tasks.md 开头长这样。

第 1 期(project-init)

代码语言:markdown
复制
## 1. 项目脚手架初始化

- [x] 1.1 使用 Vite 初始化 React + TypeScript 项目
  命令:`npx create-vite@latest . --template react-ts --yes`
  预期:项目文件生成

第 2 期(tool-registry)

代码语言:markdown
复制
## 1. 更新 catalog.ts(添加 stage 字段和初始工具数据)

**涉及文件:**
- 修改:`src/tool-registry/catalog.ts`

- [x] **1.1:更新 ToolManifest 接口**

第 3 期(ui-redesign)

代码语言:markdown
复制
## 1. 设计系统基础

- [x] 1.1 创建 design-tokens.css 文件

第 4 期(layout-restructure)

代码语言:markdown
复制
## 1. Tab 导航组件测试

- [ ] 1.1 编写 Tab 导航组件测试

看到了吗?全部都是 ## 1. + - [x] 1.1 格式。4 期文章、4 个不同的 change、几十个任务,没有一次出现 ### 任务 N 的格式。

再来看 instruction 里写了什么。逐字引用 openspec/schemas/with-review/schema.yaml 中 tasks 的 instruction 部分(截取关键段落):

代码语言:yaml
复制
- id: tasks
  generates: tasks.md
  description: Implementation checklist with trackable tasks
  template: tasks.md
  instruction: |
    创建细粒度的实现计划。每个任务的工作量应在 2-5 分钟之间。

    ## 任务格式(必须严格遵守)

    每个任务必须遵循以下格式:

    ### 任务 N:[组件名称]

    **涉及文件:**
    - 新建/修改:exact/path/to/file
    - 测试:tests/exact/path/to/test

    - [ ] **第 1 步:写失败测试**
    - [ ] **第 2 步:运行测试——确认失败**
    - [ ] **第 3 步:写最小实现**
    - [ ] **第 4 步:运行测试——确认通过**
    - [ ] **第 5 步:提交**

    ## 禁止事项(出现即视为计划不合格)
    - 「TBD」「TODO」「implement later」「fill in details」

instruction 里写得清清楚楚:### 任务 N:[组件名称],涉及文件列表,TDD 五步。甚至用了「必须严格遵守」这种措辞。

但 AI 一次都没遵守。

第 2 期稍微好一点,出现了「涉及文件」这一行,但标题还是 ## 1.,步骤还是 - [x] 1.1。第 3 期和第 4 期连涉及文件都没有了。

这不是偶然。4 期都是同一个模式,说明不是某次生成时的随机偏差,而是有系统性的原因。

根因分析:template 的优先级高于 instruction

OpenSpec 生成工件时,同时读取两个输入:template(模板文件,在 schemas/with-review/templates/ 目录下)和 instruction(指令文本,在 schema.yamlinstruction 字段里)。

LLM 面对这两个输入时的行为模式是:template 提供具体的格式示例,instruction 提供文字描述。当两者格式冲突时,LLM 倾向于跟 template 走。

这个判断来自对 OpenSpec 源码的调研。生成工件时,template 的内容被作为「参考格式」先展示给 LLM,instruction 作为「补充说明」跟在后面。顺序上的差异导致 template 的格式暗示更强——LLM 会把 template 当作「你应该长成这样」的范本,把 instruction 当作「内容上注意这些」的建议。

旧 template 的格式是这样的:

代码语言:markdown
复制
## 1. <!-- Task Group Name -->

- [ ] 1.1 <!-- Step description -->
- [ ] 1.2 <!-- Step description -->

AI 看到这个模板,脑子里形成了一个框架:「标题用 ## 1.,步骤用 - [ ] 1.1」。然后 instruction 说「用 ### 任务 N」,但它已经被 template 的格式锚定了,改不过来。

这就像你让一个人照着模板写公文,模板是表格格式的,你在旁边说「请用列表格式」,他大概率还是照着模板写表格。不是因为不听,而是模板的视觉暗示太强了。

改造方案:直接改 template

既然 instruction 管不了格式,那就改 template。逐字引用改造后的 openspec/schemas/with-review/templates/tasks.md

代码语言:markdown
复制
### 任务 1:<!-- Task Group Name -->

**涉及文件:**
- 新建/修改:exact/path/to/file
- 测试:tests/exact/path/to/test

- [ ] 1.1 **写失败测试**
``typescript
// test code here
``

- [ ] 1.2 **运行测试——确认失败**
命令:`npx vitest run tests/path/test.ts`
预期:FAIL — <!-- expected error -->

- [ ] 1.3 **写最小实现**
``typescript
// implementation code here
``

- [ ] 1.4 **运行测试——确认通过**
命令:`npx vitest run tests/path/test.ts`
预期:PASS

- [ ] 1.5 **提交**
``bash
git add path/to/files
git commit -m "feat: description"
``

### 任务 2:<!-- Task Group Name -->

**涉及文件:**
- 新建/修改:exact/path/to/file
- 测试:tests/exact/path/to/test

- [ ] 2.1 <!-- Continue with the same pattern -->

改动点很明确:

维度

旧 template

新 template

标题格式

## 1.

### 任务 1:

涉及文件

**涉及文件:** + 文件路径列表

步骤结构

- [ ] 1.1 描述

TDD 五步(写失败测试 → 确认失败 → 写实现 → 确认通过 → 提交)

代码占位

每步都有代码块或命令行

第二个任务

同上

重复模板结构

## 1. 变成 ### 任务 1:,看起来只是标记层级和命名方式的变化,但对 LLM 来说,这个格式改变会产生不同的输出模式。加了「涉及文件」列表,AI 就会习惯性地列出每个任务涉及的文件。加了 TDD 五步结构,AI 就会按这个节奏组织每个任务。

本期 ui-visual-polish change 是改造 template 后的第一次验证。

如果 AI 跟新 template 走了,tasks.md 的格式就会变成 ### 任务 N + 涉及文件 + TDD 五步。如果还是 ## 1. 格式,说明问题不止在 template,需要进一步排查。

当前项目状态

顺便说明一下本期开始前的项目状态。

逐字引用 src/theme/tokens.css(第 3 期产出,77 行):

代码语言:css
复制
:root {
  /* 品牌色板 - 冷色系 */
  --color-primary-500: #3B82F6;
  --color-primary-600: #2563EB;
  --color-primary-700: #1D4ED8;

  /* 强调色 - 琥珀色 */
  --color-accent-500: #F59E0B;
  --color-accent-600: #D97706;

  /* 中性色 - 冷灰 */
  --color-neutral-50: #F8FAFC;
  --color-neutral-200: #E2E8F0;
  --color-neutral-500: #64748B;
  --color-neutral-900: #0F172A;
  /* ... 字体、间距、圆角等 */
}

CSS 变量体系有了,但 Home 页面的 ToolCard 组件大量使用 inline style,没有充分复用这些变量。TopNav 也很基础——一个 logo + 一个「首页」链接。配色是 Tailwind 默认蓝,没有品牌辨识度。

这些就是本期视觉升级的起点。

3. Explore → Propose:从需求澄清到 5 个工件一步到位

这期有个重要发现:Explore 和 Propose 不是两个独立步骤,而是连续流程。执行 /opsx:explore,多轮对话确认方向后,AI 输出 Design Doc,确认后直接自动创建 change 并生成全部 5 个工件——中间没有单独的 /opsx:propose 步骤。

以下是完整交互过程。

多轮对话:确认视觉升级方向

执行 /opsx:explore,AI 先问了一句:

代码语言:markdown
复制
AI:What's on your mind? An idea, a problem, a comparison — or just wander?

输入本期需求:

代码语言:markdown
复制
用户:本期做一个 ui-visual-polish 变更。当前页面的 CSS 变量体系已搭好但未充分使用,配色是默认蓝没有辨识度,没有图标系统,卡片和导航样式单调。需要全面升级视觉层——配色、图标、动效,让页面从脚手架变成产品。

AI 读了一遍源码,做了一轮 Gap 分析:

代码语言:markdown
复制
AI:{读源码,做 Gap 分析}

现状梳理:
Primary (蓝):    50→700   ← 几乎未使用
Accent (琥珀):   50→600   ← Beta/Planned badge,active tab border
Neutral (冷灰):  50→900   ← 大量使用
Semantic:        success/warning/error  ← 未使用

Gap 分析:
| 维度 | 现状 | 问题 |
|------|------|------|
| 配色 | 变量定义好了,但只用 neutral | 蓝得很默认,缺乏辨识度 |
| 图标 | 仅有一个 ⏳ emoji | 分类/Tab/卡片均无图标 |
| 动效 | 仅 transition-colors,hover:shadow-md | 没有微交互 |
| 卡片 | 纯 flat border + opacity | 没有层次感 |
| 导航 | border-b-2 amber 作为 active indicator | 与品牌蓝不一致 |

几个思考方向:1. 配色策略 2. 图标系统 3. 动效深度 4. 视觉锚点。你倾向于先攻哪个方向?或者想先聊聊整体的设计语言定位再动手?

Gap 分析很准确——变量体系搭好了但几乎没用上,中性灰堆满了整个页面。一口气给 4 个方向都定了:

代码语言:markdown
复制
用户:1. 配色:换掉默认蓝,选一个有辨识度的品牌色。primary 做交互色,accent 保持琥珀做功能区分。具体的色值你来定,不要用 Tailwind 默认蓝。2. 图标:用 Lucide,每个 category 配一个 icon,badge 用小图标辅助(Beta 用 🧪 / Planned 用 📋)。3. 动效:做到中等——卡片 hover scale + shadow + stagger 入场动画,tab 切换加滑动指示器。不需要 page transition。4. Header:保持纯文字,但加一个简洁的 icon 或 logo mark,背景用微渐变提升层次。整体方向:干净、专业、有品牌感,不要花哨。参考 Linear 或 Vercel 的设计风格。

AI 又追问了 4 个关键问题:

代码语言:markdown
复制
AI:方向清晰了。再摸几个关键问题:

1. **品牌色定位** — 推荐蓝紫(blue-violet),比纯蓝更有辨识度,比纯紫更稳。你接受吗?
2. **Lucide React 安装了吗?**
3. **背景渐变** — 浅色 header + subtle gradient 还是深色 header?
4. **动效节奏** — 快速连续(30-50ms)还是柔和错落(80-120ms)?
代码语言:markdown
复制
用户:1. 蓝紫方向接受,你来定具体色值。2. Lucide 没装,本期 install 进去。3. 浅色 header + subtle gradient,保持整体 light theme 基调。4. 柔和错落 80-120ms,偏产品感。

接下来是图标分配和 Badge 方案:

代码语言:markdown
复制
AI:好,我来分配图标,附上理由:
- 文本处理 → Type ← 文字输入/编辑感
- 数据转换 → RefreshCw ← 转换/循环感
- 开发工具 → Code2 ← 开发者身份明确
- 内容创作 → Feather ← 创作、手写感
Badge: Beta → Flask, Planned → ClipboardList。确认这 6 个 icon 分配?
代码语言:markdown
复制
用户:确认
代码语言:markdown
复制
AI:最后确认——Badge 的 emoji 方案:纯图标 vs 图标+emoji 混搭?
代码语言:markdown
复制
用户:纯图标

到这里所有细节都定了。AI 输出完整 Design Doc。

Design Doc + 自动生成 5 个工件

AI 输出的 Design Doc 关键内容:

代码语言:markdown
复制
AI:{输出完整 Design Doc}

## UI Visual Polish — Design Doc

### 1. 配色体系
品牌色:蓝紫 (Blue-Violet)
Primary (蓝紫)              Accent (琥珀)              Semantic
─────────────────           ─────────────────           ────────
50: #F5F3FF   极浅紫          50: #FFFBEB               success: #10B981
100: #EDE9FE                 100: #FEF3C7              warning: #F59E0B
200: #DDD6FE                 200: #FDE68A              error: #EF4444
300: #C4B5FD                 300: #FCD34D
400: #A78BFA                 400: #FBBF24
500: #8B5CF6   ← 品牌主色     500: #F59E0B
600: #7C3AED   ← 深色交互     600: #D97706
700: #6D28D9   ← 强调/hover
语义映射:交互色 primary-500, Beta badge accent-500, Active tab indicator primary-500

### 2. 图标系统
Category Icons: 文本处理→Type, 数据转换→RefreshCw, 开发工具→Code2, 内容创作→Feather
Badge Icons: Beta→Flask(替代🧪), Planned→ClipboardList(替代📋)

### 3. 动效
卡片 Hover: scale 1.02, shadow rgba(139,92,246,0.15), 200ms ease-out
Stagger: fadeInUp 400ms, cubic-bezier(0.22,1,0.36,1), 100ms stagger
Tab 指示器: JS left/width, 250ms cubic-bezier(0.4,0,0.2,1)

### 4. Header
background: linear-gradient(135deg, neutral-50 → primary-50)
标题左侧: Wand2 icon + "shuge AI Toolbox"

### 5. 修改文件清单
tokens.css, index.css, Home.tsx, NotFound.tsx, PlaceholderPage.tsx, package.json

Design Doc 确认吗?可以的话我们开 change 了。

确认后,AI 直接自动执行 openspec new change "ui-visual-polish" 并生成全部 5 个工件,没有等用户再去执行什么 propose 命令:

代码语言:markdown
复制
用户:确认
代码语言:markdown
复制
AI:{自动执行 openspec new change "ui-visual-polish",生成 5 个工件}

Change `ui-visual-polish` 创建完成。所有 artifacts 位于 `openspec/changes/ui-visual-polish/`:
| Artifact | 说明 |
|----------|------|
| proposal.md | 变更动机 + 影响范围 |
| design.md | 蓝紫色值决策、Lucide 选型、Stagger/Tab 指示器实现方案对比 |
| specs/visual-identity/spec.md | 4 个 capability 的场景定义(配色/图标/动效/Header) |
| review.md | 5 维度审查,重点关注任务粒度和测试覆盖 |
| tasks.md | 9 个任务组,涵盖安装依赖 → 配色 → 4 类图标 → stagger → tab 指示器 → header → NotFound → Placeholder → 提交 |

下一步:运行 `/opsx:apply` 开始实现。

template 改造效果:格式变了

这是本期最有价值的观察点。直接看 tasks.md 实际生成的第一个任务组:

代码语言:markdown
复制
### 任务 1:安装 lucide-react + 重建 tokens.css 配色

**涉及文件:**
- 修改:`package.json`
- 修改:`src/theme/tokens.css`

- [ ] 1.1 **安装 lucide-react**

``bash
npm install lucide-react
``

- [ ] 1.2 **更新 package.json 并验证 lockfile**

``bash
cat package.json | grep lucide-react
``
预期:`"lucide-react": "^0.468.0"`(或当前最新版本)

- [ ] 1.3 **重建 tokens.css 的 primary 色板为蓝紫系**

``css
  /* 品牌色板 - 蓝紫 (Blue-Violet) */
  --color-primary-50: #F5F3FF;
  --color-primary-100: #EDE9FE;
  --color-primary-200: #DDD6FE;
  --color-primary-300: #C4B5FD;
  --color-primary-400: #A78BFA;
  --color-primary-500: #8B5CF6;
  --color-primary-600: #7C3AED;
  --color-primary-700: #6D28D9;
``

- [ ] 1.4 **运行测试——确认 CSS 变量正确**

``bash
npx vitest run
``
预期:PASS

对比改造前:

代码语言:markdown
复制
## 1. 任务名称

- [x] 1.1 步骤描述
- [x] 1.2 步骤描述

结论很清晰:标题从 ## 1. 变成了 ### 任务 1:,涉及文件列表成了标配,每个步骤都有代码块。 改 template 确实生效了。

9 个任务组里 8 个都有涉及文件列表,代码块总共 34 个,是前 4 期的历史高点。

不过也有一个没完全到位的地方:TDD 五步(写失败测试→确认失败→写实现→确认通过→提交)没有严格遵循。实际更接近「改代码 → 运行测试确认没坏」的回归测试模式。review.md 也指出了这个问题,标了 ⚠️ 警告:视觉类任务难以按 TDD 节奏严格拆分。这个观察很重要,后面回顾章节会展开。

4. Apply:33 步全量执行 + 三个小插曲

执行 /opsx:apply,AI 开始逐任务执行。

代码语言:markdown
复制
AI:Using change: **ui-visual-polish** (schema: with-review). Reading context files...

AI:Implementing: ui-visual-polish (schema: with-review). Progress: 0/33 tasks complete. Working on Task 1/9: 安装 lucide-react + 重建 tokens.css 配色

33 个步骤,9 个任务组,AI 一路往下跑。

三个小插曲

执行过程中出现了三个有意思的问题,AI 都自行发现并修复了。

插曲 1:Flask 图标不存在,改用 Beaker

Explore 阶段 Design Doc 规划了 Beta badge 用 Flask 图标。但 apply 执行时,AI 发现 lucide-react 里根本没有 Flask 这个组件,自动改用了 Beaker

规划时选了 Flask,实际发现 lucide-react 没有 Flask,改用了 Beaker——这种规划→执行的偏差在真实项目里很常见。AI 编程助手在执行时的这种自适应能力,是它比纯脚本自动化更有价值的地方。

插曲 2:index.css 内容被意外覆盖

代码语言:markdown
复制
AI:我发现一个问题——我把 index.css 的原有内容(imports)覆盖了。需要补回来。

AI 在编辑 index.css 时不小心覆盖了原有 imports 内容,随即自己发现并补回。这种自我修复是 AI 编程助手的常见行为——它会犯错,但也会监控自己的输出并在发现问题时立即修正。

插曲 3:NotFound.tsx 不需要改

代码语言:markdown
复制
AI:NotFound.tsx already uses `var(--color-primary-500)` — no changes needed.

tasks.md 任务 7 规划了 NotFound 配色更新。但 apply 时 AI 发现 NotFound.tsx 已经使用了 var(--color-primary-500) CSS 变量——tokens.css 的 primary 色值从 #3B82F6 改为 #8B5CF6 后,404 页面的颜色自动跟随变化,不需要改代码。

这就是使用 CSS 变量的好处:一处修改,全局生效。

另外还有一个 bug 修复:AI 使用了 React.createElement 但没导入 React,测试失败后快速定位并添加了 import React

Apply 完成报告

代码语言:markdown
复制
AI:## Implementation Complete

**Change:** `ui-visual-polish`
**Schema:** `with-review`
**Progress:** 33/33 tasks complete ✓

### Completed This Session
- Task 1: npm install lucide-react + tokens.css primary 色板重建为蓝紫系
- Task 2: index.css 添加 fadeInUp keyframes + .animate-fadeInUp class
- Task 3: Home.tsx 导入 Lucide 图标 + categoryIcon 映射 + Badge Lucide 图标 + Category 图标
- Task 4: Home.tsx stagger 入场动画 + hover scale/shadow 效果
- Task 5: Home.tsx Tab 滑动指示器 (JS ref + CSS transition)
- Task 6: Home.tsx Header Wand2 icon + 135deg 微渐变
- Task 7: NotFound.tsx 配色确认(已是 primary-500)
- Task 8: PlaceholderPage.tsx ⏳ → Clock icon
- Task 9: 全量测试 PASS + commit

### 发现并解决的问题
- Flask 在 lucide-react 中不存在 → 改用 Beaker
- Tab 指示器高亮从 className border-b-2 改为 style.borderColor(无侵入)
- Active Tab 样式用 inline style 替代 class 注入(避免 CSS 类名测试失效)

### Bug 修复
- React.createElement 未导入 React → 添加 import React

所有 30 个测试全部通过。变更已提交。可以 `/opsx:archive` 归档。

关键文件变更摘要

不多贴代码,说几个关键变化。

tokens.css:primary 色板从默认蓝换成蓝紫。

代码语言:css
复制
/* Before */
--color-primary-500: #3B82F6;
--color-primary-600: #2563EB;
--color-primary-700: #1D4ED8;

/* After */
--color-primary-500: #8B5CF6;
--color-primary-600: #7C3AED;
--color-primary-700: #6D28D9;

Home.tsx:从 146 行增加到 210 行,新增了 7 个 Lucide 图标导入、categoryIcons 映射、stagger 入场动画(useEffect + CSS 变量注入)、Tab 滑动指示器(ref + indicator state + resize 监听)、Header 的 Wand2 图标 + 135deg 微渐变背景。Badge 从纯文字变成了图标+文字(Beaker / ClipboardList)。

PlaceholderPage.tsx:⏳ emoji 替换为 <Clock size={16}> 图标。

5. Verify:构建通过 + 30 测试全过 + 视觉对比

构建和测试

Apply 后跑了一遍构建:

代码语言:markdown
复制
> shuge-ai-toolbox@0.0.0 build
> tsc -b && vite build

vite v8.0.12 building client environment for production...
✓ 1753 modules transformed.
rendering chunks...
computing gzip size...
dist/index.html                   0.46 kB │ gzip:  0.30 kB
dist/assets/index-DfrT9w8n.css   19.57 kB │ gzip:  4.67 kB
dist/assets/index-UZjH-ntc.js   295.01 kB │ gzip: 94.25 kB

✓ built in 306ms

一个细节:1753 modules。引入 lucide-react 之前是 31 个模块,引入后暴增到 1753 个——图标库的 tree-shaking 确实在工作,但 lucide-react 的总量还是不小。

再跑测试:

代码语言:markdown
复制
> shuge-ai-toolbox@0.0.0 test
> vitest run

 ✓ src/router/index.test.tsx (3 tests) 2ms
 ✓ src/tool-registry/catalog.test.ts (7 tests) 7ms
 ✓ src/layout/TopNav.test.tsx (3 tests) 31ms
 ✓ src/layout/Layout.test.tsx (2 tests) 34ms
 ✓ src/app/views/PlaceholderPage.test.tsx (5 tests) 82ms
 ✓ src/app/views/Home.test.tsx (10 tests) 205ms

 Test Files  6 passed (6)
      Tests  30 passed (30)
   Start at  11:41:23
   Duration  1.15s

30 个测试全部通过,说明视觉变更没有破坏任何功能。

Before / After 视觉对比

视觉变更,截图比代码更有说服力。

首页 Before

首页 Before
首页 Before

视觉升级前——Tailwind 默认蓝、无图标、灰白色调

首页 After

首页 After
首页 After

视觉升级后——蓝紫品牌色、Lucide 图标、Header 微渐变、Tab 滑动指示器、分类图标

变化很明显:Header 有了 Wand2 图标和蓝紫微渐变背景,Tab 栏有了滑动指示器,每个分类标题前有了 Lucide 图标,卡片有了 hover scale + shadow 效果和 stagger 入场动画,Beta 和 Planned badge 从纯文字变成了图标+文字。

占位页 Before / After

占位页 Before
占位页 Before

升级前——⏳ emoji 提示

占位页 After
占位页 After

升级后——Clock 图标替代 emoji

404 页 Before / After

404 页 Before
404 页 Before

升级前——默认蓝数字

404 页 After
404 页 After

升级后——品牌色自动跟随 tokens.css 变更(没改一行代码)

404 页这个对比值得多说一句:NotFound.tsx 一行代码都没改,但颜色从默认蓝变成了品牌蓝紫。原因就是它用了 var(--color-primary-500) 这个 CSS 变量,tokens.css 里换了色值,404 页自动跟着变。这就是第 3 期搭 CSS 变量体系时埋下的福利。

6. Archive:归档 + spec 同步

执行 /opsx:archive

代码语言:markdown
复制
AI:Delta specs exist for a new capability (`visual-identity`) — no main spec exists yet. This is a pure ADD, so syncing will create `openspec/specs/visual-identity/spec.md` for the first time.

Sync needed: visual-identity (new) — no main spec exists
  → Will create: openspec/specs/visual-identity/spec.md
代码语言:markdown
复制
AI:## Archive Complete

**Change:** `ui-visual-polish`
**Archived to:** `openspec/changes/archive/2026-05-17-ui-visual-polish/`
**Specs:** Synced to main specs (`openspec/specs/visual-identity/spec.md`)

All artifacts complete. All tasks complete.

一个值得记录的点:delta specs 的同步。本期新增了 visual-identity 这个 capability,归档时 OpenSpec 自动检测到主 specs 目录下还没有对应的 spec 文件,于是创建了 openspec/specs/visual-identity/spec.md。这个自动同步省去了手动搬运的麻烦。

另外,第 4 期 archive 报了成功但文件实际没移走。这期归档前特意 ls openspec/changes/ 确认了一下——目录下只剩 archive/,坑已填。

7. Git Push

推送环节很简单,自然语言指令触发:

代码语言:markdown
复制
用户:请帮我推送到远程仓库
代码语言:markdown
复制
AI:已推送。从 `229e2a0` 到 `423723b`,main 分支已更新。

8. 回顾

template 改造实验的结论

先说结论:template 改造确实解决了格式问题。 标题、涉及文件、步骤描述都变了。

但比预期多了一个发现:TDD 五步的严格执行取决于变更类型。本期是视觉类变更,9 个任务组里没有一个是严格的「写失败测试 → 确认失败 → 写最小实现 → 确认通过 → 提交」循环。实际更接近「改代码 → 跑测试确认没坏」的回归测试模式。review.md 也指出了这一点,标了 ⚠️。

所以更精确的结论是:template 管格式不管颗粒度。 格式是结构性的,可以靠 template 解决——从 ## 1. 变成 ### 任务 N:、加上涉及文件列表、给每个步骤配代码块,这些 template 一改就生效。但颗粒度是内容性的,取决于你改什么——视觉类变更天然难以拆出独立的「失败测试」,而纯逻辑变更(比如第 2 期的工具注册中心)就更适合走 TDD 节奏。

这对前传说过的「2/8 法则」是一个重要补充。改 instruction 占 20% 投入获 80% 质量提升,解决的是内容层面的问题——任务描述更具体了,占位符少了,代码块完整了。但那 80% 的质量提升里可能有结构性缺陷——格式始终不对。改 template 是补上这一块的正确手段。

说得更直白:你在 schema.yaml 里写的 instruction,AI 看了。但它身边的 template 格式暗示更强,AI 跟 template 走了。 这不是 bug,是 LLM 的特性——对具体示例的遵循度高于对文字描述的遵循度。

这个结论不仅适用于 OpenSpec,也适用于任何「prompt + template」模式的 AI 工具。你在设计配置的时候,template 和 instruction 要对齐——你想让 AI 输出什么格式,template 就长什么样。

视觉升级的效果

配色从 Tailwind 默认蓝 #3B82F6 换成了蓝紫 #8B5CF6,辨识度高了不少。图标系统用 Lucide 搭好了,4 个分类各有专属图标,badge 从纯文字变成图标+文字。Header 有了微渐变和 Wand2 图标。Tab 有了滑动指示器。卡片有了 hover scale + shadow + stagger 入场动画。

整体从「脚手架」升级到了有品牌感的「产品」。第 3 期搭的 CSS 变量体系和第 4 期搭的布局骨架,在这期真正发挥了作用——变量体系让换色变成改一行值的事,布局骨架让新增 UI 层不需要动结构。

对 OpenSpec 用户的启发

如果你也在用 OpenSpec,而且发现改了 instruction 但 AI 产出的格式始终没变,检查一下 template。template 文件在 openspec/schemas/<schema-name>/templates/ 目录下,每个工件类型都有一个对应的 .md 文件。改 instruction 管内容,改 template 管格式——这两件事是独立的。

你有没有遇到过类似的情况——改了配置但 AI 就是不听?评论区说说,看看是不是同一个原因。

9. 下期预告

根据系列规划,第 6 期主题是「工具市场 + 搜索/筛选」。

如果本期 template 改造效果明显,第 6 期会是第二次验证——连续两期都用新 template 生成 tasks.md,看效果是否稳定。一次生效可能是巧合,两次都生效才能说明改 template 是可靠的策略。

视觉层面,本期做完后页面已经从「脚手架」升级到有品牌感的「产品」。第 6 期可以聚焦功能层——给工具列表加上搜索和筛选,让用户不只是按分类浏览,还能按关键词快速找到目标工具。


相关资源

OpenSpec GitHub:https://github.com/shuge-x/shuge-ai-toolbox

好啦,谢谢你观看我的文章,如果喜欢可以点赞转发给需要的朋友,我们下一期再见!敬请期待!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • OpenSpec 项目实战(五) | UI 视觉打磨 + 改 template 让 AI 写出规范任务
    • 1. 视觉要升级,但更重要的是一个实验
    • 2. 为什么前 4 期的 tasks.md 格式都不对
      • 根因分析:template 的优先级高于 instruction
      • 改造方案:直接改 template
      • 当前项目状态
    • 3. Explore → Propose:从需求澄清到 5 个工件一步到位
      • 多轮对话:确认视觉升级方向
      • Design Doc + 自动生成 5 个工件
      • template 改造效果:格式变了
    • 4. Apply:33 步全量执行 + 三个小插曲
      • 三个小插曲
      • Apply 完成报告
      • 关键文件变更摘要
    • 5. Verify:构建通过 + 30 测试全过 + 视觉对比
      • 构建和测试
      • Before / After 视觉对比
    • 6. Archive:归档 + spec 同步
    • 7. Git Push
    • 8. 回顾
      • template 改造实验的结论
      • 视觉升级的效果
      • 对 OpenSpec 用户的启发
    • 9. 下期预告
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档