---
date: "2026-06-13"
status: active
origin: docs/brainstorms/2026-06-13-gui-productization-requirements.md
---

## Summary

对 Fischer AgentKit GUI 进行产品级提升，三线并行：布局重构为「左对话 + 右双栏」、建立双主题设计系统、增强交互体验。分 3 个迭代交付。

## Problem Frame

当前 GUI 处于"功能可用但体验粗糙"状态：四象限等分布局让对话空间被压缩到 1/4 屏幕；Design Token 体系仅覆盖浅色主题，暗色主题缺失；无过渡动画、操作无反馈、空状态单调。需要从布局、视觉、交互三个维度全面提升到产品级。

## Key Technical Decisions

**KTD-1. 暗色主题通过 `[data-theme="dark"]` 选择器切换，而非独立 CSS 文件。**

现有 `tokens.css` 在 `:root` 上定义了约 80 个 token。暗色主题在 `[data-theme="dark"]` 选择器上覆盖同名变量，切换时只需修改 `document.documentElement.dataset.theme`。这保持了 CSS 变量为唯一真实来源，Ant Design Vue 主题通过 `readToken()` 运行时自动跟随。无需引入 CSS-in-JS 主题切换或独立 CSS 文件。

**KTD-2. 布局重构通过调整 AgentLayout 的 SplitPane 嵌套结构实现，不修改子视图。**

当前 AgentLayout 使用三层 SplitPane 嵌套（水平 → 左侧垂直 + 右侧垂直）。重构为两层：水平（左对话 + 右侧）→ 右侧垂直（右上 + 右下）。左侧不再嵌套垂直 SplitPane，ChatView 直接占满左半屏。所有子视图（ChatView、WorkflowView、EvolutionView 等）代码零修改。

**KTD-3. 侧边导航改为 32px 图标模式，复用现有 QuadrantPanel 的 Tab 切换机制。**

点击导航图标时调用 QuadrantPanel 的 `setActiveTab()` 方法切换 Tab 并展开面板。导航状态通过 `activeNav` ref 与 QuadrantPanel 的 `activeTab` 双向同步。不引入新的路由机制。

**KTD-4. 交互增强使用 Vue 3 内置 `<Transition>` 和 `<TransitionGroup>`，配合现有 `transitions.css` 定义的动画类。**

现有 `transitions.css` 已定义 7 种动画类（fade、slide-up、slide-down、slide-right、collapse、scale、stagger-list）和 3 种关键帧动画（skeleton-pulse、pulse-dot、gentle-bounce）。交互增强直接复用这些动画类，不引入第三方动画库。

---

## High-Level Technical Design

```mermaid
flowchart LR
    subgraph Layout["布局重构"]
        HSplit["水平 SplitPane<br/>55:45"]
        Left["左半屏<br/>ChatView"]
        Right["右半屏"]
        VSplit["垂直 SplitPane<br/>60:40"]
        TR["右上面板<br/>代码/工作流/知识库"]
        BR["右下面板<br/>监控/技能/设置"]
        Left --> HSplit
        Right --> HSplit
        TR --> VSplit
        BR --> VSplit
        VSplit --> Right
    end

    subgraph Theme["双主题"]
        Light["浅色 Token<br/>:root"]
        Dark["暗色 Token<br/>[data-theme=dark]"]
        Toggle["TopNav 切换按钮"]
        Toggle --> Light
        Toggle --> Dark
    end

    subgraph Interaction["交互增强"]
        Anim["过渡动画<br/>Transition 组件"]
        Feedback["操作反馈<br/>骨架屏/Toast"]
        Empty["空状态<br/>品牌化插图"]
        Drag["拖拽增强<br/>比例提示"]
    end
```

---

## Requirements Traceability

| Origin R-ID | Plan Coverage |
|---|---|
| R1. 左对话 + 右双栏布局 | U1 |
| R2. 面板折叠为 Tab 栏 | U1 (QuadrantPanel 已支持，调整默认行为) |
| R3. 侧边导航精简为图标模式 | U2 |
| R4. Design Token 体系基础 | U3 (已有基础，补充暗色 token) |
| R5. 小屏幕适配 | U1 (调整 responsive.css 断点) |
| R6. 暗色主题 | U3 |
| R7. 组件样式统一 | U4 |
| R8. 过渡动画 | U5 |
| R9. 操作反馈 | U6 |
| R10. 空状态设计 | U7 |
| R11. 拖拽交互增强 | U8 |

---

## Implementation Units

### 迭代 1：布局骨架 + 暗色主题

### U1. AgentLayout 布局重构

**Goal:** 将四象限等分布局重构为「左对话 + 右双栏」布局。

**Requirements:** R1, R2, R5

**Dependencies:** 无

