Skip to content

feat(extension): drop eager groupNew on SESSION_START β€” connection-default lane should only exist if explicitly requested via group_id="new"Β #53

Description

@apireno

Goal

Stop the eager groupNew(["agent"]) call in the WS bridge's SESSION_START handler. The connection-default lane (the Chrome tab group with one about:blank tab, titled 🐚 agent) that's currently auto-created on every MCP initialize should not exist. Isolation should happen only when the agent explicitly requests it via group_id="new".

Why this is the right fix

A QA-UX integrator team reported that orphan agent tab groups accumulate across connection cycles β€” unattributable to which client created them, never reaped on disconnect, and visually cluttering the operator's Chrome with about:blank placeholders. The memo (docs/handovers/MEMO-connection-default-lane-naming-and-lifecycle-20260619.md) traces it back to the eager groupNew in SESSION_START.

The memo proposes 5 fixes: name the lane from clientInfo.name, reap on disconnect, auto-close never-navigated lanes, expose lane metadata + group gc, lazy creation. All 5 collapse into one structural change: don't create the lane eagerly. Nothing to reap if it never gets created.

Walking through their asks against the proposed change:

Memo ask Status under this fix
Name from clientInfo.name Lane doesn't exist to be named. βœ…
Reap on disconnect Nothing to reap. βœ…
Auto-close never-navigated lanes No about:blank placeholder lanes exist. βœ…
Lane metadata / group gc Lanes that DO exist (explicit group_id="new") are already attributable by name + id. Their integrators sweep them today.
Lazy creation This is exactly that, taken to the logical conclusion. βœ…

The change

src/background/index.ts:544-562 β€” the SESSION_START handler currently does:

if (msg.type === "SESSION_START") {
  await runSerialized(async () => {
    await swapToSession(mcpSid);
    groupMode = "shared";
    sessionGroupId = null;
    sessionGroupName = null;
    sessionGroupDisrupted = false;
    await groupNew(["agent"]);           // ← DELETE THIS LINE
    mcpSessionActive = true;
  });
  return;
}

That's it. Delete the one line.

Effects:

  • windows/tabs/here/group list β†’ returns the user's actual browser state (currently returns just the agent's 1 about:blank tab)
  • group_id="new" β†’ still creates an isolated lane (createAgentLane() unchanged)
  • group_id="<numeric-id>" β†’ still attaches to that lane (swapToAgentLane() unchanged)
  • group_id="shared" / omitted β†’ runs in true shared mode against the user's browser, no Chrome tab group created
  • No about:blank tab created on connect. No agent group. No accumulation.

Semantic shift summary

This is a deliberate behavior change for callers using group_id="shared" or omitted-group_id. The two paths that DO change:

Caller Today After this change
domshell_execute({command:"windows"}) (omitted) shows the agent's 1 about:blank tab shows the user's actual windows
domshell_execute({command:"click submit_btn", group_id:"shared"}) clicks something in the agent's about:blank (= no-op) clicks submit_btn in whatever tab the user is currently on β€” real side effects on the user

The two paths that DON'T change (and cover every well-behaved integrator we know of):

Caller Today and after
domshell_execute({..., group_id:"new", initial_url:"...", group_name:"qa-ux"}) works exactly as today β€” creates a named isolated lane with the URL loaded
domshell_execute({..., group_id:"<numeric id>"}) works exactly as today β€” joins that lane

Migration story

Already partially deployed:

  • Deprecation cycle started in 2.0.2 (2026-05-31): omitted group_id emits a [DEPRECATION] warning. Integrators have been seeing this for ~3 weeks.
  • 2.0.6 (just shipped, 2026-06-19): the deprecation reply text now telegraphs BOTH the upcoming hard-error AND this semantic shift, with an explicit migration directive ("pass group_id="new" on every call that needs an isolated lane"). The MCP_INSTRUCTIONS LANES section similarly elevates "new" to recommended and adds an IMPORTANT SEMANTIC NOTE on "shared".
  • Extension 1.3.2 (this issue): kernel change ships. The advance notice integrators have been receiving becomes the actual behavior.
  • DOMShell 3.0.0 (future): omitted group_id becomes a hard error per the existing deprecation plan.

Integrator impact survey

  • CLI-Anything (HKUDS PR #308 integrator) β€” unaffected. Their _call_execute always sets an explicit group_id ("new" or a captured numeric id) and never uses "shared" or omitted. Verified at domshell_backend.py:548-552. Their test suite stays green; no coordinated release required.
  • QA-UX integrator (the memo's author) β€” explicitly benefits. Their cleanup janitor's "self-reap on exit" becomes unnecessary because the lane it was reaping no longer exists. They can simplify integrator-side code in their next sprint.
  • Claude Desktop and ad-hoc agents β€” these are the integrators that may currently be using group_id="shared" or omitted. The 2.0.6 deprecation messaging is their advance notice; the [DEPRECATION] warning has been firing for them since 2.0.2.

Bundling

Queued for the next CWS-justifying extension release alongside:

6 kernel fixes in one CWS submission. This issue is the smallest of the six (one-line delete) but arguably the highest user-visible impact.

Tests

  • After change: a fresh MCP session that connects-and-disconnects without any tool calls leaves zero Chrome tab groups
  • After change: domshell_execute({command:"windows"}) with no group_id returns the user's actual windows (not 1 agent)
  • After change: domshell_execute({command:"ls", group_id:"new", group_name:"x", initial_url:"https://example.com"}) creates a single Chrome tab group titled x with example.com loaded (existing feat(extension): honor initial_url for group_id="new" β€” eliminate about:blank placeholder on lane creationΒ #52 behavior β€” verify nothing here regresses)
  • After change: subsequent calls with group_id=<that numeric id> attach to the same group (existing behavior)

Related issue / handover

docs/handovers/MEMO-connection-default-lane-naming-and-lifecycle-20260619.md β€” the QA-UX integrator memo that triggered this. Their asks 2–5 are intentionally out of scope; the structural fix here subsumes them all.

Server-side advance-notice work shipped as MCP server 2.0.6 (commit a8b4972).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions