Skip to content

local Chrome connect: classify state, defer marker tab, stay in selected profile#455

Open
laithrw wants to merge 1 commit into
mainfrom
improve-browser
Open

local Chrome connect: classify state, defer marker tab, stay in selected profile#455
laithrw wants to merge 1 commit into
mainfrom
improve-browser

Conversation

@laithrw

@laithrw laithrw commented Jun 18, 2026

Copy link
Copy Markdown
Member
  • Classify the connection up front (browser.py): read DevToolsActivePort + Local State and return ok / cdp-disabled / permission-blocked / browser-closed in ~0.01s, without opening a tab. Each blocked state's error carries its own fix, so the agent relays one line and retries instead of hanging or exploring.
  • Defer the marker tab until after the websocket connects, so a failed connection doesn't leave a stray tab.
  • Reuse stays in the right profile: on daemon reuse, verify the controlled tab still belongs to the selected context and re-anchor if it drifted or closed (verify_profile). On a stale session, re-attach the same tab instead of grabbing an arbitrary page.
  • admin.py routing: a 403 is permission-blocked on its own (focus the profile, don't tell the user to re-tick the checkbox); browser-closed opens/focuses the selected profile.

Summary by cubic

Make local Chrome connections fast, reliable, and profile-aware. We classify CDP state up front, avoid stray tabs on failure, and keep the daemon anchored to the user-selected profile across runs.

  • New Features

    • Instant local connection classification from DevToolsActivePort + Local State; returns ok/cdp-disabled/permission-blocked/browser-closed with one-line, actionable errors (no tab is opened).
    • Marker tab deferred until after the WebSocket connects, so failed connects don’t leave stray tabs.
    • Profile pinning across reuse: verify and re-anchor the controlled tab to the selected browserContextId; reattach the same tab on stale sessions; refuse cross-profile target switches.
    • Admin routing: 403 is treated as permission-blocked (focus/open the selected profile), and browser-closed opens/focuses the profile instead of prompting to re-tick the checkbox.
    • Native local profile/browser detection (no profile-use dependency) and new CLI: local-profiles, local-browsers, default-profile, and profile-target; helper profile_marker; daemon supports create_target and verify_profile.
  • Migration

    • When multiple local profiles exist, do not auto-pick. Use browser-harness local-profiles and browser-harness default-profile before any page work (only set a default after the user chooses).
    • Remove BH_CLOUD_ONLY if you set it; it’s no longer used.
    • profile-use is no longer required for local profile discovery.

Written for commit ff04926. Summary will update on new commits.

Review in cubic

…selected profile

- Classify the connection up front (browser.py): read DevToolsActivePort + Local State and return ok / cdp-disabled / permission-blocked / browser-closed in ~0.01s, without opening a tab. Each blocked state's error carries its own fix, so the agent relays one line and retries instead of hanging or exploring.
- Defer the marker tab until after the websocket connects, so a failed connection doesn't leave a stray tab.
- Reuse stays in the right profile: on daemon reuse, verify the controlled tab still belongs to the selected context and re-anchor if it drifted or closed (verify_profile). On a stale session, re-attach the same tab instead of grabbing an arbitrary page.
- admin.py routing: a 403 is permission-blocked on its own (focus the profile, don't tell the user to re-tick the checkbox); browser-closed opens/focuses the selected profile.
- Drop the BH_CLOUD_ONLY env var and its guard.
@browser-harness-review

Copy link
Copy Markdown

✅ Skill review passed

Reviewed 1 file(s) — no findings.

@cubic-dev-ai cubic-dev-ai 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.

2 issues found across 7 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/browser_harness/browser.py">

<violation number="1" location="src/browser_harness/browser.py:194">
P2: Dia's user data directory is inconsistent: PROFILE_ROOTS uses `.../Dia/User Data`, but `_known_browser_installs()` registers Dia with `.../Dia` (missing `User Data`). This causes missed profile discovery for Dia.</violation>
</file>

<file name="src/browser_harness/run.py">

<violation number="1" location="src/browser_harness/run.py:178">
P2: `default-profile --browser NAME` is silently ignored in the read path</violation>
</file>

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

("Microsoft Edge", Path("/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge"), home / "Library/Application Support/Microsoft Edge"),
("Chromium", Path("/Applications/Chromium.app/Contents/MacOS/Chromium"), home / "Library/Application Support/Chromium"),
("Arc", Path("/Applications/Arc.app/Contents/MacOS/Arc"), home / "Library/Application Support/Arc/User Data"),
("Dia", Path("/Applications/Dia.app/Contents/MacOS/Dia"), home / "Library/Application Support/Dia"),

@cubic-dev-ai cubic-dev-ai Bot Jun 18, 2026

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.

P2: Dia's user data directory is inconsistent: PROFILE_ROOTS uses .../Dia/User Data, but _known_browser_installs() registers Dia with .../Dia (missing User Data). This causes missed profile discovery for Dia.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/browser_harness/browser.py, line 194:

<comment>Dia's user data directory is inconsistent: PROFILE_ROOTS uses `.../Dia/User Data`, but `_known_browser_installs()` registers Dia with `.../Dia` (missing `User Data`). This causes missed profile discovery for Dia.</comment>

<file context>
@@ -0,0 +1,777 @@
+        ("Microsoft Edge", Path("/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge"), home / "Library/Application Support/Microsoft Edge"),
+        ("Chromium", Path("/Applications/Chromium.app/Contents/MacOS/Chromium"), home / "Library/Application Support/Chromium"),
+        ("Arc", Path("/Applications/Arc.app/Contents/MacOS/Arc"), home / "Library/Application Support/Arc/User Data"),
+        ("Dia", Path("/Applications/Dia.app/Contents/MacOS/Dia"), home / "Library/Application Support/Dia"),
+        ("Comet", Path("/Applications/Comet.app/Contents/MacOS/Comet"), home / "Library/Application Support/Comet"),
+        ("Helium", Path("/Applications/Helium.app/Contents/MacOS/Helium"), home / "Library/Application Support/Helium"),
</file context>
Suggested change
("Dia", Path("/Applications/Dia.app/Contents/MacOS/Dia"), home / "Library/Application Support/Dia"),
("Dia", Path("/Applications/Dia.app/Contents/MacOS/Dia"), home / "Library/Application Support/Dia/User Data"),
Fix with cubic
browser = rest[i + 1]; i += 2; continue
print("usage: browser-harness default-profile [--profile NAME_OR_ID] [--browser NAME] [--json]", file=sys.stderr)
sys.exit(2)
selected = native_set_default_profile(profile, browser_name=browser) if profile else native_default_profile()

@cubic-dev-ai cubic-dev-ai Bot Jun 18, 2026

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.

P2: default-profile --browser NAME is silently ignored in the read path

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/browser_harness/run.py, line 178:

<comment>`default-profile --browser NAME` is silently ignored in the read path</comment>

<file context>
@@ -99,6 +119,72 @@ def main():
+                browser = rest[i + 1]; i += 2; continue
+            print("usage: browser-harness default-profile [--profile NAME_OR_ID] [--browser NAME] [--json]", file=sys.stderr)
+            sys.exit(2)
+        selected = native_set_default_profile(profile, browser_name=browser) if profile else native_default_profile()
+        if as_json:
+            import json
</file context>
Suggested change
selected = native_set_default_profile(profile, browser_name=browser) if profile else native_default_profile()
selected = native_set_default_profile(profile, browser_name=browser) if profile else native_default_profile(browser_name=browser)
Fix with cubic
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant