Skip to content

feat(desktop): browser profiles for the preview browser - #7254

Open
juliusmarminge wants to merge 31 commits into
mainfrom
browser-profiles
Open

feat(desktop): browser profiles for the preview browser#7254
juliusmarminge wants to merge 31 commits into
mainfrom
browser-profiles

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Aug 16, 2026

Copy link
Copy Markdown
Member

Adds profiles to the desktop preview browser so tabs can keep separate cookies and site data. This is the bottom of the remaining stack; the browser-access setting is already merged.

Default preserves existing login storage. Incognito uses an in-memory partition. Other profiles use a separate partition namespace with unambiguous environment/profile scoping. A tab keeps its chosen profile for its lifetime.

Settings supports creating, renaming, choosing a default, and removing profiles. Removal waits for cookie/cache cleanup across all known environments and retains the profile if cleanup fails. Existing tabs remain open after removal and are labeled “Removed profile.” The Browser menu supports opening a chosen profile, including touch input.

Validation: focused profile, preview, settings-hydration, and partition-isolation tests; web/desktop typechecks; scoped formatting and lint. Latest CI results are shown below. Earlier desktop behavior was verified by the maintainer; this audit did not run another GUI pass.

Compatibility: Default partitions are unchanged. Data created in custom profiles by an earlier unmerged version of this stack is not migrated from the collision-prone partition mapping.

Original implementation: Claude Code. Review fixes: GPT-5.6 Sol agents, coordinated through Codex.

Note

Add browser profiles to the preview browser

  • Introduces BrowserProfile contracts with built-in default and incognito profiles, and adds settings UI to create, rename, delete, and set the default profile
  • Updates BrowserSession to support a profile namespace and ephemeral (in-memory) partitions for incognito mode, keeping legacy partitions disjoint
  • Updates PreviewManager and IPC handlers to pass profileId through snapshots, config requests, and partition-scoped clearing operations
  • Updates web components like RightPanelTabs to open specific profiles via a submenu, and keys previewWebviewConfigAtom by (environmentId, profileId)
  • Risk: DesktopPreviewBridge.clearCookies, clearCache, and getPreviewConfig now require (environmentId, profileId?) instead of taking no arguments or just environmentId

Macroscope summarized fe5480b.


Note

Medium Risk
Touches Electron session partitions and cookie/cache clearing semantics; legacy Default scope is preserved but IPC and storage-isolation behavior changes need careful regression on login persistence and multi-profile clears.

Overview
Adds browser profiles so preview tabs can use separate cookies and site data, wired end-to-end from contracts through desktop Electron sessions to the web UI.

Partitioning (desktop): New resolvePartitionScope keeps the Default profile on the legacy bare environmentId scope; other profiles use a JSON-encoded scope plus a profile- partition namespace so scopes like a::b vs environment a + profile b stay distinct. Incognito uses non-persistent partitions. getPreviewConfig, clearCookies, and clearCache now take environmentId and optional profileId; per-profile clears load the session first so data is actually removed after restart. BrowserSession supports targeted clears and recognizes ephemeral partition prefixes.

Server & contracts: Preview sessions carry optional profileId (fixed at tab open); the server manager preserves it across navigate and status updates. Client settings add browserProfiles and browserDefaultProfileId, with built-in Default/Incognito synthesized in resolveBrowserProfiles.

Web UX: Integrations settings to create/rename/remove profiles (removal clears data across connected environments), pick a default (not incognito), profile submenu when adding a browser tab, profile badge and scoped clear actions in preview chrome, and default profile resolution on all open-preview paths. Breaking for bridge callers: clearCookies / clearCache / getPreviewConfig now require environmentId (and accept optional profileId).

Reviewed by Cursor Bugbot for commit fe5480b. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitai Bot commented Aug 16, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 904d0a95-7510-4028-b553-9dcda458780c

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. label Aug 16, 2026
@github-actions github-actions Bot added the size:XL 500-999 changed lines (additions + deletions). label Aug 16, 2026
Comment thread apps/desktop/src/ipc/methods/preview.ts Outdated
Comment thread apps/web/src/browser/previewWebviewConfigState.ts
Comment thread apps/web/src/components/preview/PreviewMoreMenu.tsx
@github-actions

github-actions Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 13.3 KiB 13.3 KiB −7 B (−0.1%) 15.1 KiB
Codex Thread snapshot wire 6.9 KiB 6.9 KiB −3 B (−0.0%) 7.3 KiB
Codex Live turn WebSocket wire 6.4 KiB 6.4 KiB −4 B (−0.1%) 7.8 KiB
Codex Live turn WebSocket decoded 55.6 KiB 55.6 KiB −44 B (−0.1%) 66.4 KiB
Codex Live turn messages 11 10 −1 (−9.1%) 21
Claude Total thread wire 13.3 KiB 13.3 KiB −3 B (−0.0%) 15.1 KiB
Claude Thread snapshot wire 6.9 KiB 6.9 KiB +11 B (+0.2%) 7.3 KiB
Claude Live turn WebSocket wire 6.4 KiB 6.4 KiB −14 B (−0.2%) 7.8 KiB
Claude Live turn WebSocket decoded 56.4 KiB 56.4 KiB −44 B (−0.1%) 66.4 KiB
Claude Live turn messages 11 10 −1 (−9.1%) 21

