|
239 | 239 | </div> |
240 | 240 | </div> |
241 | 241 | </div> |
242 | | - <div v-else-if="!composioStatus.authenticated" class="directory-empty"> |
243 | | - <div class="directory-empty-copy"> |
244 | | - <p class="directory-empty-text">Composio is available but not logged in.</p> |
245 | | - <div class="directory-card-actions"> |
| 242 | + <div v-else-if="!composioStatus.authenticated" class="composio-preview"> |
| 243 | + <article class="composio-preview-hero"> |
| 244 | + <div class="composio-preview-copy"> |
| 245 | + <div class="directory-card-fallback composio-fallback">C</div> |
| 246 | + <div> |
| 247 | + <p class="composio-preview-kicker">Connector catalog preview</p> |
| 248 | + <h3 class="composio-preview-title">Connect everyday apps like Gmail, Calendar, Reddit, YouTube, and Drive.</h3> |
| 249 | + <p class="composio-preview-text"> |
| 250 | + Composio is installed locally. Login to browse the live catalog, connect your accounts, and try simple actions from this machine. |
| 251 | + </p> |
| 252 | + </div> |
| 253 | + </div> |
| 254 | + <div class="composio-preview-actions"> |
246 | 255 | <button class="directory-action primary" type="button" :disabled="isStartingComposioLogin" @click="startComposioCliLogin"> |
247 | | - {{ isStartingComposioLogin ? 'Opening...' : 'Login' }} |
| 256 | + {{ isStartingComposioLogin ? 'Opening...' : 'Login to Composio' }} |
| 257 | + </button> |
| 258 | + <button class="directory-action-link" type="button" @click="openExternalUrl(composioStatus.webUrl || 'https://dashboard.composio.dev/')"> |
| 259 | + Open dashboard |
248 | 260 | </button> |
249 | 261 | </div> |
| 262 | + </article> |
| 263 | + <div class="composio-preview-grid"> |
| 264 | + <article v-for="connector in visibleComposioPreviewConnectors" :key="connector.slug" class="directory-card composio-preview-card"> |
| 265 | + <div class="directory-card-top"> |
| 266 | + <div class="directory-card-fallback composio-fallback">{{ connector.initial }}</div> |
| 267 | + <div class="directory-card-main"> |
| 268 | + <div class="directory-card-title-row"> |
| 269 | + <span class="directory-card-title">{{ connector.name }}</span> |
| 270 | + <span class="directory-badge is-muted">Preview</span> |
| 271 | + </div> |
| 272 | + <span class="directory-card-meta">{{ connector.meta }}</span> |
| 273 | + </div> |
| 274 | + </div> |
| 275 | + <p class="directory-card-description">{{ connector.description }}</p> |
| 276 | + <div class="directory-chip-row"> |
| 277 | + <span v-for="chip in connector.chips" :key="chip" class="directory-chip">{{ chip }}</span> |
| 278 | + </div> |
| 279 | + </article> |
250 | 280 | </div> |
251 | 281 | </div> |
252 | 282 | <div v-else class="directory-section composio-section"> |
@@ -740,6 +770,57 @@ const tabs: Array<{ id: DirectoryTab; label: string; subtitle: string }> = [ |
740 | 770 | { id: 'skills', label: 'Skills', subtitle: 'MCPs first, then installed skills and GitHub sync state.' }, |
741 | 771 | ] |
742 | 772 |
|
| 773 | +const composioPreviewConnectors = [ |
| 774 | + { |
| 775 | + name: 'Gmail', |
| 776 | + slug: 'gmail', |
| 777 | + initial: 'G', |
| 778 | + meta: 'Inbox, drafts, attachments', |
| 779 | + description: 'Find emails, summarize threads, draft replies, and pull attachment context into a chat.', |
| 780 | + chips: ['Email', 'Search', 'Drafts'], |
| 781 | + }, |
| 782 | + { |
| 783 | + name: 'Google Calendar', |
| 784 | + slug: 'google-calendar', |
| 785 | + initial: 'C', |
| 786 | + meta: 'Events and availability', |
| 787 | + description: 'Check what is next, find open time, and turn follow-ups into calendar blocks.', |
| 788 | + chips: ['Events', 'Availability', 'Reminders'], |
| 789 | + }, |
| 790 | + { |
| 791 | + name: 'Reddit', |
| 792 | + slug: 'reddit', |
| 793 | + initial: 'R', |
| 794 | + meta: 'Posts, comments, communities', |
| 795 | + description: 'Search communities, inspect posts, and prepare natural replies before posting.', |
| 796 | + chips: ['Search', 'Comments', 'Posts'], |
| 797 | + }, |
| 798 | + { |
| 799 | + name: 'YouTube', |
| 800 | + slug: 'youtube', |
| 801 | + initial: 'Y', |
| 802 | + meta: 'Videos, channels, comments', |
| 803 | + description: 'Look up channel details, inspect video metadata, and help manage comment workflows.', |
| 804 | + chips: ['Videos', 'Channels', 'Comments'], |
| 805 | + }, |
| 806 | + { |
| 807 | + name: 'Google Drive', |
| 808 | + slug: 'google-drive', |
| 809 | + initial: 'D', |
| 810 | + meta: 'Files, docs, folders', |
| 811 | + description: 'Find files, read shared docs, and bring Drive context into a Codex thread.', |
| 812 | + chips: ['Files', 'Docs', 'Search'], |
| 813 | + }, |
| 814 | + { |
| 815 | + name: 'X', |
| 816 | + slug: 'x', |
| 817 | + initial: 'X', |
| 818 | + meta: 'Posts, replies, profiles', |
| 819 | + description: 'Research public posts, draft replies, and keep social workflows reviewable.', |
| 820 | + chips: ['Posts', 'Replies', 'Profiles'], |
| 821 | + }, |
| 822 | +] |
| 823 | +
|
743 | 824 | function isDirectoryTab(value: unknown): value is DirectoryTab { |
744 | 825 | return value === 'plugins' || value === 'apps' || value === 'composio' || value === 'skills' |
745 | 826 | } |
@@ -845,6 +926,17 @@ const visibleComposioConnectors = computed(() => sortComposioConnectors( |
845 | 926 | composioSortMode.value, |
846 | 927 | composioSearchQuery.value, |
847 | 928 | )) |
| 929 | +const visibleComposioPreviewConnectors = computed(() => { |
| 930 | + const query = normalizeSearch(composioSearchQuery.value) |
| 931 | + if (!query) return composioPreviewConnectors |
| 932 | + return composioPreviewConnectors.filter((connector) => includesSearch([ |
| 933 | + connector.name, |
| 934 | + connector.slug, |
| 935 | + connector.meta, |
| 936 | + connector.description, |
| 937 | + ...connector.chips, |
| 938 | + ], query)) |
| 939 | +}) |
848 | 940 | const visibleMcpServers = computed(() => sortMcpServers(mcpServers.value, 'popular')) |
849 | 941 | const hasMoreComposioConnectors = computed(() => composioNextCursor.value !== null) |
850 | 942 | const mcpStatusByName = computed(() => new Map(mcpServers.value.map((server) => [server.name, server]))) |
@@ -1953,6 +2045,42 @@ button.directory-card { |
1953 | 2045 | @apply min-h-0; |
1954 | 2046 | } |
1955 | 2047 |
|
| 2048 | +.composio-preview { |
| 2049 | + @apply flex flex-col gap-3; |
| 2050 | +} |
| 2051 | +
|
| 2052 | +.composio-preview-hero { |
| 2053 | + @apply flex flex-col gap-4 overflow-hidden rounded-xl border border-sky-200 bg-sky-50 p-4 sm:flex-row sm:items-center sm:justify-between; |
| 2054 | +} |
| 2055 | +
|
| 2056 | +.composio-preview-copy { |
| 2057 | + @apply flex min-w-0 items-start gap-3; |
| 2058 | +} |
| 2059 | +
|
| 2060 | +.composio-preview-kicker { |
| 2061 | + @apply m-0 text-xs font-semibold uppercase text-sky-700; |
| 2062 | +} |
| 2063 | +
|
| 2064 | +.composio-preview-title { |
| 2065 | + @apply m-0 mt-1 max-w-2xl text-lg font-semibold leading-snug text-zinc-950; |
| 2066 | +} |
| 2067 | +
|
| 2068 | +.composio-preview-text { |
| 2069 | + @apply m-0 mt-2 max-w-2xl text-sm leading-relaxed text-zinc-600; |
| 2070 | +} |
| 2071 | +
|
| 2072 | +.composio-preview-actions { |
| 2073 | + @apply flex shrink-0 flex-wrap items-center gap-2; |
| 2074 | +} |
| 2075 | +
|
| 2076 | +.composio-preview-grid { |
| 2077 | + @apply grid grid-cols-1 gap-3 md:grid-cols-2 xl:grid-cols-3; |
| 2078 | +} |
| 2079 | +
|
| 2080 | +.composio-preview-card { |
| 2081 | + @apply border-sky-100 bg-white; |
| 2082 | +} |
| 2083 | +
|
1956 | 2084 | .composio-fallback { |
1957 | 2085 | @apply bg-sky-100 text-sky-700; |
1958 | 2086 | } |
@@ -2085,6 +2213,26 @@ button.directory-card { |
2085 | 2213 | @apply border-zinc-700 bg-zinc-900 text-zinc-400; |
2086 | 2214 | } |
2087 | 2215 |
|
| 2216 | +:global(:root.dark) .composio-preview-hero { |
| 2217 | + @apply border-sky-900/70 bg-sky-950/40; |
| 2218 | +} |
| 2219 | +
|
| 2220 | +:global(:root.dark) .composio-preview-card { |
| 2221 | + @apply border-sky-900/60 bg-zinc-900; |
| 2222 | +} |
| 2223 | +
|
| 2224 | +:global(:root.dark) .composio-preview-kicker { |
| 2225 | + @apply text-sky-300; |
| 2226 | +} |
| 2227 | +
|
| 2228 | +:global(:root.dark) .composio-preview-title { |
| 2229 | + @apply text-zinc-100; |
| 2230 | +} |
| 2231 | +
|
| 2232 | +:global(:root.dark) .composio-preview-text { |
| 2233 | + @apply text-zinc-400; |
| 2234 | +} |
| 2235 | +
|
2088 | 2236 | :global(:root.dark) .directory-auth-status.is-error, |
2089 | 2237 | :global(:root.dark) .directory-error, |
2090 | 2238 | :global(:root.dark) .directory-toast.is-error { |
|
0 commit comments