Skip to content

Latest commit

 

History

History
315 lines (255 loc) · 11.1 KB

File metadata and controls

315 lines (255 loc) · 11.1 KB

Smart Tab Workspace Manager

AI‑powered Chrome extension that auto‑detects your projects, groups related tabs into workspaces, and suspends idle tabs to keep your browser fast and organized.


Features

  • Automatic workspace detection

    • Classifies new/updated tabs into workspaces (for example: “Robotics Store”, “Social / Browsing”, “AI Tools”).
    • Uses rules (GitHub, Vercel, Notion, Jira, etc.) plus optional Groq AI for smarter grouping.
  • Chrome tab groups integration

    • Each workspace maps to a Chrome tab group (color + emoji + name).
    • Tabs are moved into the correct group as you browse.
    • Switching workspaces focuses the relevant group and its tabs.
  • Workspace lifecycle

    • Save workspace: snapshot of current tabs (including pinned, titles, favicons).
    • Switch workspace: saves current, optionally suspends it, and restores the target workspace’s tabs.
    • Archive idle/empty workspaces after a period of inactivity.
  • Automatic tab suspension

    • Suspends background tabs into a lightweight suspended.html page.
    • Keeps the original favicon and a “Restore Tab” button.
    • Resumes the original URL when you interact with the tab.
  • Side panel & popup UI

    • Popup: quick list of workspaces and actions.
    • Side panel: richer management (rename, move tabs, etc.).
    • Options page: configure AI, sync, theme, and behavior.
  • Keyboard shortcuts (configurable in Chrome)

    • Alt + . – Next workspace
    • Alt + , – Previous workspace
    • Alt + S – Save current workspace

Tech stack

  • Platform

    • Chrome Extension Manifest V3
    • Background service worker: background/service-worker.js
    • Content script: content/page-analyzer.js
    • Popup, sidepanel, options pages built with React/Vite into dist/
  • Build tools

    • vite (with @crxjs/vite-plugin)
    • React 18 (react, react-dom)
  • Runtime APIs & libraries

    • Chrome APIs: tabs, tabGroups, storage, alarms, sidePanel, notifications, idle, scripting
    • Optional Groq API for AI classification:
      • Model: llama-3.3-70b-versatile
      • Endpoint: https://api.groq.com/openai/v1/chat/completions
    • Optional sync via Supabase (controlled by settings)

How it works (under the hood)

1. Workspace model & storage

Workspaces are stored in chrome.storage via helpers in utils/storage.js. A workspace looks like:

{
  id: string;
  name: string;
  color: string; // hex color
  emoji: string; // e.g. "🚀"
  createdAt: number;
  lastActive: number;
  chromeGroupId: number | null;
  status: "active" | "suspended" | "archived";
  tabs: Array<{
    url: string;
    title: string;
    favicon: string;
    pinned: boolean;
    index: number;
    lastVisited: number;
  }>;
  classificationRules: string[]; // user regex patterns
}

utils/constants.js defines:

  • WORKSPACE_COLORS, CHROME_GROUP_COLORS, WORKSPACE_EMOJIS
  • DEFAULT_SETTINGS (autoClassify, suspendOnSwitch, suspendAfterMinutes, etc.)
  • MESSAGE_TYPES, ALARM_NAMES, Groq model constants

2. Classification pipeline

  • AI pass (optional)

    • If no rule matches and a Groq API key is set:
      • Gathers tabSignals from extractTabSignals(tab) and optional content-script page signals.
      • Sends them plus sample existing workspaces to Groq.
      • Expects JSON:
        { "workspace": string, "confidence": number, "isNew": boolean }.
    • Results are cached (getCachedClassification, setCachedClassification) to avoid repeated calls.
  • Matching to existing workspace

    • findMatchingWorkspace(workspaces, classificationName):
      • Exact name match.
      • Fuzzy contains match.
      • ID match (slugified).

3. Background service worker flow

File: background/service-worker.js.

  • Startup / install

    • On install:
      • Optionally auto‑classifies all current tabs once (autoClassifyAll()).
      • Creates alarms:
        • idle-suspend-check every 5 minutes
        • auto-archive-check every hour
        • sync-workspaces every 15 minutes
    • On startup:
      • Re-creates alarms.
      • Runs syncTabGroupTitles() to ensure tab group names are consistent with workspaces.
  • Tab listeners

    • chrome.tabs.onCreated and onUpdated:

      • When a tab has a URL, is not incognito, and not ignored, call handleClassifyTab(tab).
    • handleClassifyTab(tab):

      • Gets user settings, exits if autoClassify is off.
      • Runs classifier.
      • If existing workspace found:
        • Adds tab to workspace.tabs (if new).
        • Uses ensureTabGroup(workspace) to create/attach a Chrome group.
        • Adds the tab to that group via addTabToGroup.
        • Saves workspace.
      • If classification is new and confidence >= 0.6:
        • Creates a new workspace with random color + emoji.
        • Groups the tab into a new Chrome tab group and stores chromeGroupId.
    • chrome.tabs.onActivated:

      • Updates lastActive and active workspace ID when you switch tabs within a group.
    • chrome.tabGroups.onUpdated:

      • Syncs manual group renames/colors back to the workspace.
      • If a group title is empty, fills it with "<emoji> <name>".
  • Workspace switching

    • cycleWorkspace(direction) (keyboard shortcuts).
    • switchWorkspace(fromId, toId):
      • For the current workspace:
        • Snapshots open tabs via snapshotWorkspaceTabs(fromWs).
        • Optionally suspends them via suspendWorkspaceTabs(fromWs) and marks status suspended.
        • Saves workspace.
      • For the target workspace:
        • Restores tabs via restoreWorkspaceTabs(toWs) (reopen or unsuspend).
        • Updates chromeGroupId, sets status = "active", lastActive = now.
        • Sets active workspace ID.
        • Focuses the first tab in that workspace.
      • Optionally shows a notification about the switch.
  • Messages (popup/sidepanel/options)

    • Via chrome.runtime.onMessage and MESSAGE_TYPES:
      • GET_STATE – return full state (getFullState()).
      • SWITCH_WORKSPACE, SAVE_WORKSPACE, CREATE_WORKSPACE, DELETE_WORKSPACE, ARCHIVE_WORKSPACE, RENAME_WORKSPACE, MOVE_TAB.
      • UPDATE_SETTINGS – save user settings.
      • CLASSIFY_TAB, CLASSIFY_ALL.
      • OPEN_SIDEPANEL – opens side panel for the current tab.
      • PAGE_SIGNALS – stores signals from content script into chrome.storage.session.

