Skip to content

feat: reins groups — list tab groups - #34

Merged
karngyan merged 9 commits into
mainfrom
feat/tab-groups
Sep 26, 2026
Merged

karngyan merged 9 commits into
mainfrom
feat/tab-groups

Conversation

@karngyan

@karngyan karngyan commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

What

People asked for a way to see which tabs reins controls. Chromium tab groups are the natural marker, and they're also a general "organize my tabs" tool. This PR is the read side. reins ships primitives only and never groups anything on its own; the agent decides.

reins groups
#   b1  group 1055697787  "Mercor"  grey  9 tabs  window 1427084784
reins tabs
#   b1  tab 1427084886    g1055697787  Title — url
  • Protocol:
    • Tab.groupId (optional; left out when a tab is ungrouped).
    • A new TabGroup / ListGroupsResult.
    • list_groups at tier read.
    • On output, color is a plain string, so a future Chromium color can't reject a whole list. Inputs (next PR) use the nine-color enum.
  • Extension:
    • A new tab-groups.ts.
    • groupsSupported() checks for the exact APIs used (tabGroups.query/update, tabs.group/ungroup) rather than guessing from the browser name.
    • A browser without the API gets error code unsupported. The daemon rewrites it to name the browser: <browser> (b2) doesn't support tab groups — reins groups/group/ungroup need the chrome.tabGroups API, which this browser doesn't provide. Other reins commands work normally. An older extension that doesn't know these methods gets <browser> (b2)'s reins extension predates tab groups — update it ….
    • list_groups has no host check, since group titles are the user's own labels. Denied tabs in reins tabs stay redacted and drop their groupId.
  • Permission: adds tabGroups. It shows no install warning, so existing users aren't asked to re-approve on update, and browsers that don't know it ignore it.
  • Daemon:
    • list_groups fans out across browsers like list_tabs, tagging each group with browserId.
    • A browser that can't answer (unsupported, older extension, or another error) is listed in skipped ({browserId, browser, reason, message}), and the text output prints a line such as b2 <browser> — tab groups not supported. Nothing is dropped silently.
    • It only errors when every browser fails.
  • Docs: SKILL.md, the web commands page, Chrome Web Store permission justification, privacy policy, and a minor changeset. The store copy already covers the write side (feat: reins group / ungroup — create, edit and dissolve tab groups #35, stacked on this), because both land in the same release.

Spec and plan are in docs/superpowers/.

Test plan

  • pnpm build && pnpm test && pnpm typecheck && pnpm lint: all green.
  • Unit tests:
    • Capability detection (missing tabGroups, missing tabs.group).
    • unsupported code and message.
    • Tab counts per group.
    • groupId mapping (-1 left out).
    • list_groups bypasses the host gate.
    • Redaction drops groupId.
    • Daemon aggregation: all ok, partial failure, total failure, no browsers, unknown browserId.
    • Text output.
  • Live in Chrome (sideloaded build, reins extension --reload): reins groups listed an existing group correctly, and reins tabs marked its tabs. Read-only, nothing mutated.
  • Live in Dia alongside Chrome: Dia supports tab groups (it connects as "Chromium"). reins groups lists both browsers' groups, with skipped: [].
  • Unit tests for the named errors and skipped browsers: partial failure, total failure, outdated extension, generic error, routed group call with the audit record, non-group methods untouched, and text output.
  • Not live-tested: a browser that actually lacks tab groups, since none is available here. Unit tests only.

Stacked PR with reins group / reins ungroup: #35.

🤖 Generated with Claude Code

karngyan and others added 7 commits September 26, 2026 22:33
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Daemon fans list_groups out across connected browsers, tagging each
group with browserId + browser. A browser that fails (no tab-group
support, or an older extension) contributes nothing; only when every
targeted browser fails is the first error rethrown. Adds the groups
command, groupsText, and a g<id> marker on grouped tabs in reins tabs.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
karngyan and others added 2 commits September 27, 2026 00:19
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Dia was verified live: groups show in its sidebar (cyan renders as blue).
Remove the claim that Dia (and, unverified, Arc) lack tab groups from
the changeset and comments, use a neutral browser in test fixtures, and
bring the spec in line with the skipped-browser reporting.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@karngyan
karngyan added this pull request to stack #36 September 26, 2026 18:55
@karngyan
karngyan merged commit 9c7fb71 into main Sep 26, 2026
2 checks passed
karngyan added a commit that referenced this pull request Sep 26, 2026
main's tree equals the pre-squash PR1 tip, so every conflict resolves
to this branch's side; the net diff against main is unchanged PR2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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