Real Terminal TUI Harness
real-terminal harness 在一个子进程中启动 OpenTUI 聊天界面,在 tmux 可用时通过
tmux 驱动它,必要时回退到 PTY,并将证据存储在
.artifacts/tui-real-terminal/runs 下。
Platform requirements
该 harness 运行在类 Unix 的终端环境中。Linux 和 macOS 可以直接运行它。Windows
用户需要 WSL2,因为该 harness 依赖 Unix 终端原语。它在 tmux 可用时优先使用 tmux,
并在缺少 tmux 时回退到 Unix 伪终端(Python 的 pty module)。
- Linux 和 macOS 可以使用 tmux 或 PTY 回退来运行确定性套件。
- 不支持原生 Windows shell,例如 PowerShell 和
cmd.exe:Python 的ptymodule 仅限 Unix,而 tmux 没有原生的 Windows 构建。 - WSL2 仅作为 Windows 的兼容路径被提及;在 WSL2 内部,这就是 Linux 路径本身。
当你想使用 tmux driver 时安装 tmux:
# Debian/Ubuntu Linux, including WSL2:
sudo apt-get update && sudo apt-get install -y tmux
# macOS:
brew install tmux
仅限 Windows 的设置:
# In an elevated PowerShell, once:
wsl --install # installs WSL2 + a default Ubuntu distro
# Then inside the WSL2 shell:
sudo apt-get update && sudo apt-get install -y tmux
uv run pytest tests/integration/cli/tui_real_terminal -q
当 tmux 与 PTY 都不可用时(例如原生 Windows CI),
probe_terminal_capabilities() 会报告 preferred_driver="none",并且每个
scenario 测试都会以一个命名了缺失能力的 pytest.skip 原因被跳过——该运行不会
失败。纯逻辑 driver、capability-probe 与 scenario-model 单元测试在每个平台上都会
运行。
Commands
Fast smoke:
uv run pytest tests/integration/cli/tui_real_terminal/test_launch_input_loop.py -q
Full deterministic suite:
uv run pytest tests/integration/cli/tui_real_terminal -q
Development packaged-host gate
在任何未来的分发 rollout 之前,maintainers 可以在一个干净的环境中,从仅包含已构建
的 core 和 companion wheels 以及测试依赖的状态下,于原生 macOS 和 Linux runners 上
本地重跑确定性的 OpenTUI scenarios。这个 gate 当前没有接线到正式的 v* release
工作流,也不发布资产。它会清除 PYTHONPATH、source-host override 以及 PATH 中
的 Bun,强制使用 tmux driver,并传递 --tui-require-capabilities;因此一个缺失的
终端能力是一个失败而不是一个跳过。它覆盖 launch/input、CJK、长 streaming、复杂的
tool UI、架构 replay、resize 和多行粘贴、补全 overlays 以及 primary-screen/shell
恢复。
同一个矩阵还会运行 test_packaged_gateway_e2e.py。那个 scenario 不使用
fake_opentui_app.py:它启动一个无鉴权的 loopback Gateway 加一个确定性 provider,
通过 GatewayClient 创建一个 session,上传一个小附件,并通过已安装的
opensquilla chat --ui tui --session 命令和已安装的 companion host 恢复该 session。
第二个 Gateway 客户端充当 Web surface。该 scenario 证明规范历史和附件 hydration、
Web 到 TUI 的 turn 投影、first-valid approval 收敛、排队 turn 的取消、alternate
-screen 恢复,以及退出后一个可用的回显 shell。
Scenario frames、scrollback、终端日志、结果文件、pytest 输出和 JUnit 输出都会作为
开发证据被保留,包括在失败时。真实 Gateway scenario 还额外保留 Gateway 日志、
provider 生命周期 JSONL、RPC/event snapshots、已安装的 core/companion/host 版本
溯源,以及一个显式的 fake_opentui_app: false 断言。正常的开发者运行会保持现有的
能力感知跳过行为,除非它们显式传递 --tui-require-capabilities。
Manual lab:
uv run python scripts/tui_real_terminal_lab.py --scenario long_streaming --backend opentui
通过开发全屏 renderer 运行架构 scenario:
uv run --extra dev python scripts/tui_real_terminal_lab.py \
--scenario architecture_prompt --backend opentui --driver tmux
OpenTUI backend path:
uv run pytest tests/integration/cli/tui_real_terminal -q --tui-backend opentui
确定性的样式化 framebuffer 视觉矩阵(在每个尺寸上直接冷启动,并带 cursor 和固定层 所有权检查):
uv run pytest \
tests/integration/cli/tui_real_terminal/test_visual_layout_matrix.py -q \
--tui-backend opentui --tui-driver tmux --tui-require-capabilities
这个 gate 在 80×24、120×30 和 160×40 检查终端单元格及其已解析的 RGB 样式。它断言 一个 header/logo/footer/composer、一个位于 composer 内的 cursor、footer 行中没有 transcript 绘制,以及连贯的窄/宽 rail 几何。它有意与字体无关;screenshots 仍作为 证据,而样式化 framebuffer 是阻塞性的视觉 oracle。
opentui backend 通过 real-terminal harness 运行确定性的 fake-provider apps。
存在一个受保护的 live-opentui backend,用于手动的真实 CLI smoke 检查:
OPENSQUILLA_TUI_LIVE_REAL=1 uv run pytest \
tests/integration/cli/tui_real_terminal/test_live_opentui_real_cli.py -q \
--tui-backend live-opentui --tui-driver tmux
OPENSQUILLA_TUI_LIVE_REAL=1 uv run python scripts/tui_real_terminal_lab.py \
--scenario live_opentui_architecture_prompt --backend live-opentui
该 live smoke 启动裸的 opensquilla chat --standalone,通过 tmux 驱动默认的
auto 策略,发送一个真实 prompt,并捕获文本证据。请谨慎使用它,因为它可能会命中
已配置的 live provider。
Evidence
每次运行都会写入:
scenario.jsonterminal.logapp.logtranscript.txtframes/*.txtscreenshots/result.jsonvisual-verdict.json
打包的 Gateway scenario 还会写入 gateway.log、provider-events.jsonl 和
gateway-rpc-events.json。
能力缺失在正常的开发者运行中是显式的跳过,而在开发 packaged-host gate 设置了
--tui-require-capabilities 时是硬失败。确定性的断言失败会阻塞。带 inspect 的
visual verdicts 在不阻塞无关 backend 变更的情况下保留证据。