feat: support Agent Window sizing (session start --width/--height, window resize) (#52)

- `bsk session start --width <px> --height <px>` opens the Agent Window
  with the given outer size (chrome.windows.create)
- new `bsk window resize --session <id> --width <px> --height <px>`
  resizes the Agent Window at runtime (chrome.windows.update)
- both validated on CLI, daemon and extension sides (100..=7680 CSS px)
- protocol: new tool.window_resize method (BrowserMutation) and
  optional width/height on tool.session_start params; schemas regenerated
This commit is contained in:
BB-fat
2026-08-05 11:19:10 +08:00
committed by GitHub
parent d7f0f1e78c
commit 49378d70de
25 changed files with 725 additions and 10 deletions
+21
View File
@@ -229,6 +229,7 @@ pub fn full_handler(status: DaemonStatus, state: Arc<DaemonState>) -> RpcHandler
| Method::ToolTabSelect
| Method::ToolTabBorrow
| Method::ToolTabReturn
| Method::ToolWindowResize
| Method::ToolScreenshot
| Method::ToolConsole
| Method::ToolNetwork
@@ -538,6 +539,10 @@ fn tool_dispatch_timeout(params: &Value) -> Result<Duration, RpcError> {
struct CliSessionStartParams {
#[serde(default)]
pub browser_instance_id: Option<String>,
#[serde(default)]
pub width: Option<u32>,
#[serde(default)]
pub height: Option<u32>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -629,6 +634,8 @@ async fn handle_session_start(state: &Arc<DaemonState>, params: Value) -> Result
let params: CliSessionStartParams = if params.is_null() {
CliSessionStartParams {
browser_instance_id: None,
width: None,
height: None,
}
} else {
serde_json::from_value(params).map_err(|err| RpcError {
@@ -637,11 +644,25 @@ async fn handle_session_start(state: &Arc<DaemonState>, params: Value) -> Result
data: None,
})?
};
// `--width` without `--height` (or vice versa) is rejected: the
// extension only accepts a complete size pair.
let window_size = match (params.width, params.height) {
(Some(width), Some(height)) => Some((width, height)),
(None, None) => None,
_ => {
return Err(RpcError {
code: ErrorCode::InvalidParams,
message: "width and height must be given together".into(),
data: None,
});
}
};
match start_session(
&state.browsers,
&state.sessions,
&state.tool_queues,
params.browser_instance_id.as_deref(),
window_size,
state.config.extension_connect_wait,
DEFAULT_RPC_TIMEOUT,
)
+4
View File
@@ -401,6 +401,8 @@ pub async fn start_session(
sessions: &Arc<SessionRegistry>,
queues: &Arc<ToolQueueRegistry>,
requested: Option<&str>,
// Optional Agent Window outer size as `(width, height)` CSS pixels.
window_size: Option<(u32, u32)>,
connect_wait: Duration,
timeout_dur: Duration,
) -> Result<Session, StartSessionError> {
@@ -427,6 +429,8 @@ pub async fn start_session(
let params = SessionStartParams {
session_id: session_id.0.clone(),
browser_instance_id: Some(client.id.0.clone()),
width: window_size.map(|(width, _)| width),
height: window_size.map(|(_, height)| height),
};
let rpc_id = next_rpc_id("sess-start");
let request = RequestFrame {