agent_first_http/cli/cmd/
tabs.rs1use serde_json::Value;
4
5use crate::cli::connect::Connection;
6use crate::cli::output;
7use crate::shared::error::{Error, ErrorCode};
8
9#[derive(Debug)]
10pub struct Args {
11 pub sub: TabsSub,
12}
13
14#[derive(Debug)]
15pub enum TabsSub {
16 List(EndpointArgs),
17 Close(CloseArgs),
18}
19
20#[derive(Debug)]
21pub struct EndpointArgs {
22 pub connection: Connection,
23}
24
25#[derive(Debug)]
26pub struct CloseArgs {
27 pub tab: String,
28 pub connection: Connection,
29}
30
31pub async fn run(args: Args) -> Result<(), Error> {
32 match args.sub {
33 TabsSub::List(a) => list(a).await,
34 TabsSub::Close(a) => close(a).await,
35 }
36}
37
38async fn list(args: EndpointArgs) -> Result<(), Error> {
39 let client = args.connection.client().await?;
40 let response = client.cdp("Target.getTargets").send().await?;
41 let targets = response
45 .get("targetInfos")
46 .cloned()
47 .unwrap_or(Value::Array(Vec::new()));
48 let payload = serde_json::json!({
49 "code": "tabs",
50 "targets": targets,
51 });
52 output::emit("tabs", &payload)
53}
54
55async fn close(args: CloseArgs) -> Result<(), Error> {
56 if args.tab.trim().is_empty() {
57 return Err(Error::new(
58 ErrorCode::InvalidArgument,
59 "tabs close: target id must not be empty",
60 ));
61 }
62 let client = args.connection.client().await?;
63 let response = client
64 .cdp("Target.closeTarget")
65 .params(serde_json::json!({ "targetId": args.tab }))
66 .send()
67 .await?;
68 let success = response
69 .get("success")
70 .and_then(Value::as_bool)
71 .unwrap_or(false);
72 let payload = serde_json::json!({
73 "code": "tab_closed",
74 "target_id": args.tab,
75 "success": success,
76 });
77 output::emit("tab_closed", &payload)
78}