Say what "open in container" is doing, and land on the pane doing it
Build App (Preview) / compute-version (pull_request) Successful in 4s
Build App (Preview) / create-release (pull_request) Successful in 1s
Build App (Preview) / build-macos (pull_request) Successful in 2m40s
Build App (Preview) / build-linux (pull_request) Successful in 5m33s
Build App (Preview) / build-windows (pull_request) Successful in 5m40s
Build App (Preview) / prune-previews (pull_request) Successful in 1s

Opening a page is a container probe, a browser launch, a page load and
often a viewer start — several seconds during which the only feedback
was the click itself. Worse from a terminal, where the result appears in
a pane the user is not looking at.

So: the backend emits progress on the existing `container-progress`
channel at each step, the Browser tab renders that line whenever it is
set — the progress belongs to the project, not to whoever pressed the
button, which is what lets a terminal-initiated open report anywhere at
all — and the terminal's "In container" now selects the project's
Browser tab before starting, so the line has somewhere to appear.

Selecting a sub-tab from outside needed a route: `ProjectHome` keeps it
in local state, so `openProjectHomeTab` parks a request in the store and
the pane consumes it once. Consumed once, so it cannot fight the user's
own clicking afterwards.

Preview releases now prune themselves to the newest KEEP_PREVIEWS (2),
in a job that runs only if all three platforms published — a
half-finished run must not evict a good older build. The cleanup
workflow's manual sweep stays as the backstop.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-11 11:13:21 -07:00
co-authored by Claude Opus 5
parent 85ea3956e8
commit ab747ce53d
7 changed files with 128 additions and 3 deletions
@@ -189,8 +189,15 @@ pub async fn open_page_in_container_browser(
return Err("Only http:// and https:// URLs can be opened in the browser.".to_string());
}
let container_id = running_container(&state, &project_id, "opening a page").await?;
crate::commands::project_commands::emit_progress(
&app_handle,
&project_id,
"Checking the container for Playwright…",
);
let detection = crate::browser_view::detect::detect(&container_id).await?;
let opened = page::open(
&app_handle,
&project_id,
&container_id,
&detection,
trimmed,
@@ -204,6 +211,11 @@ pub async fn open_page_in_container_browser(
// Asking for a page *is* asking to watch it, so the viewer comes up too.
let status = manager().status(&project_id).await;
if status.state != BrowserViewState::Running {
crate::commands::project_commands::emit_progress(
&app_handle,
&project_id,
"Starting the viewer…",
);
manager()
.start(
project_id.clone(),
@@ -228,6 +240,7 @@ pub async fn open_page_in_container_browser(
}
}
crate::commands::project_commands::emit_progress(&app_handle, &project_id, "");
Ok(opened)
}