**Files:**
- `src/agentkit/server/frontend/src/components/layout/AgentLayout.vue` (修改)
- `src/agentkit/server/frontend/src/styles/responsive.css` (修改)
- `src/agentkit/server/frontend/src/router/index.ts` (修改)

**Approach:**
- 修改 AgentLayout 的 SplitPane 嵌套结构：移除左侧垂直 SplitPane，ChatView 直接作为水平 SplitPane 的 first slot
- 右侧保留垂直 SplitPane（右上 + 右下），与当前相同
- 调整水平 SplitPane 默认比例为 55:45（左:右）
- 调整路由：移除 `agent-terminal` 路由（终端不再作为独立象限），终端功能可通过右侧面板 Tab 访问
- 调整 responsive.css 断点：小屏幕阈值从 1280px 调整为 1024px
- QuadrantPanel 的折叠功能已实现，无需修改

**Patterns to follow:** 现有 SplitPane + QuadrantPanel 嵌套模式

**Test scenarios:**
- 页面加载后左半屏显示 ChatView，右半屏上下分割为代码/工作流和监控
- 左右分割线可拖拽，默认比例 55:45
- 右侧上下分割线可拖拽，默认比例 60:40
- 分割比例保存到 localStorage，刷新后恢复
- 右上面板可折叠为 Tab 栏
- 右下面板可折叠为 Tab 栏
- 两个面板同时折叠后对话面板获得最大空间
- 屏幕宽度 < 1024px 时显示小屏幕提示
- 旧路由 `/terminal` 重定向正确

**Verification:** 打开 GUI 后左半屏是对话，右半屏上下分割，拖拽和折叠功能正常

### U2. 侧边导航精简为图标模式

**Goal:** 将侧边导航精简为 32px 宽的图标导航，点击切换右侧面板 Tab。

**Requirements:** R3

**Dependencies:** U1

**Files:**
- `src/agentkit/server/frontend/src/components/layout/AgentLayout.vue` (修改)
- `src/agentkit/server/frontend/src/components/layout/TopNav.vue` (修改)

**Approach:**
- 在 AgentLayout 的水平 SplitPane 之前添加 32px 宽的图标导航栏
- 导航项：对话（MessageOutlined）、工作流（ApartmentOutlined）、知识库（BookOutlined）、技能（AppstoreOutlined）、监控（DashboardOutlined）、设置（SettingOutlined）
- 点击导航图标时调用对应 QuadrantPanel 的 `setActiveTab()` 方法并展开面板
- 当前激活的导航图标高亮显示（使用 `--color-primary`）
- TopNav 添加导航栏折叠/展开按钮
- 导航栏折叠时宽度为 0px，展开时为 32px
- 导航状态与路由同步

**Patterns to follow:** QuadrantPanel 的 `setActiveTab()` 方法

**Test scenarios:**
- 导航栏显示 6 个图标，宽度 32px
- 点击「工作流」图标 → 右上面板切换到工作流 Tab 并展开
- 点击「监控」图标 → 右下面板切换到监控 Tab 并展开
- 点击「对话」图标 → 聚焦左侧对话面板
- 当前激活图标高亮
- TopNav 按钮可折叠/展开导航栏
- 折叠后导航栏宽度为 0px

**Verification:** 导航栏图标可切换右侧面板内容，折叠/展开正常

### U3. 暗色主题 Token 定义与切换

**Goal:** 在现有浅色 Token 基础上新增暗色主题 Token，支持一键切换。

**Requirements:** R4, R6

**Dependencies:** 无

**Files:**
- `src/agentkit/server/frontend/src/styles/tokens.css` (修改 — 添加 `[data-theme="dark"]` 块)
- `src/agentkit/server/frontend/src/styles/theme.ts` (修改 — 暗色主题 Ant Design 映射)
- `src/agentkit/server/frontend/src/components/layout/TopNav.vue` (修改 — 添加主题切换按钮)
- `src/agentkit/server/frontend/src/stores/theme.ts` (新建 — 主题状态管理)

**Approach:**
- 在 `tokens.css` 末尾添加 `[data-theme="dark"]` 选择器块，覆盖所有颜色相关 token（背景、文本、边框、主色、语义色、灰色阶、代码色）
- 暗色主题配色：深色背景（#1a1a2e 系列）、荧光强调色（保持 Indigo 主色但调亮）、终端原生感
- 新建 `stores/theme.ts`：管理主题状态（`light`/`dark`），切换时修改 `document.documentElement.dataset.theme`，偏好保存到 localStorage
- TopNav 添加太阳/月亮图标切换按钮
- `theme.ts` 中的 `readToken()` 已在运行时从 CSS 变量读取，暗色 token 覆盖后 Ant Design 主题自动跟随

