Documentation

Step 15: UI 组件架构

分析日期: 2026-04-16 核心目录: src/components/ (~100+ 文件), src/screens/ (3 文件)


1. 组件树图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
App (src/components/App.tsx)
  |-- FpsMetricsProvider
  |     |-- StatsProvider
  |           |-- AppStateProvider
  |                 |-- <children> (REPL 屏幕)
  |
REPL (src/screens/REPL.tsx)
  |-- FullscreenLayout
  |     |-- scrollable:
  |     |     |-- LogoHeader (memoized)
  |     |     |     |-- LogoV2
  |     |     |     |-- StatusNotices
  |     |     |
  |     |     |-- Messages  (OR  VirtualMessageList)
  |     |           |-- Message (per message, switch-dispatched)
  |     |                 |-- [user/assistant/system/attachment/grouped/collapsed]
  |     |
  |     |-- bottom:
  |     |     |-- Spinner / BashModeProgress / ToolUseLoader
  |     |     |-- PermissionRequest (when toolUseConfirmQueue active)
  |     |     |-- PromptInput
  |     |           |-- ShimmeredInput
  |     |           |-- PromptInputFooter
  |     |           |     |-- PromptInputFooterLeftSide
  |     |           |     |-- PromptInputFooterSuggestions
  |     |           |     |-- Notifications
  |     |           |-- PromptInputHelpMenu
  |     |           |-- HistorySearchInput
  |     |           |-- VoiceIndicator
  |     |
  |     |-- overlay: (PermissionRequest when pending)
  |     |-- modal: (/config, /help 等斜杠命令面板)
  |     |-- bottomFloat: (伴游精灵气泡)

2. 组件类别表

核心布局

组件 文件 职责 关键 Hooks
App App.tsx 顶层包装;提供 FPS/stat/app state React Compiler runtime
FullscreenLayout FullscreenLayout.tsx 全屏终端布局:可滚动区 + 固定底部 + 覆盖层 + 模态槽 useUnseenDivider, useSyncExternalStore
ScrollKeybindingHandler ScrollKeybindingHandler.tsx 键盘驱动滚动 useKeybinding, useKeybindings
StatusLine StatusLine.tsx 底部状态栏 useAppState, useSettings
OffscreenFreeze OffscreenFreeze.tsx 防止离屏消息重渲染 React.memo

消息/转录

组件 文件 职责
Messages Messages.tsx 编排完整消息列表:规范化、分组、折叠、虚拟化、搜索
Message Message.tsx 每条消息调度器:按 type 切换到类型特定子组件
VirtualMessageList VirtualMessageList.tsx 全屏模式虚拟化滚动;useVirtualScroll, 高度缓存, 粘性提示追踪
MessageActions messageActions.tsx 每条消息导航光标、详细切换、选择状态

消息子组件 (30+ 类型特定渲染器)

类型 组件 渲染内容
assistant/text AssistantTextMessage Markdown + API 错误检测
assistant/tool_use AssistantToolUseMessage 工具进度、名称、输入预览
assistant/thinking AssistantThinkingMessage 思考块 (详细/转录模式可见)
user/text UserTextMessage 用户文本 + 计划内容
user/image UserImageMessage 粘贴图片
user/tool_result UserToolResultMessage 调度到 success/error/reject/canceled
system SystemTextMessage 系统消息
attachment AttachmentMessage 文件附件
grouped_tool_use GroupedToolUseContent 分组读/搜工具调用
collapsed_read_search CollapsedReadSearchContent 折叠读/搜内容

