diff --git a/apps/docs/data/content-listings/ai-tools.data.ts b/apps/docs/data/content-listings/ai-tools.data.ts index 4b555dc87bc..6517e8a909e 100644 --- a/apps/docs/data/content-listings/ai-tools.data.ts +++ b/apps/docs/data/content-listings/ai-tools.data.ts @@ -19,6 +19,7 @@ const ICON_ASSETS: Record = { 'gemini-cli': { icon: '/docs/img/icons/agent-gemini-cli-icon', hasLightIcon: false }, 'github-copilot': { icon: '/docs/img/icons/agent-copilot-icon', hasLightIcon: true }, kimi: { icon: '/docs/img/icons/agent-kimi-icon', hasLightIcon: true }, + omp: { icon: '/docs/img/icons/agent-omp-icon', hasLightIcon: false }, vscode: { icon: '/docs/img/icons/agent-vscode-icon', hasLightIcon: false }, antigravity: { icon: '/docs/img/icons/agent-antigravity-icon', hasLightIcon: false }, windsurf: { icon: '/docs/img/icons/agent-devin-icon', hasLightIcon: true }, @@ -46,6 +47,7 @@ const TAGLINES: Record = { goose: 'Your native open source AI agent — desktop app, CLI, and API.', kimi: 'Engineered to drop into any dev workflow and get programming tasks done fast.', kiro: 'Move beyond AI coding to agentic engineering.', + omp: 'A coding agent with the IDE wired in.', opencode: 'The open source AI coding agent.', vscode: 'The open source AI code editor — your home for multi-agent development.', // Pre-acquisition tagline (Cognition/Devin acquired Windsurf in 2025) — see "Open questions". diff --git a/apps/docs/features/ui/AgentPluginsPanel.data.ts b/apps/docs/features/ui/AgentPluginsPanel.data.ts index 91902ae6412..883baae6939 100644 --- a/apps/docs/features/ui/AgentPluginsPanel.data.ts +++ b/apps/docs/features/ui/AgentPluginsPanel.data.ts @@ -63,6 +63,14 @@ export const PLUGIN_CLIENTS: PluginClient[] = [ repoUrl: 'https://github.com/supabase-community/supabase-plugin', docsUrl: 'https://www.kimi.com/code/docs/en/kimi-code-cli/customization/plugins.html', }, + { + key: 'omp', + label: 'omp', + icon: 'omp', + repoUrl: 'https://github.com/supabase-community/supabase-plugin', + docsUrl: 'https://github.com/can1357/oh-my-pi/blob/main/docs/marketplace.md', + docsLinkText: 'View omp plugin docs', + }, { key: 'vscode', label: 'VS Code', diff --git a/apps/docs/features/ui/AgentPluginsPanel.tsx b/apps/docs/features/ui/AgentPluginsPanel.tsx index 7df6f067d13..bf509160047 100644 --- a/apps/docs/features/ui/AgentPluginsPanel.tsx +++ b/apps/docs/features/ui/AgentPluginsPanel.tsx @@ -169,6 +169,38 @@ function PluginInstructions({ client }: { client: PluginClient }) { ) } + if (client.key === 'omp') { + return ( +
+

+ omp reads the Claude Code plugin format, so install the Supabase plugin from the{' '} + + official Anthropic marketplace + + : +

+ +

+ Installs with --scope user by default, making it available across all your + projects. Use --scope project to install it for the current project only. +

+

+ Inside a session, run /marketplace to browse plugins, then{' '} + /reload-plugins after installing to load the skills and MCP server. +

+
+ ) + } if (client.key === 'vscode') { return ( diff --git a/apps/docs/public/img/icons/agent-omp-icon.svg b/apps/docs/public/img/icons/agent-omp-icon.svg new file mode 100644 index 00000000000..379eff88719 --- /dev/null +++ b/apps/docs/public/img/icons/agent-omp-icon.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/apps/kb/astro.config.mjs b/apps/kb/astro.config.mjs index f44675364a7..019ad553395 100644 --- a/apps/kb/astro.config.mjs +++ b/apps/kb/astro.config.mjs @@ -6,6 +6,8 @@ import react from '@astrojs/react' import tailwindcss from '@tailwindcss/vite' import { defineConfig } from 'astro/config' +import supabaseTheme from '../learn/lib/themes/supabase-2.json' with { type: 'json' } + // Absolute dir of lodash-es, for the SSR-only lodash alias below (same fix // apps/studio/vite.config.ts uses). `packages/ui`'s clipboard util does // `import { noop } from 'lodash'` — under Vite's dev-mode SSR module runner, @@ -45,4 +47,23 @@ export default defineConfig({ }, plugins: [tailwindcss(), ssrLodashEs], }, + markdown: { + shikiConfig: { + theme: supabaseTheme, + // Match the docs app's CodeBlock component (border + rounded-lg on the + // outer element), since Astro's own markdown pipeline renders code + // blocks straight to a `
` with no wrapper we can add classes to.
+      transformers: [
+        {
+          name: 'kb-code-block-classes',
+          pre(node) {
+            this.addClassToHast(node, 'border border-default rounded-lg')
+          },
+          code(node) {
+            this.addClassToHast(node, 'inline-block p-6')
+          },
+        },
+      ],
+    },
+  },
 })
diff --git a/apps/kb/src/components/Nav.tsx b/apps/kb/src/components/Nav.tsx
index d28f765a059..16ff6977028 100644
--- a/apps/kb/src/components/Nav.tsx
+++ b/apps/kb/src/components/Nav.tsx
@@ -9,15 +9,16 @@ import {
   navigationMenuTriggerStyle,
 } from 'ui'
 
+import { TOPICS, topicToSlug } from '../lib/topics'
+
+const topics = TOPICS.map((topic) => ({
+  label: topic.name,
+  href: `${import.meta.env.BASE_URL}/topics/${topicToSlug(topic.name)}`,
+}))
+
 /**
  * Hard-codding links in here for now until we have actual content. Might be worth putting these arrays in their on data file too.
  */
-const topics = [
-  { label: 'Troubleshooting', href: '#' },
-  { label: 'Migrations', href: '#' },
-  { label: 'Comparisons', href: '#' },
-]
-
 const resources = [
   { label: 'Status', href: 'https://status.supabase.com' },
   { label: 'Changelog', href: 'https://supabase.com/changelog' },
diff --git a/apps/kb/src/content.config.ts b/apps/kb/src/content.config.ts
index 92612a16b79..fec50c46fb6 100644
--- a/apps/kb/src/content.config.ts
+++ b/apps/kb/src/content.config.ts
@@ -2,6 +2,8 @@ import { defineCollection } from 'astro:content'
 import { glob } from 'astro/loaders'
 import { z } from 'astro/zod'
 
+import { TOPIC_NAMES } from './lib/topics'
+
 // Every entry here is rendered through GuideLayout by
 // src/pages/guides/[...slug].astro — dropping a new file in
 // src/content/guides doesn't need any per-file layout wiring.
@@ -9,8 +11,10 @@ const guides = defineCollection({
   loader: glob({ pattern: '**/*.md', base: './src/content/guides' }),
   schema: z.object({
     title: z.string(),
-    description: z.string().optional(),
-    topics: z.array(z.string()).optional(),
+    description: z.string(),
+    // z.enum (not z.string) so a guide referencing a topic outside TOPICS
+    // fails content validation instead of silently rendering an orphaned tag.
+    topics: z.array(z.enum(TOPIC_NAMES)),
     github_url: z.string().optional(),
   }),
 })
diff --git a/apps/kb/src/content/guides/sample-guide.md b/apps/kb/src/content/guides/sample-guide.md
index 6a69b4987bc..f1af5d55b00 100644
--- a/apps/kb/src/content/guides/sample-guide.md
+++ b/apps/kb/src/content/guides/sample-guide.md
@@ -1,7 +1,7 @@
 ---
 title: 'Markdown elements sample'
 description: 'A lorem ipsum sample guide exercising every base Markdown element supported by the guide layout.'
-topics: ['example', 'markdown']
+topics: ['Tutorial', 'Database']
 github_url: 'https://github.com/supabase/supabase/discussions/0000000'
 ---
 
diff --git a/apps/kb/src/layouts/GuideLayout.astro b/apps/kb/src/layouts/GuideLayout.astro
index 49b82d04b1c..0362e842cfa 100644
--- a/apps/kb/src/layouts/GuideLayout.astro
+++ b/apps/kb/src/layouts/GuideLayout.astro
@@ -3,11 +3,12 @@ import { Github } from 'lucide-react'
 import { Badge } from 'ui'
 
 import Layout from './Layout.astro'
+import { getTopicDescription, type Topic, topicToSlug } from '../lib/topics'
 
 interface Props {
 	title: string
 	description?: string
-	topics?: string[]
+	topics?: Topic[]
 	github_url?: string
 }
 
@@ -21,7 +22,14 @@ const { title, description, topics = [], github_url } = Astro.props
 		{
 			topics.length > 0 && (
 				
- {topics.map((topic) => {topic})} + {topics.map((topic) => ( + + {topic} + + ))}
) } diff --git a/apps/kb/src/lib/topics.ts b/apps/kb/src/lib/topics.ts new file mode 100644 index 00000000000..c0725d4a303 --- /dev/null +++ b/apps/kb/src/lib/topics.ts @@ -0,0 +1,31 @@ +// Canonical list of guide topics. Single source of truth for the `topics` +// field in src/content.config.ts (so a guide with an unsupported topic fails +// content validation), the "Topics" nav menu, and the /topics/[topic] pages. +export const TOPICS = [ + { name: 'Migration', description: 'Moving data, schemas, or projects onto Supabase' }, + { name: 'Comparison', description: 'How Supabase compares to other databases and platforms' }, + { name: 'Troubleshooting', description: 'Common errors and how to resolve them' }, + { name: 'Tutorial', description: 'Step-by-step walkthroughs for building with Supabase' }, + { name: 'Storage', description: 'Uploading, managing, and serving files' }, + { name: 'Auth', description: 'Authentication, authorization, and user management' }, + { name: 'Database', description: 'Postgres schemas, queries, and performance' }, + { name: 'Edge Functions', description: 'Deploying and running serverless functions' }, + { name: 'Queues', description: 'Background jobs and message processing' }, + { name: 'Realtime', description: 'Broadcast, presence, and database changes' }, + { name: 'Supabase Platform', description: 'Project settings, billing, and infrastructure' }, +] as const + +export type Topic = (typeof TOPICS)[number]['name'] + +// zod's `enum()` needs a literal non-empty tuple of strings, which `.map()` +// can't preserve on its own — this cast is safe because TOPICS is `as const`. +export const TOPIC_NAMES = TOPICS.map((topic) => topic.name) as [Topic, ...Topic[]] + +export function getTopicDescription(topic: Topic): string { + return TOPICS.find((t) => t.name === topic)!.description +} + +// URL-safe slug for a topic, e.g. "Edge Functions" -> "edge-functions". +export function topicToSlug(topic: Topic): string { + return topic.toLowerCase().replace(/\s+/g, '-') +} diff --git a/apps/kb/src/pages/topics/[topic].astro b/apps/kb/src/pages/topics/[topic].astro new file mode 100644 index 00000000000..aa741118dc0 --- /dev/null +++ b/apps/kb/src/pages/topics/[topic].astro @@ -0,0 +1,43 @@ +--- +import { getCollection } from 'astro:content' + +import Layout from '../../layouts/Layout.astro' +import { TOPICS, topicToSlug } from '../../lib/topics' + +export async function getStaticPaths() { + const guides = await getCollection('guides') + + // One page per topic in TOPICS — not just topics a guide already uses — + // so every link on the "Topics" nav resolves instead of 404ing. + return TOPICS.map((topic) => ({ + params: { topic: topicToSlug(topic.name) }, + props: { + topic: topic.name, + description: topic.description, + guides: guides.filter((guide) => guide.data.topics?.includes(topic.name)), + }, + })) +} + +const { topic, description, guides } = Astro.props +--- + + +
+

{topic}

+

{description}

+ { + guides.length === 0 ? ( +

No guides for this topic

+ ) : ( + + ) + } +
+
diff --git a/apps/kb/src/styles/globals.css b/apps/kb/src/styles/globals.css index b15951345ec..efb8df5e7bb 100644 --- a/apps/kb/src/styles/globals.css +++ b/apps/kb/src/styles/globals.css @@ -73,8 +73,35 @@ h6:not(.font-mono), border-color: var(--border-default, currentColor); } -/* TEMPORARY UNTIL WE IMPLEMENT OUR OWN CODE COMPONENT */ -.prose pre code { - padding: 1rem; - display: inline-block; +/* Code block theme colors for use with Supabase Theme */ +[data-theme='dark'] { + --code-token-keyword: #bda4ff; + --code-foreground: #ffffff; + --code-token-constant: #3ecf8e; + --code-token-string: #ffcda1; + --code-token-comment: #949494; + --code-token-parameter: #ffffff; + --code-token-function: #3ecf8e; + --code-token-string-expression: #ffcda1; + --code-token-punctuation: #ffffff; + --code-token-link: #ffffff; + --code-token-number: #ffffff; + --code-token-property: #3ecf8e; + --code-highlight-color: #232323; +} + +[data-theme='light'] { + --code-token-keyword: #5f2fc4; + --code-foreground: oklch(from var(--foreground-light) l c h / 1); + --code-token-constant: #15593b; + --code-token-string: #9a5200; + --code-token-comment: #6a6a6a; + --code-token-parameter: oklch(from var(--foreground-light) l c h / 1); + --code-token-function: #15593b; + --code-token-string-expression: #9a5200; + --code-token-punctuation: oklch(from var(--foreground-light) l c h / 1); + --code-token-link: oklch(from var(--foreground-light) l c h / 1); + --code-token-number: oklch(from var(--foreground-light) l c h / 1); + --code-token-property: #15593b; + --code-highlight-color: #1c1c1c; } diff --git a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewContext.tsx b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewContext.tsx index 739b178761e..66de34d7abb 100644 --- a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewContext.tsx +++ b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewContext.tsx @@ -171,6 +171,12 @@ export const useIsExplorerEnabled = () => { return isExplorerEnabled && flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_EXPLORER] } +export const useIsStorageVersioningEnabled = () => { + const { flags } = useFeaturePreviewContext() + const isStorageVersioningEnabled = useFlag('storageVersioningPrivateAlpha') + return isStorageVersioningEnabled && flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_STORAGE_VERSIONING] +} + export const useFeaturePreviewModal = () => { const featurePreviews = useFeaturePreviews() const [featurePreviewModal, setFeaturePreviewModal] = useQueryState('featurePreviewModal') diff --git a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewModal.tsx b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewModal.tsx index 794d865cd2f..bd8f5ae2a19 100644 --- a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewModal.tsx +++ b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewModal.tsx @@ -39,6 +39,7 @@ import { JitDbAccessPreview } from './JitDbAccessPreview' import { PgDeltaDiffPreview } from './PgDeltaDiffPreview' import { PlatformWebhooksPreview } from './PlatformWebhooksPreview' import { SqlEditorManualSavePreview } from './SqlEditorManualSavePreview' +import { StorageVersioningPreview } from './StorageVersioningPreview' import { UnifiedLogsPreview } from './UnifiedLogsPreview' import { FeaturePreview, useFeaturePreviews } from './useFeaturePreviews' import { useBannerStack } from '@/components/ui/BannerStack/BannerStackProvider' @@ -59,6 +60,7 @@ const FEATURE_PREVIEW_KEY_TO_CONTENT: { [LOCAL_STORAGE_KEYS.UI_PREVIEW_MARKETPLACE]: , [LOCAL_STORAGE_KEYS.UI_PREVIEW_DATABASE_CONNECTIONS]: , [LOCAL_STORAGE_KEYS.UI_PREVIEW_EXPLORER]: , + [LOCAL_STORAGE_KEYS.UI_PREVIEW_STORAGE_VERSIONING]: , } export const FeaturePreviewModal = () => { diff --git a/apps/studio/components/interfaces/App/FeaturePreview/StorageVersioningPreview.tsx b/apps/studio/components/interfaces/App/FeaturePreview/StorageVersioningPreview.tsx new file mode 100644 index 00000000000..dd526321c90 --- /dev/null +++ b/apps/studio/components/interfaces/App/FeaturePreview/StorageVersioningPreview.tsx @@ -0,0 +1,23 @@ +export const StorageVersioningPreview = () => { + return ( +
+

+ Keep previous copies of a file when it's overwritten or deleted, and set a lifecycle policy + that expires them automatically. +

+
+

Enabling this preview will:

+
    +
  • Add object versioning and lifecycle policy settings to the bucket settings
  • +
  • Show a version history for each file in the file preview panel
  • +
  • Allow soft-deleting and restoring files
  • +
  • Break down retained version storage on the organization usage page
  • +
+
+

+ Versioning is in Private Alpha and is off for every bucket by default until you + turn it on. +

+
+ ) +} diff --git a/apps/studio/components/interfaces/App/FeaturePreview/useFeaturePreviews.ts b/apps/studio/components/interfaces/App/FeaturePreview/useFeaturePreviews.ts index 5b3483ac31b..5c8e9d8e8ac 100644 --- a/apps/studio/components/interfaces/App/FeaturePreview/useFeaturePreviews.ts +++ b/apps/studio/components/interfaces/App/FeaturePreview/useFeaturePreviews.ts @@ -36,6 +36,7 @@ export const useFeaturePreviews = (): FeaturePreview[] => { const isMarketplaceEnabled = useFlag('marketplaceIntegrations') const isDatabaseConnectionsEnabled = useFlag('topForPostgres') const isExplorerEnabled = useFlag('explorer') + const isStorageVersioningEnabled = useFlag('storageVersioningPrivateAlpha') const isSqlEditorManualSaveForced = useFlag('sqlEditorManualSaveForced') @@ -150,6 +151,16 @@ export const useFeaturePreviews = (): FeaturePreview[] => { getRoute: (ref?: string) => `/project/${ref}/observability/connections`, bannerId: 'database-connections-banner', }, + { + key: LOCAL_STORAGE_KEYS.UI_PREVIEW_STORAGE_VERSIONING, + name: 'Storage versioning', + discussionsUrl: undefined, + isNew: true, + isPlatformOnly: true, + isDefaultOptIn: true, + enabled: isStorageVersioningEnabled, + getRoute: (ref?: string) => `/project/${ref}/storage/files`, + }, ] return previews.sort((a, b) => Number(b.isNew) - Number(a.isNew)) @@ -160,5 +171,6 @@ export const useFeaturePreviews = (): FeaturePreview[] => { isMarketplaceEnabled, isDatabaseConnectionsEnabled, isExplorerEnabled, + isStorageVersioningEnabled, ]) } diff --git a/packages/common/constants/local-storage.ts b/packages/common/constants/local-storage.ts index f5041ea185c..abb6311eb66 100644 --- a/packages/common/constants/local-storage.ts +++ b/packages/common/constants/local-storage.ts @@ -29,6 +29,7 @@ export const LOCAL_STORAGE_KEYS = { UI_PREVIEW_MARKETPLACE: 'supabase-ui-marketplace', UI_PREVIEW_DATABASE_CONNECTIONS: 'preview-database-connections', UI_PREVIEW_EXPLORER: 'preview-explorer', + UI_PREVIEW_STORAGE_VERSIONING: 'supabase-ui-storage-versioning', AI_ASSISTANT_MCP_OPT_IN: 'ai-assistant-mcp-opt-in', @@ -172,6 +173,7 @@ const LOCAL_STORAGE_KEYS_ALLOWLIST = [ LOCAL_STORAGE_KEYS.UI_PREVIEW_SQL_EDITOR_MANUAL_SAVE, LOCAL_STORAGE_KEYS.SQL_EDITOR_MANUAL_SAVE_NOTICE_DISMISSED, LOCAL_STORAGE_KEYS.UI_PREVIEW_MARKETPLACE, + LOCAL_STORAGE_KEYS.UI_PREVIEW_STORAGE_VERSIONING, LOCAL_STORAGE_KEYS.LAST_SIGN_IN_METHOD, LOCAL_STORAGE_KEYS.HIDE_PROMO_TOAST, LOCAL_STORAGE_KEYS.BLOG_VIEW, diff --git a/packages/ui-patterns/src/McpUrlBuilder/assets/omp-icon.svg b/packages/ui-patterns/src/McpUrlBuilder/assets/omp-icon.svg new file mode 100644 index 00000000000..379eff88719 --- /dev/null +++ b/packages/ui-patterns/src/McpUrlBuilder/assets/omp-icon.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/packages/ui-patterns/src/McpUrlBuilder/clients.data.ts b/packages/ui-patterns/src/McpUrlBuilder/clients.data.ts index c73510e5023..fe7c79f3dc4 100644 --- a/packages/ui-patterns/src/McpUrlBuilder/clients.data.ts +++ b/packages/ui-patterns/src/McpUrlBuilder/clients.data.ts @@ -13,6 +13,7 @@ import type { McpClientConfig, McpClientDeepLinkOptions, McpFeatureGroup, + OmpMcpConfig, OpenCodeMcpConfig, VSCodeMcpConfig, WindsurfMcpConfig, @@ -360,6 +361,23 @@ export const MCP_CLIENT_DATA: McpClientData[] = [ } }, }, + { + key: 'omp', + label: 'omp', + icon: 'omp', + configFile: '.omp/mcp.json', + externalDocsUrl: 'https://github.com/can1357/oh-my-pi/blob/main/docs/mcp-config.md', + transformConfig: (config): OmpMcpConfig => { + return { + mcpServers: { + supabase: { + type: 'http', + url: config.mcpServers.supabase.url, + }, + }, + } + }, + }, { key: 'kiro', label: 'Kiro', @@ -449,6 +467,7 @@ export const MCP_CLIENT_GROUPS = [ 'opencode', 'factory', 'fx', + 'omp', ], }, { diff --git a/packages/ui-patterns/src/McpUrlBuilder/clients.instructions.md.tsx b/packages/ui-patterns/src/McpUrlBuilder/clients.instructions.md.tsx index 77ac73995d7..a73704c4797 100644 --- a/packages/ui-patterns/src/McpUrlBuilder/clients.instructions.md.tsx +++ b/packages/ui-patterns/src/McpUrlBuilder/clients.instructions.md.tsx @@ -275,6 +275,32 @@ export const MCP_CLIENT_INSTRUCTIONS: Record = { ), }, + omp: { + primary: () => ( + <> + + Start and add the Supabase MCP server with the guided setup: + + + + ), + alternate: () => ( + <> + + That path is project-scoped. To use the server in every project, add the same entry to{' '} + instead. + + + If a session is already open, pick up the change with . + omp opens your browser to complete the Supabase OAuth flow the first time it connects. + + + Confirm the server is connected with , or authorize again + with a different account using . + + + ), + }, kiro: { deepLinkDescription: ( diff --git a/packages/ui-patterns/src/McpUrlBuilder/types.ts b/packages/ui-patterns/src/McpUrlBuilder/types.ts index 570d09de794..89daf506c3d 100644 --- a/packages/ui-patterns/src/McpUrlBuilder/types.ts +++ b/packages/ui-patterns/src/McpUrlBuilder/types.ts @@ -214,6 +214,19 @@ export interface KimiMcpConfig extends McpClientBaseConfig { } } } +/** + * Configuration format for the omp CLI MCP client. + * omp keys servers under `mcpServers` and requires an explicit `type: "http"`: + * an entry with a `url` but no `type` is validated as stdio and rejected. + */ +export interface OmpMcpConfig extends McpClientBaseConfig { + mcpServers: { + supabase: { + type: 'http' + url: string + } + } +} // Union of all possible config types export type McpClientConfig = @@ -230,6 +243,7 @@ export type McpClientConfig = | GrokMcpConfig | KimiMcpConfig | McpClientBaseConfig + | OmpMcpConfig | OpenCodeMcpConfig | OtherMcpConfig | VSCodeMcpConfig diff --git a/packages/ui-patterns/src/McpUrlBuilder/utils/mcpIconAssets.ts b/packages/ui-patterns/src/McpUrlBuilder/utils/mcpIconAssets.ts index a5fe3f63eb6..6b7938c2665 100644 --- a/packages/ui-patterns/src/McpUrlBuilder/utils/mcpIconAssets.ts +++ b/packages/ui-patterns/src/McpUrlBuilder/utils/mcpIconAssets.ts @@ -20,6 +20,7 @@ import grokIcon from '../assets/grok-icon.svg' import kimiDarkIcon from '../assets/kimi-icon-dark.svg' import kimiIcon from '../assets/kimi-icon.svg' import kiroIcon from '../assets/kiro-icon.svg' +import ompIcon from '../assets/omp-icon.svg' import openaiDarkIcon from '../assets/openai-icon-dark.svg' import openaiIcon from '../assets/openai-icon.svg' import opencodeDarkIcon from '../assets/opencode-icon-dark.svg' @@ -52,6 +53,7 @@ const MCP_CLIENT_ICON_ASSETS = { grok: { light: grokIcon, dark: grokDarkIcon }, kimi: { light: kimiIcon, dark: kimiDarkIcon }, kiro: { light: kiroIcon, dark: kiroIcon }, + omp: { light: ompIcon, dark: ompIcon }, openai: { light: openaiIcon, dark: openaiDarkIcon }, opencode: { light: opencodeIcon, dark: opencodeDarkIcon }, perplexity: { light: perplexityIcon, dark: perplexityDarkIcon },