Problem
Switching to a view- or app-plugin tab shows a blank panel with no loading affordance. There is no spinner, no skeleton, no disabled state — the tab simply renders empty until (or unless) content arrives. During the PR #49 interactive smoke this was actively harmful: a genuinely broken tab (view-plugins could not load on Windows at all, fixed in 55b0a5b) was indistinguishable from a slow one, and the first read was "it is probably still loading".
Operator, during Smoke run 2:
It's blank, but I assume it's mostly taking a while to load. We should create an open issue to refactor our loading model. I don't want to have to wait for tabs to load independently. We should either have UX to indicate loading and make them unavailable, or load everything at once, whichever is the better user experience.
A second, related gap: failures are silent
plugin_launch returns "dispatched", not "healthy" (manager.rs:161) — deliberately, so the UI does not freeze. But nothing renders the failure path. In Smoke run 2 an AUDIENCE launch failed outright on a container-name conflict:
Container audience-redis-1 Error response from daemon: Conflict.
The container name "/audience-redis-1" is already in use ...
and the UI showed nothing at all — no chip, no error state. There is no rejected promise to catch, and the background failure never reaches the shell. A user cannot tell "starting", "failed" and "idle" apart. (Recorded as D-5 in spikes/SPIKE-RESULTS.md -> Smoke run 2.)
Options to weigh
- Loading affordance per tab — tabs show a lifecycle state and are disabled/non-interactive until ready. Cheapest; keeps lazy loading.
- Eager load everything at switcher mount — no per-tab wait at all. Costs startup time and boots container stacks nobody asked for.
- Hybrid — eagerly load cheap view-plugins, keep expensive app-plugins lazy but always surface their lifecycle state.
Acceptance criteria
Context
Found during the PR #49 interactive smoke (Smoke run 2, 2026-08-15). Not a #49 regression — a pre-existing gap in the shell's loading model that the smoke made impossible to ignore.
Problem
Switching to a view- or app-plugin tab shows a blank panel with no loading affordance. There is no spinner, no skeleton, no disabled state — the tab simply renders empty until (or unless) content arrives. During the PR #49 interactive smoke this was actively harmful: a genuinely broken tab (view-plugins could not load on Windows at all, fixed in 55b0a5b) was indistinguishable from a slow one, and the first read was "it is probably still loading".
Operator, during Smoke run 2:
A second, related gap: failures are silent
plugin_launchreturns "dispatched", not "healthy" (manager.rs:161) — deliberately, so the UI does not freeze. But nothing renders the failure path. In Smoke run 2 an AUDIENCE launch failed outright on a container-name conflict:and the UI showed nothing at all — no chip, no error state. There is no rejected promise to catch, and the background failure never reaches the shell. A user cannot tell "starting", "failed" and "idle" apart. (Recorded as D-5 in
spikes/SPIKE-RESULTS.md-> Smoke run 2.)Options to weigh
Acceptance criteria
plugin://statereaches a visible indicator for every state, includingerrorContext
Found during the PR #49 interactive smoke (Smoke run 2, 2026-08-15). Not a #49 regression — a pre-existing gap in the shell's loading model that the smoke made impossible to ignore.