**Patterns to follow:** 现有 `tokens.css` 的 `:root` 定义模式，`theme.ts` 的 `readToken()` 模式

**Test scenarios:**
- 点击 TopNav 月亮图标 → 界面切换到暗色主题
- 点击太阳图标 → 切换回浅色主题
- 暗色主题下所有组件正常显示（文字可读、边框可见、按钮可点击）
- 暗色主题下 Ant Design 组件（按钮、输入框、下拉框、模态框）正常显示
- 主题偏好保存到 localStorage，刷新后保持
- 代码块在暗色主题下使用暗色代码配色

**Verification:** 主题切换按钮可用，两种主题下所有界面元素正常显示

---

### 迭代 2：组件样式统一

### U4. 组件样式统一与 Ant Design 覆盖清理

**Goal:** 所有组件统一引用 Design Token，清理 App.vue 中的 `!important` 覆盖。

**Requirements:** R7

**Dependencies:** U3

**Files:**
- `src/agentkit/server/frontend/src/App.vue` (修改 — 清理全局覆盖)
- `src/agentkit/server/frontend/src/components/layout/SideNav.vue` (修改 — 迁移到 token)
- `src/agentkit/server/frontend/src/styles/theme.ts` (修改 — 增强组件级 token 映射)
- 各组件 scoped 样式中的硬编码值 (修改 — 替换为 token 引用)

**Approach:**
- 将 App.vue 中的 `.ant-btn`、`.ant-card` 等全局覆盖迁移到 `theme.ts` 的组件级 token 映射中，消除 `!important`
- SideNav.vue 的硬编码 `rgba()` 值替换为 token 引用
- 扫描所有组件 scoped 样式中的硬编码颜色/间距值，替换为 token 引用
- 主色统一为 `--color-primary`（消除 `#1677ff`/`#1890ff` 残留）

**Patterns to follow:** `theme.ts` 的组件级 token 映射模式

**Test scenarios:**
- App.vue 中无 `!important` 覆盖
- 所有组件 scoped 样式中无硬编码颜色值
- 浅色和暗色主题下所有组件样式一致
- Ant Design 组件（按钮、卡片、标签、模态框、选择框）圆角和间距统一

**Verification:** 搜索代码中无硬编码颜色值（除 token 定义文件外），两种主题下样式一致

---

### 迭代 3：交互增强

### U5. 过渡动画

**Goal:** 为所有交互添加过渡动画。

**Requirements:** R8

**Dependencies:** U1

**Files:**
- `src/agentkit/server/frontend/src/components/layout/QuadrantPanel.vue` (修改 — 折叠/展开动画)
- `src/agentkit/server/frontend/src/components/layout/AgentLayout.vue` (修改 — Tab 切换动画)
- `src/agentkit/server/frontend/src/views/ChatView.vue` (修改 — 消息列表动画)
- `src/agentkit/server/frontend/src/styles/transitions.css` (修改 — 如需新增动画类)

**Approach:**
- QuadrantPanel 折叠/展开：使用 Vue `<Transition>` 包裹 body 区域，应用 `collapse` 动画类
- Tab 切换：使用 Vue `<Transition>` 包裹 content 区域，应用 `fade` 动画类
- ChatView 消息列表：使用 `<TransitionGroup>` 包裹消息列表，应用 `stagger-list` 动画类
- 路由切换：使用 `<Transition>` 包裹 `<router-view>`，应用 `fade` 动画类

**Patterns to follow:** 现有 `transitions.css` 定义的动画类

**Test scenarios:**
- 面板折叠/展开有平滑过渡（200ms ease）
- Tab 切换有淡入淡出（150ms）
- 新消息出现有交错渐入效果
- 动画不影响操作响应速度

**Verification:** 所有交互有流畅的过渡动画，无生硬切换

### U6. 操作反馈

**Goal:** 为用户操作提供即时反馈。

**Requirements:** R9

**Dependencies:** U1

**Files:**
- `src/agentkit/server/frontend/src/components/common/AppToast.vue` (新建 — Toast 通知组件)
- `src/agentkit/server/frontend/src/components/common/SkeletonLoader.vue` (新建 — 骨架屏组件)
- `src/agentkit/server/frontend/src/components/layout/TopNav.vue` (修改 — WebSocket 断连横幅)
- `src/agentkit/server/frontend/src/stores/chat.ts` (修改 — 使用 Toast 替代错误提示)

**Approach:**
- 新建 AppToast 组件：基于 Ant Design Vue `message` API 封装，支持 success/error/warning/info 四种类型
- 新建 SkeletonLoader 组件：使用现有 `skeleton-pulse` 关键帧动画，支持不同形状（文本/卡片/列表）
- TopNav 添加 WebSocket 断连横幅：使用 `slide-down` 动画类
- chat.ts 中的错误提示从 `console.error` 改为 Toast 通知

