Skip to content

Tabs

Fuzzy-search, hibernate and save your open tabs

Overview

Tabs is an on-device tab manager for your browser. It gives you a ⌘K-style fuzzy finder over every open tab, groups those tabs by window, lets you hibernate idle ones to reclaim memory, and stashes a set of tabs as a named session you can reopen later. It is part of the kimtos new-tab app suite.

Everything is fully on-device. Tabs talks to the browser's own tab APIs directly and stores your saved sessions in the browser's local IndexedDB. There is no backend, no account, and no network call — your tabs and their URLs never leave the machine.

Highlights

  • Fuzzy tab finder — type to search every open tab by title and URL. A subsequence scorer ranks contiguous and word-start matches first, so gh iss surfaces your GitHub issues tab. Use / to move the highlight and Enter to jump to it; Esc clears the query.
  • Windows overview — when you are not searching, tabs are listed grouped by window (the focused window first), with tab-group chips inline.
  • Hibernate idle tabs — discard a tab to free the memory it holds; it reloads automatically the next time you focus it.
  • Tab groups — select several tabs and group them, or from a tab's menu create a new group or add it to an existing one. Rename a group and recolor it from the nine colors Chrome allows, or ungroup all its tabs.
  • Move, pin, reorder — drag a tab to reorder it or move it to another window, pin/unpin it, or send it to a brand-new window.
  • Recently closed — reopen tabs (or whole windows) you just closed, read from the browser's own recently-closed list.
  • Saved sessions — "Save window" stashes the current window's tabs as a named session; reopen it later (all tabs in a new window) or delete it.
  • Batch actions with undo — multi-select tabs to close them, or sessions to delete them, in one step.
  • Agent tools — the suite's on-device HomeAI agent can list, switch, close, and hibernate tabs and manage sessions through the same code paths as the UI.

Privacy model

