The Installed tab could only update one plugin at a time, one dialog and one watched job each. This adds the bulk action beside the list it acts on — the same place Sources keeps "Refresh all" — plus a count badge on the Installed tab trigger, because Browse is the tab the page opens on and a control nobody passes is a control nobody finds. The host takes ONE package operation at a time (409 otherwise: bun operations share a lockfile and a node_modules tree), so this is a queue the console works through job by job, driven by each job settling rather than by a timer. The run carries its own copy of what is left: every finished install invalidates the installed list, and a queue that re-derived itself would change shape underneath a run the operator already confirmed. Trust rules are unchanged, only taken once instead of N times. If any entry in the run comes from an operator-added source the whole dialog wears the external treatment and names those catalogs — a bulk action must not be a way to wave through, in one click, a warning each package would have shown on its own. The dialog lists every version change rather than a count, and names what it will not attempt: an update with no catalog entry, or one this host would refuse (400 on incompatible, blocked entries) never enters the queue, so the button's count still adds up on screen. A failure ends the run. The failed job's card is the only record of what went wrong, and starting the next install would replace it with a fresh spinner; the toast says what was applied and what was not, and the rows are still there to retry from. Also fixed, because this change leans on it: disabled buttons were invisible. AnimatedButton is a motion element and its mount animation settles as an inline `opacity: 1`, which outranks the `disabled:opacity-50` class the library also ships — measured `opacity: 1` on a disabled button, console-wide. Only `pointer-events: none` landed, so every disabled control in the app looked live and silently ignored the click. Corrected in the components/ui wrapper layer like the other @unom/ui adaptations. Verified: tsc, biome, `bun test server/`, production build, i18n check (650 messages, en + de). Storybook stories added for the list header and the confirm dialog; both rendered headless in light and dark, with the disabled states asserted on the DOM rather than by eye.