Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
338c3ca
fix(web): sidebar update pill shows updates on non-default provider i…
abdurahmon27 Oct 2, 2026
b65ced9
Merge branch 'main' into fix/sidebar-update-pill-provider-instances
abdurahmon27 Oct 3, 2026
3133fd8
Merge branch 'main' into fix/sidebar-update-pill-provider-instances
abdurahmon27 Oct 3, 2026
d1641fa
Merge branch 'main' into fix/sidebar-update-pill-provider-instances
abdurahmon27 Oct 3, 2026
dcac91e
Merge branch 'main' into fix/sidebar-update-pill-provider-instances
abdurahmon27 Oct 3, 2026
48b816d
Merge branch 'main' into fix/sidebar-update-pill-provider-instances
abdurahmon27 Oct 3, 2026
3c38a48
Merge branch 'main' into fix/sidebar-update-pill-provider-instances
abdurahmon27 Oct 3, 2026
1580c83
Merge branch 'main' into fix/sidebar-update-pill-provider-instances
abdurahmon27 Oct 4, 2026
245264e
Merge branch 'main' into fix/sidebar-update-pill-provider-instances
abdurahmon27 Oct 5, 2026
d86f4c1
Merge branch 'main' into fix/sidebar-update-pill-provider-instances
abdurahmon27 Oct 5, 2026
7379494
Merge branch 'main' into fix/sidebar-update-pill-provider-instances
abdurahmon27 Oct 5, 2026
fd8ef7f
Merge branch 'main' into fix/sidebar-update-pill-provider-instances
abdurahmon27 Oct 5, 2026
a949a64
Merge branch 'main' into fix/sidebar-update-pill-provider-instances
abdurahmon27 Oct 5, 2026
4749fa8
Merge branch 'main' into fix/sidebar-update-pill-provider-instances
abdurahmon27 Oct 7, 2026
fcd21cf
Merge branch 'main' into fix/sidebar-update-pill-provider-instances
abdurahmon27 Oct 7, 2026
7b9688a
Merge branch 'main' into fix/sidebar-update-pill-provider-instances
abdurahmon27 Oct 16, 2026
cb372ce
Merge branch 'main' into fix/sidebar-update-pill-provider-instances
abdurahmon27 Oct 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,68 @@ describe("provider update launch notification logic", () => {
});
});

it("shows the active sidebar pill for an update on a non-default instance", () => {
const view = getProviderUpdateSidebarPillView([
provider({ driver: driver("claudeAgent") }),
provider({
driver: driver("claudeAgent"),
instanceId: instanceId("claude_work"),
updateState: {
status: "running",
startedAt: checkedAt,
finishedAt: null,
message: "Updating provider.",
output: null,
},
}),
]);

expect(view).toMatchObject({
key: "loading:claudeAgent:running",
tone: "loading",
title: "Updating Claude",
description: "Claude update in progress.",
});
});

it("shows the latest terminal sidebar pill across instances of a driver", () => {
const view = getProviderUpdateSidebarPillView(
[
provider({
driver: driver("claudeAgent"),
updateState: {
status: "failed",
startedAt: checkedAt,
finishedAt: checkedAt,
message: "Update command exited with code 1.",
output: null,
},
}),
provider({
driver: driver("claudeAgent"),
instanceId: instanceId("claude_work"),
version: "1.1.0",
latestVersion: "1.1.0",
advisoryStatus: "current",
updateState: {
status: "succeeded",
startedAt: laterCheckedAt,
finishedAt: laterCheckedAt,
message: "Provider updated.",
output: null,
},
}),
],
{ visibleAfterIso: sessionStartedAt },
);

expect(view).toMatchObject({
key: "succeeded:claudeAgent:2026-04-23T10:01:00.000Z:Provider updated.",
tone: "success",
title: "Claude updated: v1.1.0",
});
});

it("uses the provider name for single failed sidebar pill updates", () => {
const view = getProviderUpdateSidebarPillView(
[
Expand Down
27 changes: 23 additions & 4 deletions apps/web/src/components/ProviderUpdateLaunchNotification.logic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -448,12 +448,31 @@ function latestFinishedAtForProviders(providers: ReadonlyArray<ServerProvider>):
}, null);
}

/**
* Collapses terminal update states to the most recently finished instance per
* driver, so an update on a non-default instance is not hidden behind an
* older outcome on the driver's default instance.
*/
function latestTerminalProvidersByDriver(providers: ReadonlyArray<ServerProvider>) {
const latestProviderByDriver = new Map<ProviderDriverKind, ServerProvider>();

for (const provider of providers) {
const current = latestProviderByDriver.get(provider.driver);
if (!current || (getUpdateFinishedAt(provider) ?? "") >= (getUpdateFinishedAt(current) ?? "")) {
latestProviderByDriver.set(provider.driver, provider);
}
}

return [...latestProviderByDriver.values()];
}

export function getProviderUpdateSidebarPillView(
providers: ReadonlyArray<ServerProvider>,
options?: ProviderUpdateSidebarPillOptions,
): ProviderUpdateSidebarPillView | null {
const dedupedProviders = dedupeProvidersByDriver(providers);
const activeProviders = dedupedProviders.filter(isProviderUpdateActive);
// Update state is recorded per instance, so pick the instances with an
// update before collapsing to one entry per driver.
const activeProviders = dedupeProvidersByDriver(providers.filter(isProviderUpdateActive));
if (activeProviders.length > 0) {
const activeProvider = activeProviders[0]!;
const activeProviderName =
Expand All @@ -475,8 +494,8 @@ export function getProviderUpdateSidebarPillView(
};
}

const recentTerminalProviders = dedupedProviders.filter((provider) =>
isRecentTerminalProvider(provider, options?.visibleAfterIso),
const recentTerminalProviders = latestTerminalProvidersByDriver(
providers.filter((provider) => isRecentTerminalProvider(provider, options?.visibleAfterIso)),
);
const terminalCandidates: ProviderUpdateSidebarPillView[] = [];

Expand Down
Loading