Tabs reads and controls your tabs only on this device:

  • Reading your tabs (titles, URLs, favicons) requires the browser's tabs permission, which the app requests at runtime — only when you open it and click Grant access to my tabs, never from a background update.
  • Saved sessions (a name, a timestamp, and each tab's title/URL/favicon) are records in the browser's local IndexedDB, in the tab-sessions collection.
  • Nothing is uploaded, and there are no analytics or third-party calls.

Because it drives the real browser tab APIs, Tabs only works in the installed extension — not in the vite dev preview, where those APIs are unavailable.

Getting Started

Open Tabs from the dock. The first time you open it, the app asks for permission to read your tabs — it needs the browser's tabs access to search, switch, hibernate, and save them. Click Grant access to my tabs to continue. The request runs from your click (a user gesture, as the browser requires) and everything stays on your device; if you decline, nothing changes and you can grant it later.

Once granted, the app loads your open tabs, your recently closed items, and any saved sessions.

Finding and switching tabs

The search box sits at the top. Start typing to fuzzy-search every open tab by its title and URL — you do not need a contiguous match, so gh iss finds a "GitHub · Issues" tab.

  • / — move the highlight up and down the results.
  • Enter — jump to the highlighted tab (focusing its window).
  • Esc — clear the query and return to the windows overview.
  • Click a tab — switch to it directly.

Search is debounced, so the ranked list rebuilds a moment after you stop typing rather than on every keystroke.

The windows overview

With the search box empty, tabs are grouped by window, with the focused window ("This window") first and a per-window tab count. Tabs that belong to a tab group appear under a colored group chip. Each row shows the favicon (or a per-domain monogram tile when no favicon is usable), the title, and a tidied URL, plus badges for pinned (📌), audible (♪), and hibernated (💤) tabs.

Row actions

Hover a tab row for its quick actions:

  • Hibernate (moon icon) — discard the tab to free memory; it reloads when next focused. Hidden for tabs that are already asleep.
  • Close (✕) — close the tab.
  • More (⋯) — a menu with Pin / Unpin, Move to (a new window, or any other open window), Group (new group, an existing group, or remove from group), and Close tab.

Grouping tabs

You can build tab groups two ways:

  • From a tab's More → Group menu: start a New group, add the tab to an existing group, or Remove from group.
  • In multi-select mode: tick several tabs, then Group N collects them into a new group at once.

Click a group's chip to open its editor: rename the group, pick one of the nine colors, or Ungroup all tabs.

Moving, pinning, and reordering

  • Drag a tab row to reorder it, drop it on another tab to place it there, or drop it on a window header to move it into that window.
  • Pin / Unpin from the More menu.
  • Move to → New window (or another open window) from the More menu, or drag it across.

If the browser clamps a move (for example, pinned-tab constraints), the list simply re-scans and reflects the real state.

Recently closed

Below the overview, Recently closed lists tabs and windows you just closed, read from the browser's own history. Click an item (or its reopen icon) to restore it — a closed window brings back all of its tabs.

Saving and reopening sessions

Click Save window in the top bar to stash the current window's saveable tabs (its http/https pages) as a named session. Saved sessions appear under Saved sessions, each showing its tab count and when you saved it.

  • Reopen — click the session (or its open icon) to reopen all its tabs in a new window.
  • Delete — remove a session with its trash icon.

Sessions persist in local browser storage, so they survive restarts and travel with your browser profile.

Deleting several at once

Use Select to enter multi-select mode:

  • In the overview, tick tabs and close them in one step (or Group them).
  • Under Saved sessions, tick sessions and delete them together.

You can also drag across rows to select a range.

Asking the assistant

The suite's on-device HomeAI agent can drive Tabs for you — for example "switch to my email tab", "hibernate the heavy tabs", or "save this window as a session". The agent uses the same on-device code paths as the UI. It cannot grant the tab permission for you (that needs your click), so if access is not yet granted it will ask you to open the app and grant it first.

Architecture

Tabs is split cleanly in two: a thin, typed wrapper over the browser tab APIs for all live tab control, and a small data layer over the shared local IndexedDB for saved sessions. The UI sits on top of both, and the same two layers back the agent tools — so tools and UI can never drift. The code lives in extension/src/apps/tabs/.

Modules

FileRole
meta.tsThe app manifest — id, name, accent, order, plan, and App Store marketing copy.
index.tsThe app descriptor and UI — the fuzzy finder, windows overview, per-tab and group menus, drag-to-reorder/move, recently-closed and saved-session sections, batch select, plus the HomeAI agent tools array.
chromeTabs.tsA typed wrapper over the browser's tabs / tabGroups / windows / sessions APIs: the runtime permission check/request, querying windows and groups, activate/close/hibernate/move/pin, group create/rename/recolor/ungroup, recently-closed read/restore, and a change subscription.
sessions.tsThe saved-session data layer — list / save / delete over the shared dataStore (the tab-sessions IndexedDB collection).
tabs.cssThe app's styles.

Permissions

Tabs uses Chrome optional permissions — tabs, tabGroups, and sessions — requested at runtime from a user click, not declared up front for everyone. On open, the app checks chrome.permissions.contains; if the permission is missing it shows a gate whose button calls chrome.permissions.request (which must run from a gesture). tabGroups and sessions degrade gracefully: if unavailable, the app simply shows no groups and no recently-closed list.

Data flow

The UI never calls the raw chrome.* APIs itself: it goes through chromeTabs.ts, which keeps all the browser guards and type conversions in one place. Live tab state is never cached to disk — it is queried on demand and kept fresh by subscribing to the browser's tab events (onTabsChanged), which re-scans and re-renders whenever a tab is opened, closed, moved, or navigated. Only saved sessions are persisted, through sessions.tsdataStore into the local tab-sessions collection.

Saved-session data model

A session is one record:

  • Session{ id, name, tabs[], createdAt }, where each entry in tabs is a SavedTab { title, url, favIconUrl }.

Only http/https tabs are saved. listSessions returns sessions newest-first; saving trims the name (defaulting to a count-and-timestamp label); reopening creates a new window from the saved URLs. The collection is named with the app-id prefix (tab-sessions), so it appears — attributed to "Tabs" — in the suite's AnubisDB storage console with no extra wiring.

Agent tools

The descriptor exposes the app to the on-device HomeAI agent as an MCP-shaped tools array: list_tabs, switch_tab, close_tab, hibernate_tab, save_session, list_sessions, open_session, and delete_session. Each tool runs through the very same chromeTabs.ts / sessions.ts functions as the UI. A shared guard first checks that Tabs is running as an extension and that the permission is granted, returning a friendly message (rather than throwing) when it needs the user to open the app and grant access.