feat(session): support unfocused agent windows (--no-focus) (#87)

`bsk session start --no-focus` opens the Agent Window in the background
without stealing focus. The flag threads focused=false through
CLI -> daemon IPC -> tool.session_start -> chrome.windows.create; an
omitted `focused` keeps the extension default (true) so older clients
are unaffected.

Reworked onto current main so it composes with #52 window sizing:
AgentWindowApi.create / SessionManager.start (extension), start_session
(CLI) and the daemon's session start now take options objects/structs
({ size, focused }) instead of colliding positional params.

Co-authored-by: alectimison-maker <alec.timison@gmail.com>
This commit is contained in:
BB-fatandalectimison-maker authored and GitHub committed 2026-08-12 19:58:53 +08:00
1 parent 0ce497f017
commit f443cfae74
17 files changed
+235 -43

No files matched your search

@@ -8,7 +8,7 @@
*/
export interface AgentWindowApi {
create(url: string, size?: { width: number; height: number }): Promise<number>;
create(url: string, opts?: AgentWindowCreateOptions): Promise<number>;
remove(windowId: number): Promise<void>;
/**
* Guarantee the Agent Window has an active, CDP-navigable tab.
@@ -18,16 +18,24 @@ export interface AgentWindowApi {
ensureActiveTab(windowId: number, url: string): Promise<void>;
}
/** Creation hints for a new Agent Window. */
export interface AgentWindowCreateOptions {
/** Optional outer size in CSS pixels. */
size?: { width: number; height: number };
/** Defaults to true so existing sessions keep visible Agent Windows. */
focused?: boolean;
}
/** Initial tab URL for every new session's Agent Window. */
export const AGENT_WINDOW_HOME = "about:blank";
export const chromeAgentWindowApi: AgentWindowApi = {
async create(url: string, size?: { width: number; height: number }): Promise<number> {
async create(url: string, opts: AgentWindowCreateOptions = {}): Promise<number> {
const win = await chrome.windows.create({
type: "normal",
focused: true,
focused: opts.focused ?? true,
url,
...(size ? { width: size.width, height: size.height } : {}),
...(opts.size ? { width: opts.size.width, height: opts.size.height } : {}),
});
if (typeof win?.id !== "number") {
throw new Error("[bh] chrome.windows.create returned no window id");