agentmux_cef\browser_api/
mod.rs

1// Copyright 2026, AgentMux Corp.
2// SPDX-License-Identifier: Apache-2.0
3
4//! Browser-pane DOM API (`/agentmux/browser/*`).
5//!
6//! External clients (test harnesses, automation scripts) use these
7//! endpoints to query and mutate the DOM inside a running browser
8//! pane without depending on screen-pixel geometry. Implemented as a
9//! thin proxy over CEF's Chrome DevTools Protocol (CDP) server on
10//! `remote_debugging_port` (9223 dev / 9222 release).
11//!
12//! Phase 1 implements only `browser.query` — a CSS-selector lookup
13//! that returns matching elements with their tag, text, attrs, and
14//! bounding rect. Subsequent phases layer on `focus_info`, `eval`,
15//! `screenshot`, and the write methods (`click_element`,
16//! `dispatch_key`, …). See `docs/specs/SPEC_BROWSER_DOM_API.md` and
17//! `docs/specs/PLAN_BROWSER_DOM_API.md`.
18//!
19//! All routes require `Authorization: Bearer <ipc_token>` — same
20//! scheme as the existing `/ipc` route in `crate::ipc`.
21
22use std::sync::Arc;
23
24use axum::routing::post;
25use axum::Router;
26
27use crate::state::AppState;
28
29pub mod cdp;
30pub mod resolver;
31pub mod routes;
32pub mod types;
33
34/// Register `/agentmux/browser/*` routes on the given axum Router.
35/// Called from `ipc::start_ipc_server` alongside the existing
36/// `/ipc` + `/health` routes.
37pub fn register_routes(router: Router<Arc<AppState>>) -> Router<Arc<AppState>> {
38    router
39        .route("/agentmux/browser/query", post(routes::query))
40        .route("/agentmux/browser/focus_info", post(routes::focus_info))
41        .route("/agentmux/browser/eval", post(routes::eval))
42        .route("/agentmux/browser/screenshot", post(routes::screenshot))
43        .route("/agentmux/browser/click_element", post(routes::click_element))
44        .route("/agentmux/browser/focus_element", post(routes::focus_element))
45        .route("/agentmux/browser/dispatch_key", post(routes::dispatch_key))
46        .route("/agentmux/browser/navigate", post(routes::navigate))
47        .route("/agentmux/browser/back", post(routes::back))
48        .route("/agentmux/browser/forward", post(routes::forward))
49        .route("/agentmux/browser/reload", post(routes::reload))
50}
51
52/// Shared state for the browser API — primarily the CDP target
53/// cache (block_id → target_id). Lives inside `AppState` and is
54/// lazily populated on first resolve per block.
55pub struct BrowserApiState {
56    pub target_cache: resolver::TargetCache,
57}
58
59impl BrowserApiState {
60    pub fn new() -> Self {
61        Self {
62            target_cache: resolver::TargetCache::new(),
63        }
64    }
65}
66
67impl Default for BrowserApiState {
68    fn default() -> Self {
69        Self::new()
70    }
71}