From 0ac5c7a319a7dc2882e4c88e3d0b94659e9cfbc7 Mon Sep 17 00:00:00 2001
From: Waishnav <86405648+Waishnav@users.noreply.github.com>
Date: Sat, 29 Aug 2026 10:58:03 +0530
Subject: [PATCH 1/3] fix(ui): use theme-specific provider logos
---
.../assets/provider-logos/copilot-light.svg | 1 +
src/ui/assets/provider-logos/cursor-light.svg | 1 +
src/ui/assets/provider-logos/openai-light.svg | 1 +
.../assets/provider-logos/opencode-dark.svg | 2 +-
.../assets/provider-logos/opencode-light.svg | 1 +
src/ui/assets/provider-logos/pi-on-light.svg | 1 +
src/ui/icons.ts | 39 +++++++++++++++----
src/ui/workspace-app.tsx | 24 ++++++++++--
8 files changed, 57 insertions(+), 13 deletions(-)
create mode 100644 src/ui/assets/provider-logos/copilot-light.svg
create mode 100644 src/ui/assets/provider-logos/cursor-light.svg
create mode 100644 src/ui/assets/provider-logos/openai-light.svg
create mode 100644 src/ui/assets/provider-logos/opencode-light.svg
create mode 100644 src/ui/assets/provider-logos/pi-on-light.svg
diff --git a/src/ui/assets/provider-logos/copilot-light.svg b/src/ui/assets/provider-logos/copilot-light.svg
new file mode 100644
index 00000000..64c54639
--- /dev/null
+++ b/src/ui/assets/provider-logos/copilot-light.svg
@@ -0,0 +1 @@
+
diff --git a/src/ui/assets/provider-logos/cursor-light.svg b/src/ui/assets/provider-logos/cursor-light.svg
new file mode 100644
index 00000000..d0cd849c
--- /dev/null
+++ b/src/ui/assets/provider-logos/cursor-light.svg
@@ -0,0 +1 @@
+
diff --git a/src/ui/assets/provider-logos/openai-light.svg b/src/ui/assets/provider-logos/openai-light.svg
new file mode 100644
index 00000000..7aff9250
--- /dev/null
+++ b/src/ui/assets/provider-logos/openai-light.svg
@@ -0,0 +1 @@
+
diff --git a/src/ui/assets/provider-logos/opencode-dark.svg b/src/ui/assets/provider-logos/opencode-dark.svg
index 62e10df4..0bdfe089 100644
--- a/src/ui/assets/provider-logos/opencode-dark.svg
+++ b/src/ui/assets/provider-logos/opencode-dark.svg
@@ -1 +1 @@
-
+
diff --git a/src/ui/assets/provider-logos/opencode-light.svg b/src/ui/assets/provider-logos/opencode-light.svg
new file mode 100644
index 00000000..8a274375
--- /dev/null
+++ b/src/ui/assets/provider-logos/opencode-light.svg
@@ -0,0 +1 @@
+
diff --git a/src/ui/assets/provider-logos/pi-on-light.svg b/src/ui/assets/provider-logos/pi-on-light.svg
new file mode 100644
index 00000000..5472a94e
--- /dev/null
+++ b/src/ui/assets/provider-logos/pi-on-light.svg
@@ -0,0 +1 @@
+
diff --git a/src/ui/icons.ts b/src/ui/icons.ts
index 8bada413..8fcb11c4 100644
--- a/src/ui/icons.ts
+++ b/src/ui/icons.ts
@@ -34,17 +34,40 @@ export const toolIcons = {
export type ToolIcon = IconNode;
const providerLogos = {
- claude: new URL("./assets/provider-logos/claude.svg", import.meta.url).href,
- codex: new URL("./assets/provider-logos/openai-dark.svg", import.meta.url).href,
- copilot: new URL("./assets/provider-logos/copilot-dark.svg", import.meta.url).href,
- cursor: new URL("./assets/provider-logos/cursor-dark.svg", import.meta.url).href,
- opencode: new URL("./assets/provider-logos/opencode-dark.svg", import.meta.url).href,
- pi: new URL("./assets/provider-logos/pi-on-dark.svg", import.meta.url).href,
+ claude: {
+ light: new URL("./assets/provider-logos/claude.svg", import.meta.url).href,
+ dark: new URL("./assets/provider-logos/claude.svg", import.meta.url).href,
+ },
+ codex: {
+ light: new URL("./assets/provider-logos/openai-light.svg", import.meta.url).href,
+ dark: new URL("./assets/provider-logos/openai-dark.svg", import.meta.url).href,
+ },
+ copilot: {
+ light: new URL("./assets/provider-logos/copilot-light.svg", import.meta.url).href,
+ dark: new URL("./assets/provider-logos/copilot-dark.svg", import.meta.url).href,
+ },
+ cursor: {
+ light: new URL("./assets/provider-logos/cursor-light.svg", import.meta.url).href,
+ dark: new URL("./assets/provider-logos/cursor-dark.svg", import.meta.url).href,
+ },
+ opencode: {
+ light: new URL("./assets/provider-logos/opencode-light.svg", import.meta.url).href,
+ dark: new URL("./assets/provider-logos/opencode-dark.svg", import.meta.url).href,
+ },
+ pi: {
+ light: new URL("./assets/provider-logos/pi-on-light.svg", import.meta.url).href,
+ dark: new URL("./assets/provider-logos/pi-on-dark.svg", import.meta.url).href,
+ },
} as const;
-export function getProviderLogo(name: string): string | undefined {
+export type ProviderLogoTheme = "light" | "dark";
+
+export function getProviderLogo(
+ name: string,
+ theme: ProviderLogoTheme = "dark",
+): string | undefined {
const normalizedName = name.trim().toLowerCase() as keyof typeof providerLogos;
- return providerLogos[normalizedName];
+ return providerLogos[normalizedName]?.[theme];
}
export function renderIcon(icon: ToolIcon, className = "icon-svg"): SVGElement {
diff --git a/src/ui/workspace-app.tsx b/src/ui/workspace-app.tsx
index bc101cb3..9dec916d 100644
--- a/src/ui/workspace-app.tsx
+++ b/src/ui/workspace-app.tsx
@@ -12,7 +12,13 @@ import {
type HostContext,
type ToolResultCard,
} from "./card-types.js";
-import { getProviderLogo, renderIcon, toolIcons, type ToolIcon } from "./icons.js";
+import {
+ getProviderLogo,
+ renderIcon,
+ toolIcons,
+ type ProviderLogoTheme,
+ type ToolIcon,
+} from "./icons.js";
import {
getFileChangePathDisplay,
getPatchDisplayParts,
@@ -83,6 +89,7 @@ async function boot(): Promise {
};
app.onhostcontextchanged = (ctx) => {
+ const previousTheme = hostContext?.theme;
hostContext = {
...hostContext,
...ctx,
@@ -90,7 +97,11 @@ async function boot(): Promise {
applyHostContext();
// Workspace details inherit host variables directly. Rebuilding their DOM on
// iframe resize would reset an in-progress instruction preview interaction.
- if (card?.tool !== "open_workspace") renderPayloadIfNeeded();
+ if (card?.tool === "open_workspace") {
+ if (ctx.theme && ctx.theme !== previousTheme) render();
+ } else {
+ renderPayloadIfNeeded();
+ }
};
app.onteardown = async () => {
@@ -583,6 +594,9 @@ function renderWorkspacePayload(container: HTMLElement, card: ToolResultCard): v
const providers = card.agentProviders ?? [];
const agents = card.agents ?? [];
+ const providerLogoTheme: ProviderLogoTheme = hostContext?.theme === "light"
+ ? "light"
+ : "dark";
const agentChips: WorkspaceChip[] = agents.map((agent) => {
const name = agent.name ?? "Unnamed agent";
const providerName = agent.provider?.trim();
@@ -594,14 +608,16 @@ function renderWorkspacePayload(container: HTMLElement, card: ToolResultCard): v
].filter((value): value is string => Boolean(value)).join("\n");
return {
label: name,
- logo: providerName ? getProviderLogo(providerName) : undefined,
+ logo: providerName
+ ? getProviderLogo(providerName, providerLogoTheme)
+ : undefined,
profile: true,
title: title || undefined,
};
});
const providerChips: WorkspaceChip[] = providers.map((provider) => {
const name = provider.id?.trim() || "Unknown provider";
- const logo = getProviderLogo(name);
+ const logo = getProviderLogo(name, providerLogoTheme);
const title = [
provider.model ? `Model: ${provider.model}` : undefined,
provider.effort ? `Effort: ${provider.effort}` : undefined,
From 0f2548db093707934d2749fa7b7c6c6bc31b68bb Mon Sep 17 00:00:00 2001
From: Waishnav <86405648+Waishnav@users.noreply.github.com>
Date: Sat, 29 Aug 2026 11:03:21 +0530
Subject: [PATCH 2/3] chore(ui): refresh official provider assets
---
src/ui/assets/provider-logos/copilot-dark.svg | 2 +-
src/ui/assets/provider-logos/copilot-light.svg | 2 +-
src/ui/assets/provider-logos/cursor-dark.svg | 13 ++++++++++++-
src/ui/assets/provider-logos/cursor-light.svg | 13 ++++++++++++-
src/ui/assets/provider-logos/openai-dark.svg | 12 +++++++++++-
src/ui/assets/provider-logos/openai-light.svg | 12 +++++++++++-
6 files changed, 48 insertions(+), 6 deletions(-)
diff --git a/src/ui/assets/provider-logos/copilot-dark.svg b/src/ui/assets/provider-logos/copilot-dark.svg
index d09df805..275b8393 100644
--- a/src/ui/assets/provider-logos/copilot-dark.svg
+++ b/src/ui/assets/provider-logos/copilot-dark.svg
@@ -1 +1 @@
-
+
diff --git a/src/ui/assets/provider-logos/copilot-light.svg b/src/ui/assets/provider-logos/copilot-light.svg
index 64c54639..b52d96cf 100644
--- a/src/ui/assets/provider-logos/copilot-light.svg
+++ b/src/ui/assets/provider-logos/copilot-light.svg
@@ -1 +1 @@
-
+
diff --git a/src/ui/assets/provider-logos/cursor-dark.svg b/src/ui/assets/provider-logos/cursor-dark.svg
index d50421b5..6849fbc3 100644
--- a/src/ui/assets/provider-logos/cursor-dark.svg
+++ b/src/ui/assets/provider-logos/cursor-dark.svg
@@ -1 +1,12 @@
-
+
+
diff --git a/src/ui/assets/provider-logos/cursor-light.svg b/src/ui/assets/provider-logos/cursor-light.svg
index d0cd849c..b054b189 100644
--- a/src/ui/assets/provider-logos/cursor-light.svg
+++ b/src/ui/assets/provider-logos/cursor-light.svg
@@ -1 +1,12 @@
-
+
+
diff --git a/src/ui/assets/provider-logos/openai-dark.svg b/src/ui/assets/provider-logos/openai-dark.svg
index 7e19c92d..cd86afb5 100644
--- a/src/ui/assets/provider-logos/openai-dark.svg
+++ b/src/ui/assets/provider-logos/openai-dark.svg
@@ -1 +1,11 @@
-
+
diff --git a/src/ui/assets/provider-logos/openai-light.svg b/src/ui/assets/provider-logos/openai-light.svg
index 7aff9250..a57ca0da 100644
--- a/src/ui/assets/provider-logos/openai-light.svg
+++ b/src/ui/assets/provider-logos/openai-light.svg
@@ -1 +1,11 @@
-
+
From 16fada9820789d29b710f3881abdd31f81e895f0 Mon Sep 17 00:00:00 2001
From: Waishnav <86405648+Waishnav@users.noreply.github.com>
Date: Sat, 29 Aug 2026 11:05:41 +0530
Subject: [PATCH 3/3] fix(ui): preserve workspace state on theme changes
---
src/ui/workspace-app.tsx | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/src/ui/workspace-app.tsx b/src/ui/workspace-app.tsx
index 9dec916d..27d4f5b8 100644
--- a/src/ui/workspace-app.tsx
+++ b/src/ui/workspace-app.tsx
@@ -98,7 +98,9 @@ async function boot(): Promise {
// Workspace details inherit host variables directly. Rebuilding their DOM on
// iframe resize would reset an in-progress instruction preview interaction.
if (card?.tool === "open_workspace") {
- if (ctx.theme && ctx.theme !== previousTheme) render();
+ if (ctx.theme && ctx.theme !== previousTheme) {
+ syncWorkspaceProviderLogos(ctx.theme === "light" ? "light" : "dark");
+ }
} else {
renderPayloadIfNeeded();
}
@@ -611,6 +613,7 @@ function renderWorkspacePayload(container: HTMLElement, card: ToolResultCard): v
logo: providerName
? getProviderLogo(providerName, providerLogoTheme)
: undefined,
+ logoProvider: providerName,
profile: true,
title: title || undefined,
};
@@ -626,6 +629,7 @@ function renderWorkspacePayload(container: HTMLElement, card: ToolResultCard): v
return {
label: name,
logo,
+ logoProvider: logo ? name : undefined,
bareLogo: Boolean(logo),
ariaLabel: name,
title: title || name,
@@ -652,6 +656,7 @@ function renderWorkspacePayload(container: HTMLElement, card: ToolResultCard): v
interface WorkspaceChip {
label: string;
logo?: string;
+ logoProvider?: string;
profile?: boolean;
bareLogo?: boolean;
ariaLabel?: string;
@@ -929,6 +934,7 @@ function renderWorkspaceChips(chips: WorkspaceChip[]): HTMLElement {
? "workspace-agent-profile-logo"
: "workspace-chip-logo";
logo.src = chip.logo;
+ if (chip.logoProvider) logo.dataset.provider = chip.logoProvider;
logo.alt = "";
logo.setAttribute("aria-hidden", "true");
item.append(logo);
@@ -941,6 +947,15 @@ function renderWorkspaceChips(chips: WorkspaceChip[]): HTMLElement {
return list;
}
+function syncWorkspaceProviderLogos(theme: ProviderLogoTheme): void {
+ for (const logo of document.querySelectorAll("img[data-provider]")) {
+ const providerName = logo.dataset.provider;
+ if (!providerName) continue;
+ const src = getProviderLogo(providerName, theme);
+ if (src && logo.src !== src) logo.src = src;
+ }
+}
+
function element(
tag: K,
options: {