**Patterns to follow:** 现有 `transitions.css` 的 `skeleton-pulse` 动画

**Test scenarios:**
- 操作成功时显示绿色 Toast 通知
- 操作失败时显示红色 Toast 通知
- 加载状态显示骨架屏而非 `<a-spin>`
- WebSocket 断连时顶部显示黄色横幅
- 重连后横幅自动消失

**Verification:** 所有操作有即时视觉反馈

### U7. 空状态设计

**Goal:** 为所有空状态提供品牌化插图和引导文案。

**Requirements:** R10

**Dependencies:** U1

**Files:**
- `src/agentkit/server/frontend/src/components/common/EmptyState.vue` (新建 — 通用空状态组件)
- `src/agentkit/server/frontend/src/views/ChatView.vue` (修改 — 对话空状态)
- `src/agentkit/server/frontend/src/views/WorkflowView.vue` (修改 — 工作流空状态)
- `src/agentkit/server/frontend/src/views/EvolutionView.vue` (修改 — 监控空状态)
- `src/agentkit/server/frontend/src/views/KnowledgeBaseView.vue` (修改 — 知识库空状态)
- `src/agentkit/server/frontend/src/views/SkillsView.vue` (修改 — 技能空状态)

**Approach:**
- 新建 EmptyState 通用组件：接受 icon（Ant Design 图标组件）、title、description、action（可选操作按钮）三个 props
- 各视图的空状态使用 EmptyState 组件替换当前的纯文字提示
- 对话空状态：MessageOutlined + "开始对话" + "输入消息与 Agent 交互"
- 工作流空状态：ApartmentOutlined + "创建工作流" + "拖拽节点构建自动化流程"
- 监控空状态：DashboardOutlined + "暂无监控数据" + "执行任务后数据将自动更新"
- 知识库空状态：BookOutlined + "添加知识源" + "上传文档或配置外部知识库"
- 技能空状态：AppstoreOutlined + "注册技能" + "通过 YAML 配置定义技能"

**Patterns to follow:** Ant Design Vue 的 `a-empty` 组件模式

**Test scenarios:**
- 新用户打开对话页面显示空状态引导
- 工作流列表为空时显示空状态引导
- 监控数据为空时显示空状态引导
- 空状态组件在浅色和暗色主题下正常显示

**Verification:** 所有空状态有品牌化插图和引导文案

### U8. 拖拽交互增强

**Goal:** 优化拖拽操作的视觉反馈。

**Requirements:** R11

**Dependencies:** U1

**Files:**
- `src/agentkit/server/frontend/src/components/layout/SplitPane.vue` (修改 — 拖拽比例提示)
- `src/agentkit/server/frontend/src/views/WorkflowView.vue` (修改 — 节点拖拽预览，如 FlowCanvas 支持)

**Approach:**
- SplitPane 拖拽时：在分割线旁显示当前比例百分比（如 "55%"），拖拽结束后淡出
- SplitPane 拖拽时：分割线高亮加粗（从 2px 到 4px），颜色从 `--border-color` 变为 `--color-primary`
- 工作流节点拖拽：如果 Vue Flow 支持自定义拖拽预览，添加放置预览指示

**Patterns to follow:** 现有 SplitPane 的拖拽处理模式

**Test scenarios:**
- 拖拽分割线时显示当前比例百分比
- 拖拽时分割线高亮加粗
- 拖拽结束后比例提示淡出
- 键盘调整分割线时也显示比例提示

**Verification:** 拖拽操作有清晰的视觉反馈

---

## Scope Boundaries

**Deferred to follow-up work:**
- 代码 Diff 查看器实现（右上「代码」Tab 仍为占位）
- Cmd+K 内联编辑
- @-mention 上下文引用
- 响应式移动端适配
- SideNav (Legacy) 组件迁移（AppLayout 保留作为回退）

**Outside this product's identity:**
- 多用户协作/实时协同编辑
- 插件市场
- 代码编辑器（只读预览）

---

## Risks & Dependencies

| Risk | Impact | Mitigation |
|------|--------|-----------|
| 暗色主题 token 覆盖不完整 | 部分组件在暗色下显示异常 | 逐组件验证，优先覆盖高频组件 |
| Ant Design Vue 4.x CSS-in-JS 主题跟随 | 暗色切换后 Ant 组件可能不跟随 | `readToken()` 运行时读取确保跟随，需验证 |
| 布局重构影响子视图高度计算 | 子视图内容溢出或空白 | 子视图使用 `height: 100%` + `overflow: auto` |
| 过渡动画性能 | 大量 DOM 操作时卡顿 | 使用 CSS transform/opacity 触发 GPU 加速 |