Baseline: 5e63aea · PR result: fe5480b · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the web UI changes (RightPanelTabs, PreviewChromeRow/PreviewView, PreviewMoreMenu, IntegrationsSettings, menu.tsx) against the shared primitive contracts. Two consistency findings, both inline.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/settings/IntegrationsSettings.tsx Outdated
Comment thread apps/web/src/components/ui/menu.tsx Outdated
@juliusmarminge
juliusmarminge marked this pull request as ready for review August 16, 2026 21:36
Comment thread apps/web/src/components/preview/PreviewView.tsx Outdated
Comment thread apps/desktop/src/ipc/methods/preview.ts Outdated
@macroscopeapp

macroscopeapp Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR adds a cross-layer browser-profile capability that changes session partitioning, cookie/login isolation, storage deletion, and the default profile used for implicit preview opens. Its new configurable product default and sensitive browser-storage behavior warrant human review.

You can add or adjust custom eligibility rules. Learn more.

@github-actions github-actions Bot added the 📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. label Aug 16, 2026
Comment thread packages/contracts/src/browserProfile.ts
Comment thread packages/contracts/src/browserProfile.ts Outdated
Comment thread apps/web/src/components/settings/IntegrationsSettings.tsx
Comment thread apps/web/src/browser/openFileInPreview.ts Outdated
Comment thread apps/web/src/components/RightPanelTabs.tsx Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two findings in the changed web UI. The MenuSubTrigger icon treatment added in this revision fixes the alignment of the new Browser sub-trigger, but the selector it uses also matches the trailing chevron on the two existing icon-less sub-triggers and overrides their ms-auto.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/ui/menu.tsx Outdated
Comment thread apps/web/src/components/preview/PreviewView.tsx Outdated
Comment thread apps/web/src/components/settings/IntegrationsSettings.tsx
Comment thread apps/web/src/components/settings/IntegrationsSettings.tsx
Comment thread apps/web/src/components/settings/IntegrationsSettings.tsx Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the new profile badge in the preview chrome row: the truncate cap doesn't actually ellipsize because Badge is a flex container. Everything else in scope (the MenuSubTrigger icon-column fix, the MenuGroup/MenuGroupLabel wrapping in PreviewMoreMenu, the profile list rows reusing SettingsRow/ITEM_ROW_INNER_CLASSNAME/DraftInput/Button/AlertDialog, and the Select for the default profile) follows the existing primitives and settings conventions.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/preview/PreviewView.tsx Outdated
@github-actions github-actions Bot removed the 📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. label Aug 17, 2026
Comment thread packages/contracts/src/ipc.ts
Comment thread apps/web/src/components/settings/IntegrationsSettings.tsx Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One convention finding: the new browserProfile module (and its test) uses the consolidated import { Schema } from "effect" form instead of the subpath namespace import used by the rest of packages/contracts. Everything else in the diff (service interfaces on BrowserSession/PreviewManager, Schema.TaggedErrorClass errors with structural attributes, make/layer shape, dependency acquisition) matches the conventions.

Posted via Macroscope — Effect Service Conventions

Comment thread packages/contracts/src/browserProfile.ts Outdated
Comment thread packages/contracts/src/browserProfile.test.ts Outdated
Comment thread apps/web/src/components/settings/IntegrationsSettings.tsx
juliusmarminge and others added 4 commits August 28, 2026 22:58
The wrapper-level dim stacked with each control's own: the rename field and
remove button composited to roughly 0.41 alpha while every other disabled
control in the desktop-only block sits at 0.64. Only the built-in row's name
and badge lack a disabled treatment, so the dim belongs there.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Profile names are user-supplied and run to 48 characters. The Browser
sub-menu rendered them bare inside an unbounded popup, so a long one widened
it to fit-content and wrapped; it is now capped and truncated like the other
name-bearing menus.

The clear actions repeated the name their own group heading already shows,
which drove the popup far past its width for no added information. The heading
keeps the profile and the actions keep fixed-length labels.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Bare rows stack on narrow viewports with a larger gap inside a row than
between rows, so the remove button read as belonging to the profile below.
Each profile is now a bounded row, and the list carries the bottom spacing
`SettingsRow` leaves to its children.

`MenuGroupLabel` renders a block box, so `text-overflow` on an inline span
inside it never applied and a long profile name pushed the popup past its
width. The truncation sits on the label itself.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A tab created before profiles existed carries no profile of its own and runs
in the built-in `default` partition — the scope the browser used before
profiles. It was labelled with, and cleared against, whatever profile is
configured as the default now, so on a machine with a custom default the
active tab's data was left untouched while another profile's was wiped.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added the 📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. label Aug 29, 2026

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two UI-consistency findings in the changed web code; details inline.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/settings/IntegrationsSettings.tsx Outdated
Comment thread apps/web/src/components/RightPanelTabs.tsx

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is ON, but a cloud agent failed to start.

Reviewed by Cursor Bugbot for commit 2d10153. Configure here.

Comment thread apps/web/src/components/settings/IntegrationsSettings.tsx Outdated
@github-actions github-actions Bot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:XL 500-999 changed lines (additions + deletions). labels Aug 29, 2026
Comment thread apps/desktop/src/ipc/methods/preview.ts Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding: the remove-profile tooltip that explains why removal is unavailable can never be shown, because its trigger is the disabled button itself.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/settings/IntegrationsSettings.tsx
Comment thread apps/web/src/components/settings/IntegrationsSettings.tsx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. size:XXL 1,000+ changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant