终端界面验证助手Skill tui-validate

此技能专门用于验证终端用户界面(TUI)的输出,通过集成freeze工具捕获屏幕截图,并利用LLM作为评判进行语义验证,支持PNG/SVG视觉验证和文本验证模式,适用于TUI应用的测试、视觉回归测试和文档生成。关键词:TUI验证、终端界面、语义验证、LLM评判、测试自动化、视觉回归测试。

测试 0 次安装 0 次浏览 更新于 3/14/2026

name: tui-validate description: 使用freeze捕获屏幕截图和LLM-as-judge进行语义验证来验证终端用户界面(TUI)输出。支持视觉(PNG/SVG)和基于文本的验证模式。 type: anthropic-skill version: “1.0”

TUI 验证

概述

此技能通过捕获终端用户界面(TUI)应用程序的输出并使用LLM-as-judge进行语义验证来验证TUI应用程序。它利用Charmbracelet的freeze工具进行高保真终端屏幕截图,并提供结构化验证标准。

理念:与脆弱的字符串匹配不同,此技能使用语义理解来验证TUI输出“看起来正确”——检查布局、内容存在性和视觉层次结构,而不会因小的格式更改而中断。

使用时机

  • 验证更改后的TUI渲染
  • 检查UI组件是否显示正确
  • 终端应用程序的视觉回归测试
  • 验证特定交互后的TUI状态
  • 创建带有验证的文档屏幕截图

前提条件

