agent_first_http/cli/cmd/
tabs.rs1use clap::{Args as ClapArgs, Subcommand};
4use serde_json::Value;
5
6use crate::cli::output;
7use crate::sdk::Client;
8use crate::shared::error::{Error, ErrorCode};
9
10#[derive(ClapArgs, Debug)]
11pub struct Args {
12 #[command(subcommand)]
13 pub sub: TabsSub,
14}
15
16#[derive(Subcommand, Debug)]
17pub enum TabsSub {
18 List(EndpointArgs),
20 Close(CloseArgs),
22}
23
24#[derive(ClapArgs, Debug)]
25pub struct EndpointArgs {
26 #[arg(long = "endpoint-url")]
28 pub endpoint: String,
29 #[arg(long = "token-secret")]
31 pub token: Option<String>,
32}
33
34#[derive(ClapArgs, Debug)]
35pub struct CloseArgs {
36 pub id: String,
38 #[arg(long = "endpoint-url")]
40 pub endpoint: String,
41 #[arg(long = "token-secret")]
43 pub token: Option<String>,
44}
45
46pub async fn run(args: Args) -> Result<(), Error> {
47 match args.sub {
48 TabsSub::List(a) => list(a).await,
49 TabsSub::Close(a) => close(a).await,
50 }
51}
52
53fn build_client(endpoint: &str, token: Option<String>) -> Result<Client, Error> {
54 let mut client = Client::connect(endpoint)?;
55 if let Some(t) = token {
56 client = client.with_token(t);
57 }
58 Ok(client)
59}
60
61async fn list(args: EndpointArgs) -> Result<(), Error> {
62 let client = build_client(&args.endpoint, args.token)?;
63 let response = client.cdp("Target.getTargets").send().await?;
64 let targets = response
68 .get("targetInfos")
69 .cloned()
70 .unwrap_or(Value::Array(Vec::new()));
71 let payload = serde_json::json!({
72 "code": "tabs",
73 "targets": targets,
74 });
75 output::emit("tabs", &payload)
76}
77
78async fn close(args: CloseArgs) -> Result<(), Error> {
79 if args.id.trim().is_empty() {
80 return Err(Error::new(
81 ErrorCode::InvalidArgument,
82 "tabs close: target id must not be empty",
83 ));
84 }
85 let client = build_client(&args.endpoint, args.token)?;
86 let response = client
87 .cdp("Target.closeTarget")
88 .params(serde_json::json!({ "targetId": args.id }))
89 .send()
90 .await?;
91 let success = response
92 .get("success")
93 .and_then(Value::as_bool)
94 .unwrap_or(false);
95 let payload = serde_json::json!({
96 "code": "tab_closed",
97 "target_id": args.id,
98 "success": success,
99 });
100 output::emit("tab_closed", &payload)
101}