1仕組みと動作原理
2ステップの分離がコアとなる手法です:まずテスト対象CLIの実シェル上で完全忠実なANSIを.ansiファイルに出力し、その後単独でPNGにレンダリングします。レンダラーにコマンドを実行させてはなりません。freezeの子ptyにより、deltaやlazygitが環境のデグレードを検知し、背景ブロック、行番号列、ヘッダー枠を暗黙的に破棄してしまうためです。
The single most important rule: **never let the renderer run the command for you.**
レンダリング側の2段階フォールバック:render_ansi.shはfreeze(charmbracelet、背景ブロックや行番号ボックスを忠実に再現)を優先し、見つからない場合はpython3 ansi2html.py(純粋なstdlibによるANSI→HTML)+ ヘッドレスChromeによるスクリーンショットへフォールバックします。
# Prefers charmbracelet/freeze (faithful background blocks, line-number boxes, # window chrome). Falls back to a zero-dependency stdlib HTML renderer + # headless Chrome when freeze is not installed.
ansi2html.pyは実際のCLIが出力するSGRサブセットのみを処理します:24ビットtruecolor(38;2;r;g;b / 48;2;r;g;b)、256色(38;5;n + xtermパレットマッピング)、bold、reset(0/39/49)。背景色ブロック(deltaの追加・削除背景色)を忠実に保持することが重要であり、テキストはインジェクションを防ぐためすべてhtml.escapeを通します。
Background color blocks (48;...) are preserved faithfully — that is the whole point, since tools like delta encode add/remove as background blocks.
背景色は実際のターミナルと一致させる必要があります。一致しない場合、白背景上のダークテーマでコントラストを誤判定します。SKILLにはmacOS Ghosttyの背景色取得コマンドと一般的なデフォルト値(#282c34/#1d1f21)が記載されています。
**Background color must match the real terminal**, or a dark theme verified on a white page looks wrong.
TUIプログラム(lazygit/htop/top)は明示的に対象外と定義されています:これらは線形なANSIストリームではなくカーソル位置指定を用いて全画面を描画するため、本手法でのキャプチャは不可能です。色の検証には基盤となるレイヤーを切り出す必要があります(例:lazygitのdiff表示にはdeltaの設定を使用)。
## TUI programs (lazygit, htop, top) — out of scope
レンダリング結果はエージェントがRead/画像ツールを用いて読み戻し、視覚的な判断を行います。「16進数による色推測」を「実際のレンダリング結果におけるコントラスト、配置、背景ブロックの確認」へと置き換えます。
Then read the PNG with the Read tool and judge the colors.
2コア機能
3外部依存関係
| Kind | Dependency / Endpoint |
|---|---|
| cli | freeze(charmbracelet/freeze,首选渲染器,可选) |
| cli | Google Chrome(无头模式,回退渲染路径;路径硬编码 macOS) |
| cli | python3(ansi2html.py 运行环境,纯 stdlib) |
| cli | go/brew(仅安装 freeze 时的可选项) |
4推奨統制措置と判定根拠
- scripts/: ローカルスクリプトまたはコマンドの実行: render_ansi.sh(bash、set -euo pipefail):freezeまたはpython3 ansi2html.py + Chromeヘッドレスを実行
- 网络端点: 外部ネットワークアクセスの宣言: なし(スクリプト内でのネットワーク呼び出しはゼロ。freezeのインストールコマンドはユーザー主導の操作であり、go moduleミラー経由が可能)
- 本地工作目录: ファイルの読み書きと成果物の出力: ユーザー指定のパスにoutput.png(およびフォールバックパスの中間ファイルoutput.html)を出力。入力となる.ansiはキャプチャ工程でユーザー自身が/tmp等に保存
5二重目の独立検証
- [ok] 文本是否先转义再进 HTML(防注入) — ansi2html.py 'esc = H.escape(p)' 后拼入 span/裸文本;输出文档无其他用户可控拼接。
- [ok] Chrome --no-sandbox 与降级面 — render_ansi.sh 回退路径含 --no-sandbox;渲染对象为本地生成、已转义的 HTML;freeze 存在时该路径不触发。
- [ok] 无网络外发/凭证读取 — 两脚本无 curl/wget/http/url/env 密钥访问;go install 仅出现在 SKILL.md 安装指引(用户主动)。
- [ok] SKILL 声称的每工具捕获配方 — 配方表为文档层指引(agent 在 shell 执行),脚本不含这些 CLI 调用,无隐藏依赖。
- [ok] TUI 边界声明与实现一致 — SKILL 明确 TUI 光标定位无法线性捕获;脚本只处理线性 ANSI 流输入。
- [unlocatable] freeze/Chrome 实际渲染保真度 — 依赖外部渲染器行为(背景块/行号盒/字体度量),本环境未实装 freeze/Chrome,未做端到端截图验证。
6結論
f71128c440db3c5b…