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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant