Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Starting from 0.2.0, CLI / Extension / DSH Plugin share the same version number.

## [Unreleased]

<<<<<<< HEAD
### Fixed

- Protocol: preserve explicit `null` results when deserializing `ResponseFrame`,
Expand Down Expand Up @@ -60,6 +61,23 @@ Starting from 0.2.0, CLI / Extension / DSH Plugin share the same version number.
`"staged"` status is gone.
- README documents `BSK_AUTO_UPDATE=off`.

### Added

- `bsk tab group create|update|list|ungroup`: native Chrome/Edge tab-group
management (`chrome.tabGroups`) scoped to the session's Agent Window, with
the same sandbox rule as `tab close` / `tab select`. Every affected tab —
not only the ones a request names, but every existing member of the group
too — is authorised with the direct-control rules, so unowned or borrowed
tabs cannot be renamed, regrouped or ungrouped through group operations.
Browsers that misplace a freshly created group (most reproducible with
`session start --no-focus`) get a bounded recovery ladder — group-level
move, then per-tab relocation plus an in-place group recreation, each
step re-verified against browser state — and an honest
`group_window_mismatch` error with `cleanup_state` instead of a silent
partial group when no attempt lands every tab. Group creation checks
cancellation between stages and stops with cleanup rather than
continuing to mutate after an abort.

## [0.3.1] - 2026-09-23

### Added
Expand Down
639 changes: 639 additions & 0 deletions apps/extension/src/tools/__tests__/tabs.test.ts

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions apps/extension/src/tools/dispatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,20 @@ import {
handleTabBorrow,
handleTabClose,
handleTabCreate,
handleTabGroupCreate,
handleTabGroupList,
handleTabGroupUngroup,
handleTabGroupUpdate,
handleTabList,
handleTabReturn,
handleTabSelect,
type TabBorrowParams,
type TabCloseParams,
type TabCreateParams,
type TabGroupCreateParams,
type TabGroupListParams,
type TabGroupUngroupParams,
type TabGroupUpdateParams,
type TabListParams,
type TabReturnParams,
type TabSelectParams,
Expand Down Expand Up @@ -479,6 +487,14 @@ export class ToolDispatcher {
);
case "tool.tab_select":
return handleTabSelect(this.sessions, req.params as TabSelectParams, { signal });
case "tool.tab_group_create":
return handleTabGroupCreate(this.sessions, req.params as TabGroupCreateParams, { signal });
case "tool.tab_group_update":
return handleTabGroupUpdate(this.sessions, req.params as TabGroupUpdateParams, { signal });
case "tool.tab_group_list":
return handleTabGroupList(this.sessions, req.params as TabGroupListParams, { signal });
case "tool.tab_group_ungroup":
return handleTabGroupUngroup(this.sessions, req.params as TabGroupUngroupParams, { signal });
case "tool.tab_borrow": {
const result = await handleTabBorrow(this.sessions, req.params as TabBorrowParams, {
signal,
Expand Down Expand Up @@ -1005,6 +1021,9 @@ function sessionIdForBrowserControlMethod(req: RequestFrame): string | null {
case "tool.tab_select":
case "tool.tab_borrow":
case "tool.tab_return":
case "tool.tab_group_create":
case "tool.tab_group_update":
case "tool.tab_group_ungroup":
case "tool.window_resize":
case "tool.emulate":
case "tool.navigate":
Expand Down
Loading