权限 (15+ 特定工具权限组件)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
PermissionRequest.tsx: permissionComponentForTool(tool)
    |
    +-- FileEditTool       --> FileEditPermissionRequest (diff 视图)
    +-- FileWriteTool       --> FileWritePermissionRequest (写入差异预览)
    +-- BashTool            --> BashPermissionRequest (命令显示)
    +-- PowerShellTool       --> PowerShellPermissionRequest
    +-- WebFetchTool        --> WebFetchPermissionRequest (URL 显示)
    +-- NotebookEditTool    --> NotebookEditPermissionRequest (单元格差异)
    +-- GlobTool/GrepTool/FileReadTool --> FilesystemPermissionRequest (文件路径)
    +-- EnterPlanModeTool   --> EnterPlanModePermissionRequest
    +-- ExitPlanModeV2Tool  --> ExitPlanModePermissionRequest
    +-- SkillTool           --> SkillPermissionRequest
    +-- AskUserQuestionTool --> AskUserQuestionPermissionRequest (多问题导航)
    +-- default             --> FallbackPermissionRequest

所有权限组件共享:

  • PermissionDialog: 圆角顶部边框 + 标题/副标题/worker 徽章
  • PermissionPrompt: Select 选项 + Tab 展开反馈输入 + 分析

Agent/任务

组件 文件 职责
BackgroundTask tasks/BackgroundTask.tsx 后台任务状态 (bash shell, 远程 agent, 进程内队友)
BackgroundTaskStatus tasks/BackgroundTaskStatus.tsx 聚合后台任务状态行
ShellProgress tasks/ShellProgress.tsx 实时 shell 进度
AsyncAgentDetailDialog tasks/AsyncAgentDetailDialog.tsx 异步 agent 详情
InProcessTeammateDetailDialog tasks/InProcessTeammateDetailDialog.tsx 进程内队友详情
DreamDetailDialog tasks/DreamDetailDialog.tsx Dream(推测)任务详情
AgentsList/AgentsMenu/AgentDetail/AgentEditor agents/ Agent 管理
CreateAgentWizard agents/new-agent-creation/ 多步创建向导

设置/配置

组件 文件 职责
Settings Settings/Settings.tsx /config 主面板
MCPSettings/MCPListPanel mcp/ MCP 服务器配置
SandboxSettings sandbox/ 沙箱配置
HooksConfigMenu hooks/ Hook 配置菜单
ThemePicker/ModelPicker 各自 主题/模型选择

设计系统

组件 文件 职责
ThemeProvider design-system/ThemeProvider.tsx 主题上下文;’auto’ -> OSC 11 检测
ThemedText design-system/ThemedText.tsx 主题感知文本组件
ThemedBox design-system/ThemedBox.tsx 主题感知盒子组件
Dialog design-system/Dialog.tsx 确认/取消对话框 + 键绑定
Pane design-system/Pane.tsx 斜杠命令内容面板
FuzzyPicker design-system/FuzzyPicker.tsx 模糊搜索选择器
KeyboardShortcutHint design-system/ 快捷键显示

Markdown/代码高亮

组件 文件 渲染策略
Markdown Markdown.tsx 混合渲染:表格用 React flexbox,其他用 ANSI 字符串;LRU token 缓存 (500 条)
StreamingMarkdown Markdown.tsx 流式优化:稳定前缀 memoized,不稳定后缀逐 delta 重解析
MarkdownTable MarkdownTable.tsx 表格用 React flexbox 组件
HighlightedCode HighlightedCode.tsx tree-sitter 语法高亮 (回退到 HighlightedCodeFallback)
StructuredDiff StructuredDiff.tsx 结构化差异显示 + tree-sitter 高亮

3. 消息渲染管线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
原始 API 消息 (Message[])
       |
       v
Messages.tsx: normalizeMessages() + reorderMessagesInUI()
       |-- collapseReadSearchGroups()
       |-- collapseBackgroundBashNotifications()
       |-- collapseHookSummaries()
       |-- collapseTeammateShutdowns()
       |-- applyGrouping()
       |-- buildMessageLookups()
       |-- filterForBriefTool() [if brief mode]
       |-- dropTextInBriefTurns() [if brief mode]
       |
       v
RenderableMessage[] (规范化、分组、折叠)
       |
       v
Messages.tsx: renderItem()
       |
       v
