Repository navigation
fix(server): t3_preview_list and t3_preview_close see the thread's Environment browser tabs - #201
Merged
Merged
Conversation
immakermatty
marked this pull request as ready for review
November 14, 2026 20:09
immakermatty
force-pushed
the
agent/environment-browser-thread-tabs
branch
from
November 14, 2026 20:09
b561a1a to
ee40e14
Compare
…vironment browser tabs
With the Environment browser, a thread's tabs live in its strip (the holder file of
threadTabs.ts), which upstream's PreviewManager never sees. t3_preview_list answered
an empty list, and t3_preview_close fell through to PreviewManager.close, which does
nothing for an unknown tab and answered {}, so the tab stayed in the strip.
The host now hands /mcp the thread's strip, through a reference whose default keeps
upstream's behavior and which overlay.ts provides from the same host and strips as
its routes. t3_preview_list lists the strip's tabs as server sessions with their
address, title and view (one Target.getTargets call, so a busy page still answers),
and preview_status carries the same tabs. t3_preview_close sends close to the host
for a tab the thread holds, which lets go of it through threadTabs.release, and
refuses a tab the thread does not hold instead of answering {}.
Fixes #200
Claude Opus 5.5 in Claude Code (T3 Code).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
immakermatty
force-pushed
the
agent/environment-browser-thread-tabs
branch
from
November 14, 2026 21:33
ee40e14 to
b64c1aa
Compare
6 of 9 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Status: in progress (draft)
Problem
With the Environment browser, a thread's tabs live in its strip:
ThreadTabsinapps/server/src/lazurio/threadTabs.ts, persisted in the holder file$XDG_RUNTIME_DIR/lazurio-browser/holders/t3-<thread>.json. The handlers oft3_preview_listandt3_preview_close(apps/server/src/mcp/toolkits/previewControls/handlers.ts) read only upstream'sPreviewManager, which the overlay never writes:t3_preview_listansweredsessions: []while the thread held tabs.t3_preview_closesentcloseto the broker only for a server sessionPreviewManagerknew, and otherwise fell through tomanager.close, which does nothing for an unknown tab and answered{}. The overlay'sclose(threadTabs.release) never ran, and the tab stayed in the strip.Fix
environmentBrowser.ts) hands out the thread's strip asEnvironmentBrowserTabs(lazurio/environmentBrowserTabs.ts). This is aContext.Referencewhose default lists nothing, so without the Environment browser, and in every upstream test, the handlers behave exactly as upstream.overlay.tsbuilds the host and the strips once andserver.tsprovides the same layer to/mcp(LazurioOverlay.withEnvironmentBrowserTabs(McpHttpServer.layer)). The memoized layer shares one host and one set of strips with the overlay's routes.Target.getTargetscall (connection.pages()), not from evaluating in every page, so a busy page or one with an open dialog does not stall the list.t3_preview_list: where the Environment declares its browser, the strip's tabs come first as server sessions (tabId,navStatuswithurlandtitle,runtime: "server", andview=https://browser.…/t/<tabId>, aspreview_openanswers), followed by anyPreviewManagersessions. The tool's success schema gains the optionalviewfield.t3_preview_close: a tab in the thread's strip goes to the broker asclose, which the host turns intothreadTabs.release. On a strip, a tab that the thread holds neither in the strip nor inPreviewManageris refused withinvalid_requestinstead of{}. Without a strip, upstream's path is unchanged.preview_statuscarries the same strip astabs(tabId,url,visible).lazurio-fork-ci.ymlgains the twopreviewControlsfiles, the release contract test checks the new seams inoverlay.ts,server.tsand the host, anddocs/operations/lazurio-overlay.mdgets one sentence. Tool descriptions stay as they are, because none of them is untrue after the fix.Verification
apps/server/src/lazurio/environmentBrowser.test.tsruns the real broker, the real host over the fake browser, the realThreadTabson a temporaryXDG_RUNTIME_DIR, and the realPreviewControlshandlers. It runspreview_open×3, then checks that the list has 3 tabs with URL, title and view and that the holder file holds 3. It closes 1 and checks that the list and the holder file hold 2, thatpreview_statustabsshows the same 2 and that the window stays open. Closing the released tab again returnsOrchestratorMcpFailure invalid_request, and the holder file stays at 2. With upstream'shandlers.tsthe case fails exactly as in the issue:expected { sessions: [] … }.vp test run src/lazurio src/mcp/toolkits/previewControls src/mcp/PreviewAutomationBroker.test.ts src/mcp/McpHttpServer.test.ts: 41 files, 552 tests passed (15 skipped, as on main).vp run typecheck(apps/server): passed.node --test scripts/lazurio-release-contract.test.mjs: 52/52.vp run check:changed: format, lint, knip, graphql and typecheck passed.src/provider/AgentContextBudget.test.tsfails with the same numbers with or without this change (codexAdditionalContextBytes8838 vs 7327,mcpToolListJsonBytes48399 vs 48217 inagentContextBudget.json), because the budget measures tool descriptions and input schemas, which this PR does not change. The mismatch is already onorigin/mainand is not addressed here.Open
docs/operations/lazurio-fork-release.md, "Cílový stack": this commit belongs to row 10 (and touchesoverlay.ts* of row 11). By §9 the stack gets commits that landed after the swap in the post-release PR, so it is not edited here.Fixes #200
Agent: environment a480495c-25e0-4e51-828b-1dbf1b77d62f · T3 thread thread:delegated-task:command%3Amcp%3Abd2c9a58-fde8-46a0-b4c7-a6abe8e94735%3Adelegate-task%3Aea52843b-643d-4e8a-a3d8-88b6ea81a654
🤖 Generated with Claude Code
Note
Show the thread's Environment browser tabs in
t3_preview_listandt3_preview_closeEnvironmentBrowserTabsservice that lists a thread's browser strip, built from the CDP target listing in environmentBrowserConnection.ts and themakeservice in environmentBrowser.tst3_preview_listnow prepends strip tabs to PreviewManager sessions and paginates the combined list, with a view URL on each session (see handlers.ts)t3_preview_closecan close a tab held by the thread's strip via the broker; when a strip is available and the ID matches neither the strip nor a server session, it returns aninvalid_requestfailureLazurioOverlay.withEnvironmentBrowserTabsin overlay.ts and server.ts, and covers the flow with an integration test and updated docsEnvironmentBrowserConnectionimplementations must now provide apagesoperation; strip-list failures surface asorchestration_errorMCP failuresMacroscope summarized b561a1a.