first pass of merging in warp (doesn't build)
This commit is contained in:
@@ -4,17 +4,44 @@ use std::path::PathBuf;
|
||||
|
||||
use clap::{Parser, Subcommand, ValueEnum};
|
||||
use computer_use::{
|
||||
Action, Key, MouseButton, Options, ScreenshotParams, ScreenshotRegion, Vector2I,
|
||||
Action, Key, MouseButton, Options, ScreenshotParams, ScreenshotRegion, Target, TargetedAction,
|
||||
Vector2I,
|
||||
};
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(name = "use_computer")]
|
||||
#[command(about = "Manually test computer use actions")]
|
||||
struct Cli {
|
||||
/// Experimental (macOS only): target a specific background window/process instead of the
|
||||
/// screen. Deliver events directly to this process ID (and `--window-id`, if given) without
|
||||
/// moving the real cursor or raising the window.
|
||||
#[arg(long, global = true)]
|
||||
pid: Option<i32>,
|
||||
|
||||
/// Experimental (macOS only): the CGWindowID of the window to target. Required when `--pid`
|
||||
/// is given. Use the `windows` subcommand to list window ids.
|
||||
#[arg(long, global = true)]
|
||||
window_id: Option<u32>,
|
||||
|
||||
#[command(subcommand)]
|
||||
command: Command,
|
||||
}
|
||||
|
||||
impl Cli {
|
||||
/// Resolves the per-action / screenshot target from the CLI flags. A `--pid` selects a
|
||||
/// background window target; otherwise the legacy whole-screen target is used. Callers must
|
||||
/// validate that `--window-id` is present whenever `--pid` is given (see `main`), so the
|
||||
/// ambiguous `0` sentinel is never sent to the actor.
|
||||
fn target(&self) -> Target {
|
||||
match (self.pid, self.window_id) {
|
||||
(Some(pid), Some(window_id)) => Target::Window { window_id, pid },
|
||||
// `--pid` without `--window-id` is rejected up front in `main`; fall back to the
|
||||
// screen target here so a missing id can never become a `0`-id window target.
|
||||
(Some(_), None) | (None, _) => Target::Screen,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum Command {
|
||||
/// Perform a mouse click (mouse down + mouse up) at a position.
|
||||
@@ -46,6 +73,9 @@ enum Command {
|
||||
/// The key to press. Can be a single character (e.g., "a") or a keycode (e.g., "0x24" for Return on macOS).
|
||||
key: String,
|
||||
},
|
||||
/// Experimental (macOS only): list on-screen windows with their window number, owner PID,
|
||||
/// owner name, layer, and bounds, to help identify the right target PID/window.
|
||||
Windows,
|
||||
}
|
||||
|
||||
#[derive(Clone, ValueEnum)]
|
||||
@@ -94,6 +124,29 @@ fn parse_region(s: &str) -> Result<(i32, i32, i32, i32), String> {
|
||||
async fn main() {
|
||||
let cli = Cli::parse();
|
||||
|
||||
// Window listing does not go through the actor's action model; handle it up front.
|
||||
if let Command::Windows = cli.command {
|
||||
match computer_use::experimental_list_windows() {
|
||||
Ok(text) => print!("{text}"),
|
||||
Err(e) => {
|
||||
eprintln!("Error: {e}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// A window target needs a concrete window id; require it alongside `--pid` so the ambiguous
|
||||
// `0` sentinel is never sent to the actor.
|
||||
if cli.pid.is_some() && cli.window_id.is_none() {
|
||||
eprintln!(
|
||||
"--window-id is required when --pid is given. Use the `windows` subcommand to list \
|
||||
window ids."
|
||||
);
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
let target = cli.target();
|
||||
let mut actor = computer_use::create_actor();
|
||||
|
||||
let (actions, screenshot_params, output_path) = match cli.command {
|
||||
@@ -124,6 +177,7 @@ async fn main() {
|
||||
max_long_edge_px: None,
|
||||
max_total_px: None,
|
||||
region,
|
||||
target,
|
||||
}),
|
||||
Some(output),
|
||||
)
|
||||
@@ -154,9 +208,21 @@ async fn main() {
|
||||
None,
|
||||
)
|
||||
}
|
||||
// Handled before the actor is created, above.
|
||||
Command::Windows => unreachable!(),
|
||||
};
|
||||
|
||||
let options = Options { screenshot_params };
|
||||
// Pair every action with the resolved target before handing off to the actor.
|
||||
let actions: Vec<TargetedAction> = actions
|
||||
.into_iter()
|
||||
.map(|action| TargetedAction { action, target })
|
||||
.collect();
|
||||
// The CLI is a developer tool for exercising window targeting, so background per-window
|
||||
// control is always enabled here.
|
||||
let options = Options {
|
||||
screenshot_params,
|
||||
background_enabled: true,
|
||||
};
|
||||
|
||||
match actor.perform_actions(&actions, options).await {
|
||||
Ok(result) => {
|
||||
|
||||
Reference in New Issue
Block a user