Message.tsx: switch(message.type)
       |
       +-- "user" --> UserMessage (param.type switch)
       |      +-- "text"         --> UserTextMessage
       |      +-- "image"        --> UserImageMessage
       |      +-- "tool_result"  --> UserToolResultMessage -> (success/error/reject/canceled)
       |      +-- (isCompactSummary) --> CompactSummary
       |
       +-- "assistant" --> map content blocks
       |      +-- "text"              --> AssistantTextMessage --> Markdown
       |      +-- "tool_use"          --> AssistantToolUseMessage
       |      +-- "thinking"          --> AssistantThinkingMessage
       |      +-- "redacted_thinking"  --> AssistantRedactedThinkingMessage
       |
       +-- "system" --> subtype switch
       |      +-- "compact_boundary"   --> CompactBoundaryMessage
       |      +-- "local_command"      --> UserTextMessage
       |      +-- default             --> SystemTextMessage
       |
       +-- "attachment" --> AttachmentMessage
       +-- "grouped_tool_use" --> GroupedToolUseContent
       +-- "collapsed_read_search" --> CollapsedReadSearchContent

Markdown 渲染:
  string content
       |-- stripPromptXMLTags()
       |-- cachedLexer() [LRU, 500条, hash 键控]
       |      |-- Fast path: 无 MD 语法 -> 单段 token
       |      |-- Hit: 返回缓存 token
       |      |-- Miss: marked.lexer() -> 缓存并返回
       |
       v
  MarkdownBody: 迭代 token
       +-- "table"  --> MarkdownTable (React flexbox)
       +-- other   --> formatToken() -> ANSI 字符串 -> <Ansi>

4. 权限对话框流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
工具执行需要权限
       |
       v
PermissionRequest.tsx: permissionComponentForTool(tool)
       |  (映射 Tool 类 -> 权限组件)
       v
特定权限组件 (如 BashPermissionRequest)
       |-- PermissionDialog (共享框架: 圆角边框、标题、副标题、worker 徽章)
       |-- PermissionPrompt (Select 选项 + Tab 反馈输入 + 分析)
       |-- 工具特定内容:
       |     +-- Bash: 命令显示、命令描述、选项 (allow/deny/always-allow)
       |     +-- FileEdit: diff 视图、文件路径
       |     +-- FileWrite: 写入差异预览
       |     +-- Filesystem: 文件路径显示
       |     +-- AskUserQuestion: 多问题导航、预览、提交
       |
       v
用户选择 --> PermissionDecision (allow/deny/always-allow/always-deny)
       |
       v
决策应用到工具执行管线

5. 关键架构观察

  1. React Compiler: 编译输出使用 react/compiler-runtime (_c()) 进行自动 memoization。几乎所有组件使用编译器缓存槽。

  2. 虚拟滚动: 全屏模式使用 VirtualMessageList + useVirtualScroll。非全屏模式使用普通 .map() + MAX_MESSAGES_WITHOUT_VIRTUALIZATION 上限。

  3. 消息规范化管线: 原始 API 消息经过多步管线:规范化、重排序、分组(读/搜折叠)、后台 Bash 折叠、hook 摘要折叠、队友关闭折叠、brief 模式过滤。

  4. Markdown 三层优化: (a) 无 MD 语法的快速路径跳过, (b) LRU token 缓存 (500 条, hash 键控), (c) 流式分割渲染(稳定前缀 memoized + 不稳定后缀逐 delta 重解析)。

  5. 权限调度模式: PermissionRequest.tsx 使用工具类到组件的映射函数,每个工具特定组件共享 PermissionDialog 框架和 PermissionPrompt 选项系统。

  6. FullscreenLayout 插槽: 5 个渲染插槽:scrollable(消息)、bottom(提示/旋转器)、overlay(权限请求)、modal(斜杠命令)、bottomFloat(伴游气泡)。

  7. REPL 作为编排器: REPL 屏幕 (screens/REPL.tsx) 是中央编排器,持有绝大多数应用状态。