4. Tab grouping and suspension

All in utils/tabUtils.js.

  • Group helpers

    • ensureTabGroup(workspace):
      • If workspace.chromeGroupId is valid, returns it.
      • Else:
        • Finds tabs that belong to the workspace (by URL).
        • Groups them with chrome.tabs.group.
        • Sets title to "<emoji> <workspace.name>" (fallback to 💻 Workspace).
        • Sets color based on workspace color.
        • Collapses if workspace is suspended.
    • addTabToGroup(tabId, groupId):
      • Safely adds a tab to a given group.
  • Suspension

    • suspendTab(tabId):
      • Skips active / ignored / already suspended tabs.
      • Navigates the tab to:
        chrome.runtime.getURL("assets/suspended.html") + ?url=<originalUrl>&title=<title>&favicon=<faviconUrl>
    • restoreTab(tabId):
      • Extracts url from the suspended page query param and navigates back to it.
    • suspendWorkspaceTabs(workspace):
      • Finds tabs belonging to the workspace (prefers groupId).
      • Collapses the tab group.
      • Calls suspendTab on each.
    • restoreWorkspaceTabs(workspace):
      • For each stored tab:
        • If already open, restores if suspended.
        • Else, reuses a suspended instance if present.
        • Else, opens a new tab with correct url and pinned state.
      • Groups all opened tabs into a tab group with proper title and color.
  • Suspended page

    • Files:

      • assets/suspended.html
      • assets/suspended.js
    • suspended.html:

      <!doctype html>
      <html>
        <head>
          <meta charset="utf-8" />
          <title>Tab Suspended</title>
        </head>
        <body>
          <div class="icon">💤</div>
          <h2>This tab has been suspended</h2>
          <p>Click below or interact with this tab to restore it.</p>
          <button id="restore-button">Restore Tab</button>
          <script src="suspended.js" defer></script>
        </body>
      </html>
    • suspended.js:

      • Reads url, title, favicon from the query string.
      • Sets page title to "<original title> (suspended)".
      • Dynamically creates/updates <link rel="icon"> to show the original favicon.
      • Wires the button and visibility events to call restore().

Usage examples

Example 1: Web dev project browsing

  1. Open:
    • github.com/
    • localhost:3000 (your dev server)
    • vercel.com/you/
  2. With auto‑classify ON, the extension:
    • Detects name from GitHub/Vercel URLs.
    • Groups these tabs into a “Name” workspace.
    • Creates a yellow tab group with an emoji, for example 🛒 Name.
  3. Press Alt + S:
    • A snapshot is saved with all those URLs and pinned states.
  4. Switch to another workspace via keyboard or popup:
    • Current tabs are optionally suspended.
    • Tabs for the target workspace are restored and grouped.

Example 2: Keeping “Social / Browsing” under control

  1. Open many social sites: Twitter/X, YouTube, Reddit, Instagram.
  2. The classifier maps them to a workspace named “Social / Browsing”.
  3. When you switch to a “Work” workspace:
    • Social tabs are suspended in the background.
    • Only a small group remains, easily collapsible.
  4. Coming back:
    • Switch to “Social / Browsing” workspace.
    • Tabs restore from the suspended page back to their original URLs.

Example 3: Manually organizing cross‑project tabs

  1. In the side panel:
    • Create a workspace: AI Research with emoji 🧠.
  2. Drag or “Move tab to workspace” from the UI:
    • Selected tabs are added to AI Research.
    • The extension groups those tabs into a 🧠 AI Research Chrome tab group.
  3. When closing the browser and reopening:
    • On startup, the extension restores group titles and keeps your workspace metadata.

Installation & development

Load unpacked in Chrome

  1. Run a build:
cd GridMind
npm install
npm run build
  1. In Chrome/Brave:
    • Go to chrome://extensions (or brave://extensions).
    • Enable Developer mode.
    • Click “Load unpacked” and select the dist/ folder.

Dev mode (auto‑rebuild)

npm run dev
  • Vite watches source files and rebuilds into dist/.
  • After changes, click Reload on the extension in the extensions page.

Configuration

Open the Options page (right‑click the extension icon → Options or chrome://extensions → Details → Extension options):

  • Groq API key – enable AI classification.
  • Auto classify – on/off.
  • Suspend on switch – whether to suspend tabs when leaving a workspace.
  • Suspend after minutes – idle time before auto‑suspend via alarm.
  • Show notifications – toasts for save/switch events.
  • Sync settings – Supabase URL/key if you want cross‑device sync (optional).
  • Theme – dark/light.