Skip to content

fix(opencode): point agents at T3's browser instead of OpenCode's - #50

Merged
ScriptedAlchemy merged 6 commits into
mainfrom
fix/opencode-t3-browser
Nov 4, 2026
Merged

ScriptedAlchemy merged 6 commits into
mainfrom
fix/opencode-t3-browser

Conversation

@ScriptedAlchemy

@ScriptedAlchemy ScriptedAlchemy commented Nov 3, 2026 •

Copy link
Copy Markdown
Owner

OpenCode agents running under T3 couldn't use a browser. OpenCode 2.x ships its own browser.* tools, which only work when OpenCode's desktop app attaches, so OpenCode denies them by default. T3's full-access * allow rule switched them back on. In a DeepSeek research thread, the agent called browser.tabs.open, got [browser.disconnected] No desktop browser is connected, and never found T3's preview_* tools. OpenCode's system prompt never mentioned preview_*, though Codex and ACP prompts do.

Fix

  • Both OpenCode 1 and 2 receive the existing T3 browser instructions only when the T3 MCP connection is confirmed and browserToolsAvailable is enabled.
  • Full-access sessions start with explicit native browser and browser-skill denies. For existing sessions on external OpenCode servers, preserve the exact native browser rules, their ordering, and duplicate attachment grants. Native deny rules cannot be undone by a remembered T3 approval.
  • Follow native permission events, invalidate cached permissions after a stream gap, and refresh before the next write. If a desktop permission event lands while that write is in flight, write again from the newer snapshot so the server does not keep the stale allow list. Treat a successful snapshot with omitted permissions as a known empty list.
  • Fresh forks and newly announced child sessions lose inherited browser access. Explicit browser and skill allows are removed. A remaining * allow, which last-match-wins back onto the browser, gets an explicit browser and skill deny on both managed and external servers. A child with no browser rule and no * allow is left as OpenCode reported it.
  • Keep ownership of the T3 MCP registration across transient stream reconnects, so the next turn can reconnect failed transports and unload can remove the registration.

Validation

  • vp test run apps/server/src/orchestration-v2/Adapters/OpenCode2AdapterV2.test.ts: 105 passed.
  • vp test run apps/server/src/orchestration-v2/OpenCode2OrchestratorV2.integration.test.ts: 9 passed.
  • vp test run packages/provider-opencode: 157 passed across 15 files.
  • The recorded nested-background replay (opencode2_nested_background) passes with the child * deny appended.
  • vp run check:changed origin/main passed format, lint, both knip passes, GraphQL, typecheck of 10 packages, and 166 tests across 4 files.
  • The child * deny failed first as a replay timeout: the adapter never sent session.update. The mid-update rewrite failed first as OpenCodeReplayMismatchError (the next call was session.instructions.entry.put, not the corrective update).

Native permission snapshots are the authority available to T3. Replacing the whole native permission array is not atomic against another client, and a preserved allow on an existing session does not independently establish browser liveness.

The instruction text itself is unchanged; it's existing text now also sent to OpenCode. I didn't run the paid mcp-tool-use eval.

Related, not in this PR: OpenCode 2.x asks once which third-party search provider (Exa, Firecrawl, Parallel, …) to use before its websearch tool works. In the reported thread, an answer arrived 16 ms after the prompt appeared, and OpenCode then stored web search as disabled. It is unclear how; the user did not choose to disable it. Fixed locally by pinning "websearch": { "provider": "exa" } in the OpenCode config, which skips the prompt and needs no API key.

Claude Opus 5.5 via Claude Code in T3 Code.

🤖 Generated with Claude Code

Follow-up review and repairs: GPT-6 Astra Pro through ChatGPT coding tools.

Child full-access deny and mid-update rewrite: Grok 4.7 via Cursor.

OpenCode denies its own browser tool until its desktop app attaches, but
T3's full-access `*` allow re-enabled it. Agents reached for a browser that
can never connect under T3 and never found `preview_*`. Re-deny the browser
tool and skill in full-access sessions, and give OpenCode the T3 browser
instructions Codex and ACP already get when browser access is enabled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: f7393e0

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Scope native browser denies to T3-managed OpenCode 2 servers and retain external desktop browser access. Add the existing T3 browser instructions to OpenCode 1 turns only when its MCP connection and browser capability are available. Cover managed/external resume and disconnected/disabled browser states.

Validated with 170 OpenCode tests and direct provider/server typechecks.

Reviewed and repaired with GPT-6 Astra Pro through ChatGPT coding tools.
ScriptedAlchemy and others added 3 commits November 3, 2026 14:20
A child that inherits only a `*` allow kept OpenCode's browser, because stripping explicit browser allows does nothing to that rule. A desktop permission event during session.update could also leave the stale allow list on the server while the local cache moved on.

Co-Authored-By: Grok 4.7 <noreply@x.ai>
Co-authored-by: Cursor <cursoragent@cursor.com>
@ScriptedAlchemy
ScriptedAlchemy merged commit f85c2a8 into main Nov 4, 2026
16 checks passed
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