必需:

  • 安装freeze CLI工具(brew install charmbracelet/tap/freeze
  • tmux用于交互式TUI捕获(可选,用于实时应用程序)

验证:

# 检查freeze是否安装
freeze --version

# 检查tmux是否安装(用于交互式捕获)
tmux -V

参数

  • target(必需):要验证的目标。可选:

    • file:<路径> - 要验证的ANSI输出文件
    • command:<命令> - 要执行并捕获的命令
    • tmux:<会话> - 要捕获的实时tmux会话
    • buffer:<文本> - 要验证的原始文本/ANSI
  • criteria(必需):验证标准。可以是:

    • 预定义标准名称(见内置标准)
    • 描述要检查内容的自定义标准字符串
  • output_format(可选,默认:“svg”):屏幕截图格式

    • svg - 矢量格式,最适合文档
    • png - 栅格格式,最适合视觉差异
    • text - 仅文本提取,最快
  • save_screenshot(可选,默认:false):是否保存屏幕截图

    • 如果为true,保存到当前目录的{target_name}.{format}
  • judge_mode(可选,默认:“semantic”):验证方法

    • semantic - LLM基于含义和布局评判
    • strict - 还检查确切内容存在性
    • visual - 需要PNG,检查视觉外观

内置标准

ralph-header

验证Ralph TUI头部组件:

  • 迭代计数器以[iter N][iter N/M]格式显示
  • MM:SS格式显示已用时间
  • 带表情符号和名称的帽子指示器
  • 模式指示器(▶ auto⏸ paused
  • 可选滚动模式指示器[SCROLL]
  • 可选空闲倒计时idle: Ns

ralph-footer

验证Ralph TUI底部组件:

  • 活动指示器(◉ active◯ idle■ done
  • 最后事件主题显示
  • 搜索模式显示(当活动时)

ralph-full

验证完整Ralph TUI布局:

  • 顶部头部部分(3行)
  • 终端内容区域(可变高度)
  • 底部底部部分(3行)
  • 适当的视觉层次结构和边框

tui-basic

通用TUI验证:

  • 有可见内容(非空白)
  • 无渲染伪影或损坏字符
  • 适当的终端尺寸

执行流程

1. 捕获阶段

基于目标类型捕获TUI输出:

对于文件目标:

freeze {file_path} -o /tmp/tui-capture.{format}

对于命令目标:

freeze --execute "{command}" -o /tmp/tui-capture.{format}

对于tmux目标:

tmux capture-pane -pet {session} | freeze -o /tmp/tui-capture.{format}

对于缓冲区目标:

echo "{buffer}" | freeze -o /tmp/tui-capture.{format}

约束:

  • 在尝试捕获之前,您必须验证freeze是否安装
  • 您必须优雅地处理捕获失败并报告错误
  • 您必须使用适当的freeze标志用于输出格式
  • 您应该使用--theme base16以实现一致渲染
  • 您应该使用--width--height设置合理尺寸

2. 提取阶段

为LLM分析提取内容:

对于文本/语义验证:

  • 如果格式为text,直接使用捕获的文本
  • 如果格式为svgpng,还捕获文本版本用于内容分析

对于视觉验证:

  • 需要PNG格式
  • 将直接使用视觉能力分析图像

约束:

  • 当judge_mode为visual时,您必须提取视觉和文本表示
  • 当相关时,您必须保留ANSI转义序列用于颜色验证

3. 验证阶段

应用具有适当标准的LLM-as-judge:

语义验证提示模板:

分析此终端UI输出并确定它是否符合以下标准:

标准:
{criteria_description}

终端输出:
{captured_text}

评估每个标准并提供:
1. 每个要求的通过或失败
2. 任何失败的简要解释
3. 总体裁决:通过或失败

对确切格式宽松,但对以下严格:
- 所需内容存在性
- 逻辑布局和层次结构
- 无渲染错误或伪影

视觉验证提示模板(带图像):

检查此终端屏幕截图并验证:

标准:
{criteria_description}

检查:
1. 视觉层次结构和布局
2. 颜色编码正确性
3. 无渲染伪影或损坏字符
4. 适当对齐和间距

裁决:通过或失败,附带解释

约束:

  • 您必须返回清晰的通过或失败裁决
  • 您必须提供失败的具体反馈
  • 您必须对空白/格式差异宽松
  • 您必须对内容存在性和语义正确性严格
  • 您应该即使通过结果也注意任何警告

4. 报告阶段

报告验证结果:

当通过:

✅ TUI 验证通过

标准: {criteria_name}
目标: {target}
模式: {judge_mode}

所有要求满足。
{optional_notes}

当失败:

❌ TUI 验证失败

标准: {criteria_name}
目标: {target}
模式: {judge_mode}

发现问题:
- {issue_1}
- {issue_2}

屏幕截图保存: {path_if_saved}

约束:

  • 您必须始终提供清晰裁决
  • 您必须在失败时列出具体问题
  • 您必须提供屏幕截图路径(如果保存)
  • 您应该建议常见问题的修复

示例

示例1:从文件验证Ralph头部

输入:

/tui-validate file:test_output.txt criteria:ralph-header

过程:

  1. 读取包含ANSI输出的test_output.txt
  2. 使用freeze捕获:freeze test_output.txt -o /tmp/capture.svg
  3. 提取文本内容
  4. 通过LLM评判应用ralph-header标准
  5. 报告带有细节的通过/失败

示例2:验证tmux中的实时TUI

输入:

/tui-validate tmux:ralph-session criteria:ralph-full save_screenshot:true

过程:

  1. 捕获tmux窗格:tmux capture-pane -pet ralph-session | freeze -o ralph-session.svg
  2. 还捕获文本:tmux capture-pane -pet ralph-session > /tmp/text.txt
  3. 应用ralph-full标准检查头部、内容和底部
  4. 保存屏幕截图到ralph-session.svg
  5. 报告验证结果

示例3:自定义标准验证

输入:

/tui-validate command:"cargo run --example tui_demo" criteria:"显示带边框的框,内有居中文本'Hello World'" output_format:png judge_mode:visual

过程:

  1. 执行命令并捕获:freeze --execute "cargo run --example tui_demo" -o /tmp/capture.png
  2. 使用视觉模型分析PNG
  3. 检查边框框和居中文本
  4. 报告视觉验证结果

示例4:快速文本验证

输入:

/tui-validate buffer:"[iter 3/10] 04:32 | 🔨 Builder | ▶ auto" criteria:ralph-header output_format:text

过程:

  1. 直接分析文本(文本模式缓冲区无需freeze)
  2. 检查迭代格式、已用时间、帽子和模式指示器
  3. 报告验证结果

标准定义

ralph-header(完整定义)

name: ralph-header
description: Ralph TUI头部组件验证
requirements:
  - name: iteration_counter
    description: 以[iter N]或[iter N/M]格式显示迭代
    required: true
    pattern: '\[iter \d+(/\d+)?\]'

  - name: elapsed_time
    description: 以MM:SS格式显示已用时间
    required: true
    pattern: '\d{2}:\d{2}'

  - name: hat_indicator
    description: 显示带表情符号前缀的当前帽子
    required: true
    examples: ["🔨 Builder", "📋 Planner", "🎯 Executor"]

  - name: mode_indicator
    description: 显示循环模式状态
    required: true
    values: ["▶ auto", "⏸ paused"]

  - name: scroll_indicator
    description: 在滚动模式时显示[SCROLL]
    required: false
    pattern: '\[SCROLL\]'

  - name: idle_countdown
    description: 空闲超时时显示
    required: false
    pattern: 'idle: \d+s'

ralph-footer(完整定义)

name: ralph-footer
description: Ralph TUI底部组件验证
requirements:
  - name: activity_indicator
    description: 显示当前活动状态
    required: true
    values: ["◉ active", "◯ idle", "■ done"]

  - name: event_topic
    description: 显示最后事件主题
    required: false
    examples: ["task.start", "build.done", "loop.terminate"]

  - name: search_display
    description: 搜索时显示搜索查询和匹配计数
    required: false
    pattern: 'Search: .+ \d+/\d+'

ralph-full(完整定义)

name: ralph-full
description: 完整Ralph TUI布局验证
requirements:
  - name: header_section
    description: 顶部头部部分,含迭代、时间、帽子和模式
    required: true
    references: ralph-header

  - name: content_section
    description: 主要终端内容区域
    required: true
    checks:
      - 有可见内容或准备就绪用于内容
      - 正确界定在头部和底部之间

  - name: footer_section
    description: 底部底部部分,含活动状态
    required: true
    references: ralph-footer

  - name: visual_hierarchy
    description: 各部分间清晰视觉分隔
    required: true
    checks:
      - 各部分间边框或间距
      - 各部分一致宽度

故障排除

freeze未找到

# macOS
brew install charmbracelet/tap/freeze

# Linux(通过Go)
go install github.com/charmbracelet/freeze@latest

# 验证安装
freeze --version

tmux捕获失败

  • 确保tmux会话存在:tmux list-sessions
  • 验证窗格号:tmux list-panes -t {session}
  • 尝试捕获特定窗格:tmux capture-pane -pet {session}:{pane}

捕获中渲染伪影

  • 在freeze中尝试不同终端模拟器设置
  • 使用--theme标志以实现一致颜色
  • 确保终端尺寸匹配TUI预期

LLM评判过于严格/宽松

  • 调整标准以更具体
  • 对确切匹配要求使用strict模式
  • 对布局/存在性检查使用semantic模式

与测试集成

此技能可以集成到测试套件中:

// 在tests/tui_validation.rs中
#[test]
#[ignore] // 运行:cargo test -- --ignored
fn validate_header_rendering() {
    // 1. 渲染头部到缓冲区
    let output = render_header_to_string(&test_state);

    // 2. 保存到临时文件
    std::fs::write("/tmp/header_test.txt", &output).unwrap();

    // 3. 运行tui-validate技能(通过CLI或编程方式)
    // /tui-validate file:/tmp/header_test.txt criteria:ralph-header

    // 4. 断言验证通过
}

最佳实践

  1. 对布局检查使用语义验证 - 不要因小格式更改而中断
  2. 对内容要求使用严格验证 - 确保关键信息存在
  3. 失败时保存屏幕截图 - 帮助调试
  4. 使用各种终端尺寸测试 - TUI应响应式
  5. 与单元测试结合 - 将此用于集成/视觉验证,单元测试用于逻辑