Skip to content

fix(web): the right panel opens on the thread's tab, not on Nová karta beside it - #57

Merged
immakermatty merged 1 commit into
mainfrom
agent/DEV-6646-first-load-thread-tabs
Oct 12, 2026
Merged

immakermatty merged 1 commit into
mainfrom
agent/DEV-6646-first-load-thread-tabs

Conversation

@immakermatty

Copy link
Copy Markdown

Problem

A thread's agent opened a page, but the right panel did not show it. The panel opened on the empty Nová karta, and the strip had a "Browser" tab beside it that showed nothing.

This happens whenever a thread's first snapshot after it comes into view already lists the agent's tab. That covers opening the thread after the agent opened the page, reloading the page, or a client that reconnects. The first snapshot is a baseline of reveals by design: a reload never opens the panel by itself. The strip's reconciliation then added the tab but kept an empty selection. When the person opened the panel, RightPanelTabs showed the empty panel's Nová karta (activeSurfaceId === null). The frames of the strip's tabs only mount beside a selected surface, so the tab never loaded. Its title stayed "Browser".

We reproduced it on a canary Environment running preview 0.0.45-preview.20261012.3:

  • fresh page on a thread whose agent had opened a page → panel on Nová karta, no frame;
  • switching to another thread and back → the tab shows. Upstream's reconcileBrowserSurfaces effect selects the first surface on a thread change, which hid the bug there.

A live reveal (the thread in view while the agent opens a page) already worked and still works. On the same canary, a new thread's agent opened a page and the panel opened on it by itself.

Fix

reconcileThreadTabs now selects the first Environment browser tab when nothing is selected or the selected surface went. This is the same rule upstream's reconciliation uses for its browser (fallbackBrowser ?? surfaces[0]).

  • It also applies when the list brings nothing new. A panel stored without a selection, for example by a client running the previous build, recovers on the next snapshot.
  • Another Environment's tab added behind (withSurface, the foreign event without a reveal) follows the same rule. An open panel on the empty Nová karta used to keep it, and now selects that tab.
  • A closed panel stays closed. Only a live reveal opens it, as before.

The runbook's paragraph on the web's strip states the rule.

What does not change

  • Reveals: the first snapshot after a thread comes into view is still a baseline. No panel opens by itself on a reload.
  • A tab the device already shows stays the device's choice. Pending holds, Nová karta tabs and other Environments' tabs are kept as before.
  • The desktop app keeps upstream's panel.

Verification

  • vp test run src/lazurio/threadTabs.test.ts src/lazurio/LazurioEnvironmentBrowser.test.tsx src/lazurio/LazurioNewTab.test.tsx: 51 passed.
  • The three new tests fail on the previous threadTabs.ts (3 failed, 23 passed) and pass with the fix:
    • the strip selects a tab where nothing is selected;
    • another Environment's tab is selected where nothing is;
    • a thread that comes into view with its agent's tab leaves it selected, and the panel the person opens shows it.
  • vp lint, vp fmt --check on the changed files, vp run --filter @t3tools/web typecheck, node --test scripts/lazurio-release-contract.test.mjs (22 passed).
  • Browser check: after merge, in the next preview on the canary Environment, following the fork runbook (preview → canary → browser check → stable). No screenshots here: the evidence comes from a client Environment, and this repository is public.

Follow-up

The agents' instructions in the Lazurio Folder manual (LazurioPlatform) will explain how the Environment browser presents a page in each client. That covers a plain link, the view of a remote tab, and the thread's tab in the panel. It is a separate change.

🤖 Generated with Claude Code (Claude Opus 5.5)

…a beside it

A thread whose first snapshot already lists its agent's tab (it comes into view, or
the page reloads, after the agent opened a page) added the tab to the strip with
nothing selected: the first snapshot reveals nothing, and the strip's reconciliation
kept an empty selection. The panel then opened on the empty Nová karta beside a
"Browser" tab whose frame it never loaded, so the agent's page looked missing.

The strip after the server's list now selects its first Environment browser tab
where nothing is selected or the selected surface went, as upstream's reconciliation
does for its browser, even when the list brings nothing new (a panel stored without
a selection). Another Environment's tab added behind follows the same rule. A closed
panel stays closed; a live reveal still opens it.

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

@agentrozjedemeai agentrozjedemeai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@immakermatty Approved on exact head 4e7eef7. The reconciliation now selects a surviving Environment browser surface when selection is absent or removed, without opening a closed panel; a selected real Nová karta remains the user choice. The first snapshot remains a reveal baseline. The release runbook describes this selection rule and retains the separate no-auto-open rule. In a clean isolated clone: 51 focused tests passed, 4 additional reviewer edge-case tests passed, targeted lint and format passed, web typecheck passed, release contract passed (22), and git diff --check passed. Live CI: 4 successful jobs, 2 skipped advisory jobs; no unresolved threads. Canary/browser verification and stable release remain post-merge gates, not claims of this review.

@immakermatty
immakermatty merged commit a4d5040 into main Oct 12, 2026
6 checks passed
@immakermatty
immakermatty deleted the agent/DEV-6646-first-load-thread-tabs branch October 13, 2026 19:21
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.

2 participants