Skip to content

Adopt marker-tab window model for Workspaces, drop tab-groups support#41

Open
trsrm wants to merge 18 commits intovsmejkal:masterfrom
trsrm:no-tab-groups
Open

Adopt marker-tab window model for Workspaces, drop tab-groups support#41
trsrm wants to merge 18 commits intovsmejkal:masterfrom
trsrm:no-tab-groups

Conversation

@trsrm
Copy link

@trsrm trsrm commented Nov 16, 2025

Context & Rationale

Chrome/Brave now persist Tab Groups, which caused duplicate markers and broke the original “tab-group-per-workspace” approach. This PR finishes the move to a pure window-based model: every workspace lives in its own browser window, identified by a pinned “marker tab”. The marker tab gives us a reliable window identifier (even after browser restarts or extension reloads) and doubles as a mini status page. As part of this change we cleaned up the docs, welcome page, and manual test plan so they no longer mention Tab Groups, removed the unreliable toolbar badge indicator, added small UX niceties (clipboard helper, marker self-healing), and cut a release prep pass for 0.8.

Highlights

  • Window-only workspaces: Opening a workspace now always prepends a pinned marker tab; syncing ignores marker tabs; background scripts rebind windows from markers at startup and recreate markers if they’re closed manually.
  • Marker page UX: The marker HTML page now shows workspace info, a color-coded favicon, and a “Copy workspace tabs” button that writes every tab’s title/URL to the clipboard.
  • Docs & onboarding: README, Welcome page, and manual Test Plan now describe the dedicated-window + marker-tab experience (no more “tab group” language), including marker behavior in test expectations.

trsrm added 17 commits November 16, 2025 00:39
Chrome now persists tab groups, which caused duplicated groups and other bugs in the extension. This change removes the tabGroups permission, strips all tab group listeners and helpers from the background worker, and makes the Workspace lifecycle rely solely on windows plus stored data. Legacy methods (activate, deactivate, getGroupId) become no-ops to keep existing callers working.

As a result, workspace windows continue to open/sync correctly while the extension no longer touches Chrome’s tab group APIs.
Workspace sync logic now treats window IDs as required: update service guards against missing IDs, and Workspace.sync immediately returns if it cannot resolve a valid window/workspace pair. Added comments in WorkspaceList (for per-window ownership and startup rebind behavior) and Workspace.sync to make the new window-only model explicit.

This keeps the extension from relying on tab groups while documenting how tabs in a window map entirely to that workspace.
Add a shared WORKSPACE_MARKER_PATH constant and isWorkspaceMarkerUrl helper so we can recognize the internal marker tab URL everywhere. WorkspaceTab.create now returns null for marker tabs (and callers filter), keeping the marker out of saved workspace state. Workspace sync and tab move flows leverage the filtered tab list so only “real” tabs get persisted.

This prepares the codebase for dedicated marker tabs without polluting workspace history.
Each workspace window now starts with a pinned marker tab whose URL identifies the workspace. WorkspaceOpenService prepends the marker URL when creating the window, pins/deactivates it, and offsets tab setup so user tabs retain their previous active/pinned state. A shared getWorkspaceMarkerUrl helper constructs the marker URL for reuse.

This gives every workspace window a stable internal marker that later tasks can detect.
handleWindowOpen now inspects new normal windows for our marker tab, parses the embedded workspaceId, and rebinds the window via WorkspaceList.update. The new helper logs when multiple markers appear and only accepts existing workspace IDs to avoid false positives. getUrlParams was hardened to parse marker URLs safely.

This restores window→workspace associations after browser restarts without any tab group dependency.
Introduce src/pages/workspace-marker/ (HTML/CSS/JS) so the pinned marker tab displays the workspace name, color badge, and title. The page reads workspaceId from the URL, fetches the workspace via Workspace.get, and shows friendly error states if data is missing.

The marker tab also now draws a per-workspace favicon: a full-size rounded rectangle filled with the workspace color and the uppercase initial letter. This makes workspace windows immediately recognizable in the tab strip.
When a tab/window becomes active, the background script now derives the workspace label (first few alphanumeric characters) and sets the action badge text/background color accordingly. The badge clears when focus moves to non-workspace windows or when no workspace is linked. This uses WorkspaceColor to ensure the badge color matches the workspace theme, giving users a quick visual cue for the active workspace.
- Added two sync options (workspaceBadge, markerIconLetter) with defaults and exposed radio controls on the Options page.
- Background service worker now caches options, listens for sync changes, and only sets the toolbar badge when the preference is enabled.
- Workspace marker page reads the new option and only draws the letter on the favicon when allowed (color block remains regardless).

This lets users hide the toolbar badge or the workspace initial on the marker tab while retaining color cues.
Ensure the workspace marker favicon’s letter always stays legible by choosing a text color that contrasts with the workspace background. The favicon renderer now computes the workspace color luminance and uses either white or near-black for the letter instead of always white.
The action badge indicator proved flaky, so this change removes it completely: background no longer tracks or updates badge text/colors, the workspaceBadge option and corresponding options UI have been deleted, and docs no longer describe a toolbar badge cue. Workspaces now rely solely on marker tabs and existing UI indicators.
If a user closes the marker tab (or it disappears during reload), the background script now recreates it automatically: tab removal events re-check whether the window is bound to a workspace and call ensureMarkerTab, and startup already rebinds/restores markers for all bound windows. This ensures marker tabs always persist.
The workspace marker page now includes a subtle “Copy Workspace Tabs” button that gathers every tab’s title/URL pair and writes them to the clipboard (title\nurl with blank lines between entries). A brief status message confirms success/failure, and the button uses a semi-transparent, de-emphasized style so it doesn’t distract from the main display.
- Set manifest version to 0.8, added a 0.8 changelog entry describing the new window-only design, and marked the v0.8 items complete in TODO (with a new v0.9 backlog).
- Updated README, Welcome page, and manual Test Plan to explicitly describe the dedicated-window + marker-tab workflow instead of tab groups/auth.

Ready for release.
@trsrm trsrm mentioned this pull request Nov 16, 2025
@trsrm
Copy link
Author

trsrm commented Nov 16, 2025

Screenshot:
image

- Ensure the marker page loads live tabs from the workspace window (ignoring the marker/newtab page) so the “Copy Workspace Tabs” helper works immediately after creating a workspace.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant