vm-lab について
タスク専用の Parallels 仮想マシンで、GUI 自動化や macOS の動作をテストするスキルです。ツールの出力をホスト側のスクリーンショットやゲスト状態などと照合して検証します。
主な機能
- 01VM の状態とスナップショット由来の確認
- 02macOS ゲスト内でのコマンド実行
- 03ホスト側の参照スクリーンショット取得
- 04独立した信号による GUI 操作の検証
- 05権限とパフォーマンスの確認
活用シーン
- 01クリーンな VM での GUI 自動化テスト
- 02画面収録権限の検証
- 03ゲスト状態を用いたクリックと入力の確認
- 04ツールの画像とホスト側キャプチャの比較
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ steipete/ agent-scripts --skill vm-labインストール後、Claude Code で/vm-labを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
agents/openai.yamlreferences/bootstrap-diagnostics.mdscripts/parallels_type.py詳細
VM Lab
GUI 自動化、TCC プロンプト、スクリーンショットの撮影、クリック、入力、パフォーマンス、または Peekaboo のようなツールの「双方向検証」のテストにクリーンな macOS VM が必要な場合に使用します。
基本方針:テスト対象のツールはゲスト内で実行し、Parallels のスクリーンショットとホスト側の観察を使ってゲストの外から検証します。自分が所有していないアプリを終了しないでください。
安全ルール
- 破棄してよいのはタスク専用のクローンのみです。ソース/ゴールデンスナップショット、復旧用 VM、ほかのタスクの VM は保持し、スナップショットをリセット、復元、削除しないでください。
- クローンの起動準備のために、継承されたゲストの認証情報にアクセスしたり、ログイン/起動時のセキュリティを回避したりしないでください。
- シークレットを表示しないでください。
opが必要な場合は、1Password スキルに従い、tmux内でのみ実行してください。 - 自分で作成した新しいアプリウィンドウを優先してください。TextEdit、ローカルの HTML テストページ、小さなテストアプリなどを使用します。
- ホストへの書き込みは、タスク専用の一時的な診断データと、明示的に許可されたクローンの復旧のみに限定してください。ラボの回避策として、Bash/Codex のグローバル設定を変更しないでください。
- VM 内の Git リポジトリでは、HTTPS リモートと通常のブランチ運用を使用してください。
起動準備の事前確認
ゲストの自動化を始める前に、タスク専用 VM の正確な UUID とスナップショットの出所を確認してください。以下の名前は例であり、既存の VM を操作する許可を意味するものではありません。
- Apple-VZ クローンが起動しない場合は、クローンの作成成功や論理サイズだけでなく、アクティブな raw ディスクの内容を確認してください。スパースなリンク子ディスクだけでは、チェーンが壊れている証拠にはなりません。
clone --unlinkは別のクローンを作成するものであり、インプレース修復ではありません。 - 最初の出力が出る前にパッケージ作成が停止する場合は、製品コードやビルドガードを変更する前に、タスク専用のシェルプロセスと heredoc のリダイレクトを調べてください。system-Bash で再試行する場合、その呼び出しに限り、PATH から解決される子シェルも固定する必要があります。
読み取り専用の確認、証拠の限界、範囲を限定した復旧の境界については、起動準備の診断を使用してください。
VM の検出
VM の一覧を表示します。
prlctl list --all
VM のステータス/IP を取得します。
prlctl list --info "macOS Tahoe"
Peter としてゲストコマンドを実行します。
prlctl exec "macOS Tahoe" \
'sudo -u steipete -H /bin/zsh -lc '\''source ~/.zprofile 2>/dev/null || true; uname -a'\'''
独立したホスト側のスクリーンショットを撮影します。
prlctl capture "macOS Tahoe" --file /tmp/vm-reference.png
sips -g pixelWidth -g pixelHeight /tmp/vm-reference.png
TCC/GUI の帰属
macOS の画面収録とアクセシビリティでは、どのプロセスが要求元かが重要です。
prlctl execはヘッドレスであり、画面収録の適切な帰属情報を生成できないことがあります。- 画面収録が関係する場合は、ゲスト内の表示されているターミナルアプリからテストコマンドを起動してください。
- インストールされている場合、Ghostty は GUI ターミナルとして使用できます。
- 最初のキャプチャに失敗したら、
System Settings > Privacy & Security > Screen & System Audio Recordingを確認してください。 prlctl exec経由で実行したpermissions statusでは、Ghostty を許可した後も画面収録が false と報告されることがあります。Ghostty からキャプチャを再実行して、画面収録を検証してください。
画面収録パネルを開きます。
prlctl exec "macOS Tahoe" \
'sudo -u steipete -H open "x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture"'
Ghostty を開きます。
prlctl exec "macOS Tahoe" 'sudo -u steipete -H open -a Ghostty'
Ghostty 経由でコマンドを実行する
最適な方法:prlctl exec でゲストスクリプトを作成し、Ghostty を開いてフォーカスしたあと、表示されているターミナルには短いランチャーパスだけを入力します。
ゲストスクリプトのパターン:
prlctl exec "macOS Tahoe" 'sudo -u steipete -H /bin/zsh -lc '\''cat > /tmp/run-vm-lab.zsh <<EOF
#!/bin/zsh
source ~/.zprofile 2>/dev/null || true
cd ~/Projects/Peekaboo || exit 1
Apps/CLI/.build/debug/peekaboo image --path /tmp/peekaboo-vm.png --json
rc=$?
echo "EXIT:$rc"
[ -f /tmp/peekaboo-vm.png ] && sips -g pixelWidth -g pixelHeight /tmp/peekaboo-vm.png
echo "Press return to close..."
read _
exit $rc
EOF
chmod +x /tmp/run-vm-lab.zsh
ln -sf /tmp/run-vm-lab.zsh /tmp/r
open -a Ghostty'\'''
次に、ランチャーを Ghostty のホームディレクトリにリンクし、scripts/parallels_type.py で ./r と入力します。これにより、Parallels のキー入力でパス中の文字が正しく入力されない問題を回避できます。
prlctl exec "macOS Tahoe" \
"sudo -u steipete -H /bin/zsh -lc 'ln -sf /tmp/run-vm-lab.zsh ~/r'"
python3 skills/vm-lab/scripts/parallels_type.py "macOS Tahoe" $'./r\n'
長いコマンドの入力は避けてください。Parallels のキー入力は独自のキーコード表を使用するため、キーボードレイアウトの影響を受けることがあります。
既知の落とし穴
- macOS のクリップボード API は
prlctl exec経由では失敗する場合があります。ヘッドレスのゲスト環境では、pbcopy、AppleScript によるクリップボード操作、Peekaboo によるペーストのいずれも失敗することがあります。 - macOS では、
open -na Ghostty.app --args -e ...を実行しても、既存の Ghostty ウィンドウにフォーカスするだけの場合があります。コマンドが実行されると想定しないでください。 prlctl execは、ゲストシェルを介して argv を再結合することがあります。複雑なペイロードの場合は、完全にシェルクォートしたコマンド文字列を 1 つ渡すか、簡潔な Python ライターでファイルを作成してください。- Parallels の
send-key-event --keyでは、macOS の仮想キーコードではなく、Parallels のキー値を使用します。 - 通常のキー入力では、
--eventを指定せずにprlctl send-key-event <vm> --key <key>を送信してください。明示的なpress/releaseは、キー入力を繰り返したり、キーが押されたままになったりすることがあります。Return は例外で、press の後に release を使用します。 - 複数の
send-key-eventプロセスを個別に実行するより、prlctl send-key-event --jsonでまとめて送信してください。個別の呼び出しでは、フォーカスや遅延の影響でずれが生じることがあります。 PRL_KEY_ENTER = 36、PRL_KEY_SLASH = 61、PRL_KEY_R = 27、PRL_KEY_T = 28、PRL_KEY_M = 58、PRL_KEY_P = 33を使用してください。- キー入力が文字化けする場合は、Return を送信して行をクリアし、短いランチャーを作成してから、もう一度試してください。
- 画面収録の権限がない状態で Peekaboo の権限確認がハングし、
SWIFT TASK CONTINUATION MISUSEが出力される場合は、製品のバグとして記録してください。VM ハーネスの問題と混同しないでください。
双方向の検証
GUI 操作ごとに、互いに独立した 2 つのシグナルで検証してください。
- テスト対象ツールの出力:JSON、スクリーンショットファイル、AX の結果、またはアプリの状態。
- 外部検証手段:
prlctl capture、ホスト側での画像検査、ゲスト内のファイル内容、またはプロセス/ウィンドウの状態。
例:
- スクリーンショット:Peekaboo の画像の寸法/内容を
prlctl captureと比較します。 - クリック:Peekaboo でテストボタンをクリックし、ゲストアプリの状態とホストのスクリーンショットの両方を確認します。
- 入力:Peekaboo で管理されたテキストフィールドに入力し、AX の値とホストのスクリーンショットを確認します。
- パフォーマンス:コマンドを
/usr/bin/time -pでラップし、コールド実行/ウォーム実行を繰り返して、出力を/tmpに保存します。
Peekaboo VM のベースライン
ゲスト内:
cd ~/Projects/Peekaboo
git pull --recurse-submodules
swift build --package-path Apps/CLI
Apps/CLI/.build/debug/peekaboo --version
Apps/CLI/.build/debug/peekaboo permissions status --json
ホスト側の参照キャプチャ:
prlctl capture "macOS Tahoe" --file /tmp/vm-prlctl-reference.png
Ghostty 経由でのゲスト側 Peekaboo キャプチャ:
/tmp/r
比較:
prlctl exec "macOS Tahoe" \
'sudo -u steipete -H /bin/zsh -lc '\''sips -g pixelWidth -g pixelHeight /tmp/peekaboo-vm.png'\'''
sips -g pixelWidth -g pixelHeight /tmp/vm-prlctl-reference.png
報告
引き継ぎ時には、次の項目のみを記載してください。
- VM 名と OS ビルド。
- テストしたリポジトリのコミット。
- 権限の状態。
- 成功/失敗したコマンド。
- 独立した検証結果。
- 発見した製品のバグ。