droid-control について
Droid Controlは、ターミナル、ブラウザー、デスクトップアプリを自動化するスキルです。対象と指定された操作方法に応じて手順を選び、成果物の記録・編集・検証も扱います。
主な機能
- 01対象と操作方法に応じたワークフロー選択
- 02ターミナル、ブラウザー、デスクトップ操作の自動化
- 03証拠素材の記録と編集
- 04成果物の要件適合性を検証
- 05分離された記録作業の調整
活用シーン
- 01ターミナルやブラウザーの操作を記録
- 02修正前後の回帰デモを作成
- 03QAやデモの成果物を検証
- 04ネイティブデスクトップアプリを自動化
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ factory-ai/ factory-plugins --skill droid-controlインストール後、Claude Code で/droid-controlを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
atoms/browser-use/ATOM.mdatoms/capture/ATOM.mdatoms/compose/ATOM.mdatoms/desktop-use/ATOM.mdatoms/droid-cli/ATOM.mdatoms/pty-capture/ATOM.mdatoms/pty-capture/platforms/linux.mdmacos.mdwindows.mdatoms/showcase/ATOM.mdatoms/terminal-use/ATOM.mdatoms/true-input/ATOM.mdatoms/true-input/platforms/linux.mdmacos.mdwindows.mdatoms/verify/ATOM.md詳細
Droid Control
ターミナル、ブラウザー、デスクトップアプリを自動化します。まずユーザーが要求した方法に従ってルーティングし、必要な仕組みと証拠の段階だけを読み込みます。
基本ルール
- 実際のアプリ、実際の環境を使います。 LLM の応答、ネットワーク遅延、出力の変動など、動作が非決定的であることを想定してください。
wait/wait-idleで対処します。フィクスチャやモックデータで代用してはいけません。 - 証拠をもとに復旧します。 アクションが失敗した場合や結果が不確かな場合は、再試行する前に現在の状態を確認します。方法の制約と権限の境界を守ってください。拒否されたからといって、別のドライバーやより広い対象を使ってよいわけではありません。
- アトムはスキルではなくファイルです。 Read ツールで、ルーティングされた各アトムを
${DROID_PLUGIN_ROOT}/skills/droid-control/atoms/<atom>/ATOM.md(インデックスはアトムを参照)から読み込みます。Skill ツールでは読み込めません。このプラグインのコマンドやアトムで太字になっているアトム名は、そのファイルを指します。アトムから参照されるファイルのパスはアトムファイルを基準にしています。必要に応じて読み込んでください。アトムファイルは展開されないため、DROID_PLUGIN_ROOT 変数が記述されている箇所では、このプラグインのルート${DROID_PLUGIN_ROOT}に置き換えてください(シェルコマンドでは引用符で囲みます)。デスクトップを操作するために、別途 cua スキルをインストールする必要はありません。 - 記録されたターミナルセッションは
tctlが管理します。 PTY 上でasciinema recをラップします。ブラウザーとデスクトップの各ドライバーは、それぞれ独立したライフサイクルを管理します。tuistory launchを直接呼び出してはいけません。ターミナルのワークフローまたはワーカーへの引き継ぎに限り、TCTLを絶対パスに解決します。 - 実行ごとに分離します。 同じマシン上で複数のドロイドが同時に録画している場合があります。セッション名と出力パスはグローバルな名前空間(
/tmp/tctl-sessions/)を共有します。各ワークフローの開始時に、実行 ID(RUN_ID=$(date +%s)-$$など)を生成し、すべてのセッション名のプレフィックスと、すべての出力ファイルの個別の一時ディレクトリに使用します。RUN_ID="$(date +%s)-$$" RUN_DIR="$(mktemp -d /tmp/droid-run-${RUN_ID}-XXXXXX)" # Session names: -s ${RUN_ID}-before, -s ${RUN_ID}-after # Output paths: ${RUN_DIR}/before.cast, ${RUN_DIR}/after.cast-s demo、-s before、-s afterのようなプレフィックスのないセッション名は、並行実行と衝突するため使用しないでください。 名前とパスを分けても、共有デスクトップのフォーカスやキーボード入力は分離されません。画面に表示されるデスクトップを操作するコントローラーは、1 つだけにしてください。
アトム
各アトムは ${DROID_PLUGIN_ROOT}/skills/droid-control/atoms/<atom>/ATOM.md にあります。
| アトム | 対象範囲 |
|---|---|
| terminal-use | ターミナル TUI ドライバー:デフォルトでは tuistory 仮想 PTY を使用し、実際のターミナルでの証拠には true-input を使用 |
| true-input | ヘッドレス Wayland コンポジターまたは VM を介した、実際のターミナルエミュレーター用ドライバー |
| browser-use | agent-browser を介した Web ページおよび Electron アプリ用ドライバー |
| desktop-use | trycua cua-driver を介したネイティブ GUI アプリ用ドライバー |
| droid-cli | Droid CLI の対象パターン、ショートカット、モード、起動ヘルパー |
| pty-capture | 実際のターミナルエミュレーターから取得した、信頼できるバイト列 |
| capture | ターミナルおよびブラウザーのセッションを記録するライフサイクル |
| compose | fframes レンダラーによる動画の組み立て:タイトルカード、レイアウト、トランジション、エフェクト、ショーケースの仕上げ |
| verify | 約束事項に照らした成果物の検証 |
| showcase | 視覚的な仕上げ:ウィンドウの装飾、アニメーション、ブランド付き背景 |
ルーティング
独立した検索を 3 つ行います。すべて実行してから、そこから得られたアトムをまとめて読み込みます。
1. 対象ルート — 何を操作しますか?
| 対象 | 読み込むアトム |
|---|---|
| ユーザーが cua のみ、ネイティブ GUI 入力、またはデスクトップ操作(Electron を含む)を明示的に要求している | desktop-use。方式に関する制約は、以下のデフォルト設定より優先されます |
Droid CLI(droid-dev、droid exec) | terminal-use + droid-cli |
| その他のターミナル TUI | terminal-use |
| Web ページまたは Electron アプリ | browser-use |
| ネイティブデスクトップ GUI アプリ | desktop-use |
| 生のターミナルバイトシーケンス | terminal-use + pty-capture |
terminal-use は ${DROID_PLUGIN_ROOT}/bin/tctl の背後で使うターミナルバックエンドを選択します。デフォルトは tuistory で、実際のターミナル描画やキーボードエンコーディングの証拠が必要な場合は true-input を読み込みます。Desktop-use にはコンポジター固有のガイダンスが含まれます。Linux の対象がすべて X11 のみだと決めつけたり、ユーザーが選んだ方式を放棄したりせず、Cua のライブ機能を確認してください。
2. ステージルート — ワークフローで必要な作業は何ですか?
すべてのワークフローは複数のステージを経ます。使用する各ステージのアトムを読み込んでください。
| ステージ | アトム | 読み込むタイミング |
|---|---|---|
| キャプチャ | capture | 録画、スクリプト化された複数ステップの証拠、またはデモ/QA 用の成果物が必要な場合。通常のデスクトップ操作では、ドライバーの観察/検証ループを使用します |
| 作成 | compose | 成果物(動画、注釈付きスクリーンショット、比較画像など)を作成する場合 |
| 検証 | verify | 正式な証明、デモ、または QA 用の成果物が必要な場合。このステージを使わない場合でも、各操作の検証は必要です |
3. 成果物ルート — compose で仕上げ用ツールが必要ですか?
compose を読み込んだ場合にのみ関係します。
| 成果物の要件 | 追加で読み込むもの |
|---|---|
| ショーケースの仕上げ(ウィンドウ枠、ブランドフレーム、映画のような背景) | showcase |
| エフェクトとキー入力オーバーレイ | (compose が処理します。これらは Showcase の props JSON にあるフィールドです) |
ワークフローの構成
Command (intent + commitments)
→ Target route (load driver atoms)
→ Capture (record / screenshot / byte-capture)
→ Compose (assemble deliverable, if needed)
→ Verify (check against commitments)
→ Report
コマンドは生成する内容を宣言します。アトムはその方法を担います。
レイアウトのデフォルト
デフォルト:single。 対象または最終状態を示すクリップを 1 つ使います。成果物が本質的に比較である場合を除き、これを選んでください。
| ケース | レイアウト |
|---|---|
| 新機能(意味のある以前の状態がない) | single |
| バグ修正、動作する経路を示す単一クリップの証明 | single |
| 操作説明/チュートリアル/README のヒーロー画像 | single |
| リグレッションの証明(修正前と修正後) | side-by-side |
| 動作を維持するリファクタリング(視覚的な同等性が要点) | side-by-side |
| ユーザーが比較を明示的に要求している | side-by-side |
side-by-side にするために、「修正前」の状態を作り出さないでください。実際のベースラインがない場合は、single を使ってください。
委任
短時間の対話型デスクトップタスクは親に任せてください。観察、入力、ユーザーの許可待ち、クリーンアップを親が担います。別々のキャプチャ環境やレンダリングを委任し、別のコントローラーの入力と交互に行う個々のスクリーンショットは委任しないでください。
委任する内容
| タスク | 委任するか | 理由 |
|---|---|---|
| 対話型の共有デスクトップ | いいえ — 親 | フォーカス、スナップショット、入力、許可待ち、クリーンアップは、1 つのコントローラーが担います |
| 隔離されたターミナル/ブラウザー環境でのクリップのキャプチャ | はい | ワーカーが対話と録画のライフサイクル全体を担います |
| 両方のクリップのキャプチャ(比較レイアウト) | はい。ただし独立した環境を使う場合のみ | ワークツリーとセッションラベルだけでは、デスクトップは隔離されません |
| ショーケースのレンダリング | はい | 必要なのは props JSON、クリップのパス、出力先のパスのみです。render-showcase.sh を実行します(.cast 変換、レンダリングごとのステージング、忠実度プロファイル、最長クリップの再生時間、クリーンアップを処理します) |
| 計画、操作のスクリプト化 | いいえ — 親 | PR のコンテキストと編集上の判断が必要です |
| レイアウトとプロパティの構築 | いいえ — 親 | エフェクト、タイミング、ラベルに関する編集上の判断が必要です |
| 検証 | いいえ — 親 | コミットメントのコンテキストが必要です |
| ffprobe の単発実行/ファイルの存在確認 | いいえ — 直接実行 | サブエージェントのオーバーヘッドをかけるほどではありません |
委任方法
ステップ 0:パスを解決し、実行 ID を生成します。 ワーカーは ${DROID_PLUGIN_ROOT} を引き継ぎません。一度解決し、すべての場所に貼り付けます。
TCTL="$(realpath "${DROID_PLUGIN_ROOT}/bin/tctl")"
RENDER="$(realpath "${DROID_PLUGIN_ROOT}/scripts/render-showcase.sh")"
RUN_ID="$(date +%s)-$$"
RUN_DIR="$(mktemp -d /tmp/droid-run-${RUN_ID}-XXXXXX)"
すべての出力ファイル(録画、props、レンダリング済み動画)には ${RUN_DIR} を使用します。すべてのセッション名には ${RUN_ID}- をプレフィックスとして付けます。-s before のようなプレフィックスなしの名前や、/tmp/before.cast のようなハードコードされたパスは使用しないでください。
解決済みの絶対パスを使った正確なコマンドをワーカーに渡してください。抽象的な指示や tuistory、${DROID_PLUGIN_ROOT} は使わないでください。考えるのは親側で、実行するのはワーカーです。
Task prompt for a capture worker:
"Run these commands in order. Report the output file path and any errors.
1. /abs/path/to/bin/tctl launch "droid-dev" -s 1712345678-42-before --backend tuistory \
--repo-root /abs/path/to/baseline/worktree \
--cols 120 --rows 36 --record /tmp/droid-run-1712345678-42-xxxx/before.cast \
--env FORCE_COLOR=3 --env COLORTERM=truecolor
2. /abs/path/to/bin/tctl -s 1712345678-42-before wait ">" --timeout 15000
3. /abs/path/to/bin/tctl -s 1712345678-42-before type "hello world"
4. /abs/path/to/bin/tctl -s 1712345678-42-before press enter
5. /abs/path/to/bin/tctl -s 1712345678-42-before wait-idle
6. /abs/path/to/bin/tctl -s 1712345678-42-before close"
Task prompt for a render worker:
"Run this command. Report the output file path and any errors.
/abs/path/to/scripts/render-showcase.sh \
--props /tmp/droid-run-1712345678-42-xxxx/showcase-props.json \
--output /tmp/droid-run-1712345678-42-xxxx/demo.mp4 \
/tmp/droid-run-1712345678-42-xxxx/before.cast /tmp/droid-run-1712345678-42-xxxx/after.cast"
並列キャプチャパターン(比較フローのみ)
Layout のデフォルトテーブルで side-by-side が選択され、キャプチャ環境が独立している場合にのみ適用されます。共有デスクトップのキャプチャは直列化してください。単一の対話型デスクトップタスクでは、親側が操作を続けてください。
ビフォー/アフター比較のデモでは、両方のキャプチャワーカーを同時に起動します。
1. Parent constructs the interaction script (identical for both branches)
2. Launch worker A: capture the baseline/reference branch with `--repo-root` set to that worktree
3. Launch worker B: capture the candidate/change branch with `--repo-root` set to that worktree
4. Wait for both to complete (TaskOutput)
5. Collect .cast paths from results
6. Continue to compose
共有ツール
ターミナルドライバーは統合された tctl ラッパーを使用します。ブラウザー操作とデスクトップ操作には、それぞれ専用の CLI(agent-browser、cua-driver)があり、tctl は使用しません。
ドライバーは 1 つのワークフロー内で組み合わせられます。たとえば、CLI には tctl を使い、それが操作する Web UI には agent-browser を使えます。
劣化した末尾の再現手順(droid TUI)
droid CLI で、劣化したトランスクリプト末尾(実行状態のまま残るツール行や、キューに入ったステアリングメッセージ)を、遅いモデルの処理を待たずに再現するための確定的な手順です。コツは、遅い PreToolUse フックを使って、必要な時間だけツールを実行中の状態に保つことです。
-
一時プロジェクトを用意します。 一時的なディレクトリ(実際のリポジトリは使用しないでください。フックは条件に一致するツール呼び出しごとに実行されます)を作成し、スリープするプロジェクトローカルのフックを設定します。
SCRATCH="$(mktemp -d /tmp/degraded-tail-XXXXXX)" mkdir -p "$SCRATCH/.factory" cat > "$SCRATCH/.factory/settings.json" <<'JSON' { "hooks": { "PreToolUse": [ { "matcher": "TodoWrite", "hooks": [{ "type": "command", "command": "sleep 120" }] } ] } } JSONフックの実行中に操作できるよう、十分な長さ(60~180 秒)のスリープ時間を設定し、プロンプトによって確実に呼び出されるツールにマッチャーを設定します(複数ステップの依頼では
TodoWriteが実行されます)。 -
--cwdに一時プロジェクトを指定して起動します。--repo-rootは開発用ワークツリーのままにし、droid-devのプロベナンスにテスト対象のコードが記録されるようにします。$TCTL launch "droid-dev" -s ${RUN_ID}-tail --cwd "$SCRATCH" \ --repo-root /abs/path/to/dev/worktree --record ${RUN_DIR}/tail.cast -
フックを起動し、ツール行が実行中と表示されている間に末尾を劣化させます。
- フックの実行中に割り込みます(
press escape)。 実行中のツール行が残り、トランスクリプト末尾で完了状態やキャンセル状態に移行しなくなります。 - フックの実行中にステアリングします(
type "..."+press enter)。 ステアリングメッセージは割り込みではなく、実行中のツールの後ろにキューイングされます。
- フックの実行中に割り込みます(
注意点: 開発スコープのフック設定によって、プロジェクトのフックが気づかないうちに無効化されることがあります。ツールがすぐに完了する場合は、セッションで /hooks を実行し、フック設定自体を調べる前に「Hooks enabled」の切り替えを確認してください。
前提条件
| ステージ | プラットフォーム | 必須 | 任意 |
|---|---|---|---|
| terminal-use (tuistory) | すべて | tuistory、asciinema、agg | tmux |
| true-input | Linux/Wayland | cage、wtype、Wayland ターミナル、/dev/dri/* | grim、wf-recorder |
| true-input | Windows (KVM) | libvirt、qemu、SPICE + SSH を備えた KVM VM、DROID_VM_* 環境変数 | virt-manager |
| true-input | macOS (QEMU) | qemu、socat、SSH を備えた macOS VM、DROID_MAC_* 環境変数 | — |
| browser-use | すべて | agent-browser(および agent-browser install) | — |
| desktop-use | すべて | 対象のグラフィカルセッションでの cua-driver、承認済みの OS 権限 | ドキュメントは同梱されています。別途スキルをインストールする必要はありません |
| compose | すべて | ffmpeg、ffprobe、agg | — |
| showcase | すべて | Rust(stable)、clang/libclang、libx264 | — |
インストールコマンド
# tuistory driver + recording
npm install -g tuistory # virtual PTY driver
pip install asciinema # terminal recording (tctl wraps this)
cargo install --git https://github.com/asciinema/agg # .cast -> .gif converter (compose needs this)
# true-input driver (Linux/Wayland)
sudo apt-get install -y cage wtype # required: headless compositor + keystroke injection
sudo apt-get install -y grim wf-recorder # optional: screenshots + video recording
# agent-browser driver
agent-browser install # one-time: downloads bundled Chromium
# desktop-use: follow its setup instructions only if the binary
# is missing and installation is approved. No separate skill install.
# compose + showcase (video rendering)
sudo apt-get install -y ffmpeg # video processing (includes ffprobe)
sudo apt-get install -y clang libclang-dev libx264-dev # renderer build deps (macOS: xcode-select --install; brew install x264)
cargo build --release --manifest-path ${DROID_PLUGIN_ROOT}/fframes/Cargo.toml # renderer (render-showcase.sh also builds on first use)