{t(plugin.nameKey)}
diff --git a/packages/ui/src/components/sections/integrations/thirdPartyPlugins.ts b/packages/ui/src/components/sections/integrations/thirdPartyPlugins.ts
index cf1b4d80..ff28c43e 100644
--- a/packages/ui/src/components/sections/integrations/thirdPartyPlugins.ts
+++ b/packages/ui/src/components/sections/integrations/thirdPartyPlugins.ts
@@ -7,6 +7,8 @@ export interface ThirdPartyPluginDefinition {
packageName: string;
providerId: string;
icon: IconName;
+ /** Brand mark tint (e.g. Claude orange); neutral marks use text-foreground. */
+ brandClassName: string;
nameKey: I18nKey;
descriptionKey: I18nKey;
homepage: string;
@@ -17,7 +19,8 @@ export const THIRD_PARTY_PLUGINS: readonly ThirdPartyPluginDefinition[] = [
id: 'opencode-claude',
packageName: '@otto-assistant/opencode-claude',
providerId: 'claude-code',
- icon: 'sparkling',
+ icon: 'claude-code',
+ brandClassName: 'text-[#D97757]',
nameKey: 'settings.integrations.thirdParty.opencodeClaude.name',
descriptionKey: 'settings.integrations.thirdParty.opencodeClaude.description',
homepage: 'https://github.com/otto-assistant/opencode-claude',
@@ -26,7 +29,8 @@ export const THIRD_PARTY_PLUGINS: readonly ThirdPartyPluginDefinition[] = [
id: 'opencode-commandcode',
packageName: '@otto-assistant/opencode-commandcode',
providerId: 'command-code',
- icon: 'terminal-box',
+ icon: 'command-code',
+ brandClassName: 'text-foreground',
nameKey: 'settings.integrations.thirdParty.opencodeCommandcode.name',
descriptionKey: 'settings.integrations.thirdParty.opencodeCommandcode.description',
homepage: 'https://github.com/otto-assistant/opencode-commandcode',
@@ -36,6 +40,7 @@ export const THIRD_PARTY_PLUGINS: readonly ThirdPartyPluginDefinition[] = [
packageName: '@otto-assistant/opencode-cursor-oauth',
providerId: 'cursor',
icon: 'cursor',
+ brandClassName: 'text-foreground',
nameKey: 'settings.integrations.thirdParty.opencodeCursorOauth.name',
descriptionKey: 'settings.integrations.thirdParty.opencodeCursorOauth.description',
homepage: 'https://github.com/otto-assistant/opencode-cursor',
diff --git a/packages/ui/src/components/ui/ProviderLogo.tsx b/packages/ui/src/components/ui/ProviderLogo.tsx
index ef2e3bac..70af4f45 100644
--- a/packages/ui/src/components/ui/ProviderLogo.tsx
+++ b/packages/ui/src/components/ui/ProviderLogo.tsx
@@ -1,6 +1,8 @@
import React from 'react';
+import { Icon } from '@/components/icon/Icon';
import { useProviderLogo } from '@/hooks/useProviderLogo';
import { cn } from '@/lib/utils';
+import { getProviderLogoFallbackIcon } from './providerLogoFallback';
interface ProviderLogoProps {
providerId: string;
@@ -16,6 +18,7 @@ export const ProviderLogo: React.FC
= ({
onError: externalOnError
}) => {
const { src, onError: handleInternalError, hasLogo } = useProviderLogo(providerId);
+ const fallbackIcon = getProviderLogoFallbackIcon(providerId);
const handleError = React.useCallback(() => {
handleInternalError();
@@ -23,7 +26,7 @@ export const ProviderLogo: React.FC = ({
}, [handleInternalError, externalOnError]);
if (!hasLogo || !src) {
- return null;
+ return fallbackIcon ? : null;
}
return (
diff --git a/packages/ui/src/components/ui/providerLogoFallback.test.ts b/packages/ui/src/components/ui/providerLogoFallback.test.ts
new file mode 100644
index 00000000..c82b9ad3
--- /dev/null
+++ b/packages/ui/src/components/ui/providerLogoFallback.test.ts
@@ -0,0 +1,13 @@
+import { describe, expect, test } from 'bun:test';
+import { getProviderLogoFallbackIcon } from './providerLogoFallback';
+
+describe('provider logo fallbacks', () => {
+ test('uses a local terminal icon when Command Code has no resolved logo', () => {
+ expect(getProviderLogoFallbackIcon('command-code')).toBe('terminal-box');
+ });
+
+ test('does not replace providers with their own logo assets', () => {
+ expect(getProviderLogoFallbackIcon('claude-code')).toBeNull();
+ expect(getProviderLogoFallbackIcon('cursor')).toBeNull();
+ });
+});
diff --git a/packages/ui/src/components/ui/providerLogoFallback.ts b/packages/ui/src/components/ui/providerLogoFallback.ts
new file mode 100644
index 00000000..9aa871fd
--- /dev/null
+++ b/packages/ui/src/components/ui/providerLogoFallback.ts
@@ -0,0 +1,5 @@
+import type { IconName } from '@/components/icon/icons';
+
+export function getProviderLogoFallbackIcon(providerId: string | null | undefined): IconName | null {
+ return providerId?.trim().toLowerCase() === 'command-code' ? 'terminal-box' : null;
+}
diff --git a/scripts/generate-icon-sprite.mjs b/scripts/generate-icon-sprite.mjs
index 1d1f1c3e..3098bb05 100644
--- a/scripts/generate-icon-sprite.mjs
+++ b/scripts/generate-icon-sprite.mjs
@@ -22,6 +22,21 @@ const customIconData = new Map([
"openchamber",
``,
],
+ // Claude spark — official Anthropic mark (Simple Icons path), monochrome.
+ [
+ "claude-code",
+ ``,
+ ],
+ // Cursor two-cursor mark — official (Simple Icons path), monochrome.
+ [
+ "cursor",
+ ``,
+ ],
+ // Command Code — corner squares + center square (official logo geometry).
+ [
+ "command-code",
+ ``,
+ ],
])
const source = readFileSync(remixPath, "utf-8")