@yancyyu/openhermit 1.6.36 → 1.6.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-renderer/assets/{ProjectEditorOverlay-B_QAoeaA.js → ProjectEditorOverlay-lJZi-9Hp.js} +1 -1
- package/dist-renderer/assets/{TeamGraphOverlay-PB9luAZU.js → TeamGraphOverlay-ZEDfZyHb.js} +1 -1
- package/dist-renderer/assets/{_basePickBy-Dfzcp_Ry.js → _basePickBy-CIhniz70.js} +1 -1
- package/dist-renderer/assets/{_baseUniq-B5u2Yiq2.js → _baseUniq-cKAW4Q8I.js} +1 -1
- package/dist-renderer/assets/{arc-DElOI7qz.js → arc-YmNsoDXW.js} +1 -1
- package/dist-renderer/assets/{architectureDiagram-VXUJARFQ-Cf6f4tCu.js → architectureDiagram-VXUJARFQ-DHEls2sX.js} +1 -1
- package/dist-renderer/assets/{blockDiagram-VD42YOAC-FJUdo9Ry.js → blockDiagram-VD42YOAC-Bpwf1Sbg.js} +1 -1
- package/dist-renderer/assets/{c4Diagram-YG6GDRKO-BvJQS9lb.js → c4Diagram-YG6GDRKO-B0IaQ4w5.js} +1 -1
- package/dist-renderer/assets/channel-yIlSKy0e.js +1 -0
- package/dist-renderer/assets/{chunk-4BX2VUAB-n-SGLbin.js → chunk-4BX2VUAB-DLk-hcFc.js} +1 -1
- package/dist-renderer/assets/{chunk-55IACEB6-Dwle9tlA.js → chunk-55IACEB6-1XRmX_Zm.js} +1 -1
- package/dist-renderer/assets/{chunk-B4BG7PRW-Dic8YxQz.js → chunk-B4BG7PRW-1waH1DAD.js} +1 -1
- package/dist-renderer/assets/{chunk-DI55MBZ5-3n5jC1jk.js → chunk-DI55MBZ5-BqpZBtrN.js} +1 -1
- package/dist-renderer/assets/{chunk-FMBD7UC4-BqizUB3O.js → chunk-FMBD7UC4-Bly7vVym.js} +1 -1
- package/dist-renderer/assets/{chunk-QN33PNHL-JRDmD8o9.js → chunk-QN33PNHL-Ci2QWBAs.js} +1 -1
- package/dist-renderer/assets/{chunk-QZHKN3VN-BxFpQw92.js → chunk-QZHKN3VN-YCqFW7d-.js} +1 -1
- package/dist-renderer/assets/{chunk-TZMSLE5B-ByqPwtW9.js → chunk-TZMSLE5B-B0xGXInl.js} +1 -1
- package/dist-renderer/assets/classDiagram-2ON5EDUG-24fHez0s.js +1 -0
- package/dist-renderer/assets/classDiagram-v2-WZHVMYZB-24fHez0s.js +1 -0
- package/dist-renderer/assets/clone-BTNuUva-.js +1 -0
- package/dist-renderer/assets/{cose-bilkent-S5V4N54A-CVztr86T.js → cose-bilkent-S5V4N54A-DxcFNQKT.js} +1 -1
- package/dist-renderer/assets/{dagre-6UL2VRFP-CIui920O.js → dagre-6UL2VRFP-DPo_RfZY.js} +1 -1
- package/dist-renderer/assets/{diagram-PSM6KHXK-CyL8-bgb.js → diagram-PSM6KHXK-U3hQsFe4.js} +1 -1
- package/dist-renderer/assets/{diagram-QEK2KX5R-CM_67YoY.js → diagram-QEK2KX5R-OrwrAy0V.js} +1 -1
- package/dist-renderer/assets/{diagram-S2PKOQOG-DtrtPSGg.js → diagram-S2PKOQOG-CXATPWVw.js} +1 -1
- package/dist-renderer/assets/{erDiagram-Q2GNP2WA-bOICzF9d.js → erDiagram-Q2GNP2WA-B0e8AfMF.js} +1 -1
- package/dist-renderer/assets/{flowDiagram-NV44I4VS-CJV1g9Hr.js → flowDiagram-NV44I4VS-CXfzA4jJ.js} +1 -1
- package/dist-renderer/assets/{ganttDiagram-JELNMOA3-CXbhDo09.js → ganttDiagram-JELNMOA3-CMr08qVl.js} +1 -1
- package/dist-renderer/assets/{gitGraphDiagram-V2S2FVAM-vbXopTpS.js → gitGraphDiagram-V2S2FVAM-vYFHpPmy.js} +1 -1
- package/dist-renderer/assets/{graph-CY2T-j4q.js → graph-DOe5j8dH.js} +1 -1
- package/dist-renderer/assets/{index-Dv7q-OB0.js → index-B2Dy7M2G.js} +1 -1
- package/dist-renderer/assets/index-Bi6nrZ4z.css +1 -0
- package/dist-renderer/assets/{index-CpyChjme.js → index-BySQS7AB.js} +1 -1
- package/dist-renderer/assets/{index-S-i9egm8.js → index-C_okzZXP.js} +1 -1
- package/dist-renderer/assets/{index-Mrh4pTHw.js → index-CzWxVCRL.js} +1 -1
- package/dist-renderer/assets/{index-Dn-BpzSm.js → index-V7dAKPqd.js} +571 -607
- package/dist-renderer/assets/{index-C9ONRXVI.js → index-VJ-MM9xa.js} +1 -1
- package/dist-renderer/assets/{infoDiagram-HS3SLOUP-BNg14AdU.js → infoDiagram-HS3SLOUP-D_WubR0B.js} +1 -1
- package/dist-renderer/assets/{journeyDiagram-XKPGCS4Q-2_PkPCiu.js → journeyDiagram-XKPGCS4Q-w9ca-1TI.js} +1 -1
- package/dist-renderer/assets/{kanban-definition-3W4ZIXB7-DjTx7qoU.js → kanban-definition-3W4ZIXB7-Jg9p6_pN.js} +1 -1
- package/dist-renderer/assets/{layout-DZlHGGN0.js → layout-B-z3y17c.js} +1 -1
- package/dist-renderer/assets/{linear-DnlOm48z.js → linear-D-RTX5UW.js} +1 -1
- package/dist-renderer/assets/{mindmap-definition-VGOIOE7T-B-nrgt7V.js → mindmap-definition-VGOIOE7T-CDQmHOYP.js} +1 -1
- package/dist-renderer/assets/{pieDiagram-ADFJNKIX-BToJFvWR.js → pieDiagram-ADFJNKIX-D_odsQL7.js} +1 -1
- package/dist-renderer/assets/{quadrantDiagram-AYHSOK5B-C0qoxXvH.js → quadrantDiagram-AYHSOK5B-BRsmYWSA.js} +1 -1
- package/dist-renderer/assets/{requirementDiagram-UZGBJVZJ-DCKGwsGN.js → requirementDiagram-UZGBJVZJ-ChNE_BOV.js} +1 -1
- package/dist-renderer/assets/{sankeyDiagram-TZEHDZUN-CS6JCcu7.js → sankeyDiagram-TZEHDZUN-C8FtpwKc.js} +1 -1
- package/dist-renderer/assets/{sequenceDiagram-WL72ISMW-C9pAWoSR.js → sequenceDiagram-WL72ISMW-DmLCzNcc.js} +1 -1
- package/dist-renderer/assets/{stateDiagram-FKZM4ZOC-BTTX_v1m.js → stateDiagram-FKZM4ZOC-WJBm4bhu.js} +1 -1
- package/dist-renderer/assets/{stateDiagram-v2-4FDKWEC3-BHk97lQJ.js → stateDiagram-v2-4FDKWEC3-_m6iPPUR.js} +1 -1
- package/dist-renderer/assets/{timeline-definition-IT6M3QCI-CSWCEzCQ.js → timeline-definition-IT6M3QCI-BXs_hOJs.js} +1 -1
- package/dist-renderer/assets/{treemap-GDKQZRPO-CmiIc68g.js → treemap-GDKQZRPO-o04MA0G9.js} +1 -1
- package/dist-renderer/assets/{xychartDiagram-PRI3JC2R-DhwSTphI.js → xychartDiagram-PRI3JC2R-Czj69XRd.js} +1 -1
- package/dist-renderer/index.html +2 -2
- package/package.json +2 -2
- package/src/main/ipc/extensions.ts +29 -50
- package/src/main/server.ts +17 -26
- package/src/main/services/extensions/ExtensionFacadeService.ts +2 -51
- package/src/main/services/extensions/library/McpLibraryService.ts +243 -0
- package/src/main/services/session-intelligence/UsageTelemetryService.ts +14 -1
- package/src/main/services/teams-mvp/TaskDispatchService.ts +32 -7
- package/src/renderer/api/httpClient.ts +108 -22
- package/src/renderer/components/extensions/ExtensionStoreView.tsx +6 -96
- package/src/renderer/components/extensions/plugins/PluginCard.tsx +8 -0
- package/src/renderer/components/extensions/plugins/PluginsPanel.tsx +13 -8
- package/src/renderer/components/team/TeamDetailView.tsx +15 -0
- package/src/renderer/components/team/tools/AddMcpInline.tsx +47 -0
- package/src/renderer/components/team/tools/AddSkillInline.tsx +61 -0
- package/src/renderer/components/team/tools/McpChip.tsx +42 -0
- package/src/renderer/components/team/tools/SkillChip.tsx +35 -0
- package/src/renderer/components/team/tools/ToolsSection.tsx +208 -0
- package/src/shared/types/extensions/api.ts +9 -0
- package/src/shared/types/extensions/index.ts +4 -0
- package/src/shared/types/extensions/mcp.ts +41 -0
- package/src/shared/utils/extensionNormalizers.ts +22 -0
- package/dist-renderer/assets/channel-DnbgZg0A.js +0 -1
- package/dist-renderer/assets/classDiagram-2ON5EDUG-BAD4p014.js +0 -1
- package/dist-renderer/assets/classDiagram-v2-WZHVMYZB-BAD4p014.js +0 -1
- package/dist-renderer/assets/clone-CRX5ZTPd.js +0 -1
- package/dist-renderer/assets/index-B2z_IyRH.css +0 -1
- package/src/main/services/extensions/catalog/GlamaMcpEnrichmentService.ts +0 -190
- package/src/main/services/extensions/catalog/McpCatalogAggregator.ts +0 -150
- package/src/main/services/extensions/catalog/OfficialMcpRegistryService.ts +0 -381
- package/src/main/services/extensions/install/McpInstallService.ts +0 -407
- package/src/main/services/extensions/state/McpInstallationStateService.ts +0 -42
- package/src/renderer/components/extensions/mcp/McpServerCard.tsx +0 -314
- package/src/renderer/components/extensions/mcp/McpServerDetailDialog.tsx +0 -765
- package/src/renderer/components/extensions/mcp/McpServersPanel.tsx +0 -593
- package/src/renderer/components/extensions/skills/SkillDetailDialog.tsx +0 -372
- package/src/renderer/components/extensions/skills/SkillImportDialog.tsx +0 -343
- package/src/renderer/components/extensions/skills/SkillsPanel.tsx +0 -659
|
@@ -1,314 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* McpServerCard — grid card for a single MCP server in the catalog.
|
|
3
|
-
* Shows server icon from registry when available.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { useState } from 'react';
|
|
7
|
-
|
|
8
|
-
import { api } from '@renderer/api';
|
|
9
|
-
import { Badge } from '@renderer/components/ui/badge';
|
|
10
|
-
import { Button } from '@renderer/components/ui/button';
|
|
11
|
-
import { Tooltip, TooltipContent, TooltipTrigger } from '@renderer/components/ui/tooltip';
|
|
12
|
-
import { useStore } from '@renderer/store';
|
|
13
|
-
import { formatCompactNumber, formatRelativeTime } from '@renderer/utils/formatters';
|
|
14
|
-
import {
|
|
15
|
-
getMcpInstallationSummaryLabel,
|
|
16
|
-
getMcpOperationKey,
|
|
17
|
-
sanitizeMcpServerName,
|
|
18
|
-
} from '@shared/utils/extensionNormalizers';
|
|
19
|
-
import { getDefaultMcpSharedScope } from '@shared/utils/mcpScopes';
|
|
20
|
-
import { Clock, Cloud, Globe, KeyRound, Lock, Monitor, Star, Tag, Wrench } from 'lucide-react';
|
|
21
|
-
import { Github as GithubIcon } from 'lucide-react';
|
|
22
|
-
|
|
23
|
-
import { InstallButton } from '../common/InstallButton';
|
|
24
|
-
import { SourceBadge } from '../common/SourceBadge';
|
|
25
|
-
|
|
26
|
-
import type { CliInstallationStatus } from '@shared/types';
|
|
27
|
-
import type {
|
|
28
|
-
InstalledMcpEntry,
|
|
29
|
-
McpCatalogItem,
|
|
30
|
-
McpServerDiagnostic,
|
|
31
|
-
} from '@shared/types/extensions';
|
|
32
|
-
|
|
33
|
-
interface McpServerCardProps {
|
|
34
|
-
server: McpCatalogItem;
|
|
35
|
-
isInstalled: boolean;
|
|
36
|
-
installedEntry?: InstalledMcpEntry | null;
|
|
37
|
-
installedEntries?: InstalledMcpEntry[];
|
|
38
|
-
diagnostic?: McpServerDiagnostic | null;
|
|
39
|
-
diagnosticsLoading?: boolean;
|
|
40
|
-
onClick: (serverId: string) => void;
|
|
41
|
-
cliStatus?: Pick<
|
|
42
|
-
CliInstallationStatus,
|
|
43
|
-
'installed' | 'authLoggedIn' | 'binaryPath' | 'launchError' | 'flavor' | 'providers'
|
|
44
|
-
> | null;
|
|
45
|
-
cliStatusLoading?: boolean;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export const McpServerCard = ({
|
|
49
|
-
server,
|
|
50
|
-
isInstalled,
|
|
51
|
-
installedEntry,
|
|
52
|
-
installedEntries = [],
|
|
53
|
-
diagnostic,
|
|
54
|
-
diagnosticsLoading,
|
|
55
|
-
onClick,
|
|
56
|
-
cliStatus: cliStatusOverride,
|
|
57
|
-
cliStatusLoading,
|
|
58
|
-
}: McpServerCardProps): React.JSX.Element => {
|
|
59
|
-
const storedCliStatus = useStore((s) => s.cliStatus);
|
|
60
|
-
const cliStatus = cliStatusOverride ?? storedCliStatus;
|
|
61
|
-
const sharedScope = getDefaultMcpSharedScope(cliStatus?.flavor);
|
|
62
|
-
const operationKey = getMcpOperationKey(server.id, sharedScope);
|
|
63
|
-
const installProgress = useStore((s) => s.mcpInstallProgress[operationKey] ?? 'idle');
|
|
64
|
-
const installMcpServer = useStore((s) => s.installMcpServer);
|
|
65
|
-
const uninstallMcpServer = useStore((s) => s.uninstallMcpServer);
|
|
66
|
-
const installError = useStore((s) => s.installErrors[operationKey]);
|
|
67
|
-
const stars = useStore((s) =>
|
|
68
|
-
server.repositoryUrl ? s.mcpGitHubStars[server.repositoryUrl] : undefined
|
|
69
|
-
);
|
|
70
|
-
const canAutoInstall = !!server.installSpec;
|
|
71
|
-
const normalizedInstalledEntries = installedEntries.length
|
|
72
|
-
? installedEntries
|
|
73
|
-
: installedEntry
|
|
74
|
-
? [installedEntry]
|
|
75
|
-
: [];
|
|
76
|
-
const requiresConfiguration =
|
|
77
|
-
server.installSpec?.type === 'http' ||
|
|
78
|
-
server.envVars.length > 0 ||
|
|
79
|
-
server.requiresAuth ||
|
|
80
|
-
(server.authHeaders?.length ?? 0) > 0;
|
|
81
|
-
const defaultServerName = sanitizeMcpServerName(server.name);
|
|
82
|
-
const sharedInstallEntry =
|
|
83
|
-
normalizedInstalledEntries.find((entry) => entry.scope === sharedScope) ?? null;
|
|
84
|
-
const installSummaryLabel = getMcpInstallationSummaryLabel(normalizedInstalledEntries);
|
|
85
|
-
const supportsDirectInstalledAction =
|
|
86
|
-
isInstalled &&
|
|
87
|
-
normalizedInstalledEntries.length === 1 &&
|
|
88
|
-
sharedInstallEntry?.name === defaultServerName &&
|
|
89
|
-
!requiresConfiguration;
|
|
90
|
-
const shouldShowDirectInstallButton =
|
|
91
|
-
canAutoInstall && (!isInstalled ? !requiresConfiguration : supportsDirectInstalledAction);
|
|
92
|
-
const [imgError, setImgError] = useState(false);
|
|
93
|
-
const hasIcon = !!server.iconUrl && !imgError;
|
|
94
|
-
const diagnosticBadgeClass =
|
|
95
|
-
diagnostic?.status === 'connected'
|
|
96
|
-
? 'border-emerald-500/30 bg-emerald-500/10 text-emerald-400'
|
|
97
|
-
: diagnostic?.status === 'needs-authentication'
|
|
98
|
-
? 'border-amber-500/30 bg-amber-500/10 text-amber-400'
|
|
99
|
-
: diagnostic?.status === 'failed'
|
|
100
|
-
? 'border-red-500/30 bg-red-500/10 text-red-400'
|
|
101
|
-
: 'border-border bg-surface-raised text-text-muted';
|
|
102
|
-
|
|
103
|
-
return (
|
|
104
|
-
<div
|
|
105
|
-
role="button"
|
|
106
|
-
tabIndex={0}
|
|
107
|
-
onClick={() => onClick(server.id)}
|
|
108
|
-
onKeyDown={(e) => {
|
|
109
|
-
if (e.key === 'Enter' || e.key === ' ') {
|
|
110
|
-
e.preventDefault();
|
|
111
|
-
onClick(server.id);
|
|
112
|
-
}
|
|
113
|
-
}}
|
|
114
|
-
className={`relative flex w-full cursor-pointer flex-col gap-2 overflow-hidden rounded-lg border p-4 text-left transition-all duration-200 hover:border-border-emphasis hover:bg-surface-raised hover:shadow-[0_0_12px_rgba(255,255,255,0.02)] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-[var(--color-border-emphasis)] ${
|
|
115
|
-
isInstalled ? 'border-l-2 border-border border-l-emerald-500/30' : 'border-border'
|
|
116
|
-
}`}
|
|
117
|
-
>
|
|
118
|
-
{/* Header: icon + name */}
|
|
119
|
-
<div className="flex items-start gap-2.5">
|
|
120
|
-
{/* Server icon (only when available) */}
|
|
121
|
-
{hasIcon && (
|
|
122
|
-
<div className="flex size-9 shrink-0 items-center justify-center rounded-lg border border-border bg-surface-raised">
|
|
123
|
-
<img
|
|
124
|
-
src={server.iconUrl}
|
|
125
|
-
alt=""
|
|
126
|
-
className="size-7 rounded object-contain"
|
|
127
|
-
onError={() => setImgError(true)}
|
|
128
|
-
/>
|
|
129
|
-
</div>
|
|
130
|
-
)}
|
|
131
|
-
<div className="min-w-0 flex-1">
|
|
132
|
-
<div className="flex items-start justify-between gap-2">
|
|
133
|
-
<div className="min-w-0">
|
|
134
|
-
<h3 className="truncate text-sm font-semibold text-text">{server.name}</h3>
|
|
135
|
-
{server.source !== 'official' && (
|
|
136
|
-
<div className="mt-1">
|
|
137
|
-
<SourceBadge source={server.source} />
|
|
138
|
-
</div>
|
|
139
|
-
)}
|
|
140
|
-
</div>
|
|
141
|
-
<div className="flex shrink-0 items-center gap-1.5">
|
|
142
|
-
{isInstalled && (
|
|
143
|
-
<Badge
|
|
144
|
-
className="border-emerald-500/30 bg-emerald-500/10 text-emerald-400"
|
|
145
|
-
variant="outline"
|
|
146
|
-
>
|
|
147
|
-
{installSummaryLabel ?? 'Installed'}
|
|
148
|
-
</Badge>
|
|
149
|
-
)}
|
|
150
|
-
{isInstalled && diagnosticsLoading && !diagnostic && (
|
|
151
|
-
<Badge
|
|
152
|
-
className="border-border bg-surface-raised text-text-muted"
|
|
153
|
-
variant="outline"
|
|
154
|
-
>
|
|
155
|
-
Checking...
|
|
156
|
-
</Badge>
|
|
157
|
-
)}
|
|
158
|
-
{diagnostic && (
|
|
159
|
-
<Badge className={diagnosticBadgeClass} variant="outline">
|
|
160
|
-
{diagnostic.statusLabel}
|
|
161
|
-
</Badge>
|
|
162
|
-
)}
|
|
163
|
-
</div>
|
|
164
|
-
</div>
|
|
165
|
-
</div>
|
|
166
|
-
</div>
|
|
167
|
-
|
|
168
|
-
{/* Description */}
|
|
169
|
-
<p className="line-clamp-2 text-xs text-text-secondary">{server.description}</p>
|
|
170
|
-
{diagnostic?.target && (
|
|
171
|
-
<p className="truncate font-mono text-[10px] text-text-muted" title={diagnostic.target}>
|
|
172
|
-
{diagnostic.target}
|
|
173
|
-
</p>
|
|
174
|
-
)}
|
|
175
|
-
|
|
176
|
-
{/* Footer indicators + install button */}
|
|
177
|
-
<div className="flex items-center justify-between gap-2">
|
|
178
|
-
<div className="flex min-w-0 flex-wrap items-center gap-x-3 gap-y-1 text-xs text-text-muted">
|
|
179
|
-
{server.tools.length > 0 && (
|
|
180
|
-
<span className="inline-flex items-center gap-1 rounded-full bg-surface-raised px-1.5 py-0.5 ring-1 ring-border">
|
|
181
|
-
<Wrench className="size-3" />
|
|
182
|
-
{server.tools.length} {server.tools.length === 1 ? 'tool' : 'tools'}
|
|
183
|
-
</span>
|
|
184
|
-
)}
|
|
185
|
-
{server.envVars.length > 0 && (
|
|
186
|
-
<span className="inline-flex items-center gap-1">
|
|
187
|
-
<KeyRound className="size-3" />
|
|
188
|
-
{server.envVars.length} {server.envVars.length === 1 ? 'env' : 'envs'}
|
|
189
|
-
</span>
|
|
190
|
-
)}
|
|
191
|
-
{server.requiresAuth && (
|
|
192
|
-
<span className="inline-flex items-center gap-1 text-amber-400">
|
|
193
|
-
<Lock className="size-3" />
|
|
194
|
-
Auth
|
|
195
|
-
</span>
|
|
196
|
-
)}
|
|
197
|
-
{server.version && (
|
|
198
|
-
<span className="inline-flex items-center gap-1">
|
|
199
|
-
<Tag className="size-3" />
|
|
200
|
-
{server.version}
|
|
201
|
-
</span>
|
|
202
|
-
)}
|
|
203
|
-
{server.updatedAt && (
|
|
204
|
-
<span className="inline-flex items-center gap-1">
|
|
205
|
-
<Clock className="size-3" />
|
|
206
|
-
{formatRelativeTime(server.updatedAt)}
|
|
207
|
-
</span>
|
|
208
|
-
)}
|
|
209
|
-
{server.author && <span className="truncate">by {server.author}</span>}
|
|
210
|
-
{server.hostingType === 'remote' && (
|
|
211
|
-
<span className="inline-flex items-center gap-1">
|
|
212
|
-
<Cloud className="size-3" />
|
|
213
|
-
Remote
|
|
214
|
-
</span>
|
|
215
|
-
)}
|
|
216
|
-
{server.hostingType === 'local' && (
|
|
217
|
-
<span className="inline-flex items-center gap-1">
|
|
218
|
-
<Monitor className="size-3" />
|
|
219
|
-
Local
|
|
220
|
-
</span>
|
|
221
|
-
)}
|
|
222
|
-
{server.hostingType === 'both' && (
|
|
223
|
-
<span className="inline-flex items-center gap-1">
|
|
224
|
-
<Globe className="size-3" />
|
|
225
|
-
Both
|
|
226
|
-
</span>
|
|
227
|
-
)}
|
|
228
|
-
{/* External links + stars */}
|
|
229
|
-
{server.repositoryUrl && (
|
|
230
|
-
<Tooltip>
|
|
231
|
-
<TooltipTrigger asChild>
|
|
232
|
-
<button
|
|
233
|
-
className="inline-flex items-center gap-1.5 text-text-muted transition-colors hover:text-text"
|
|
234
|
-
onClick={(e) => {
|
|
235
|
-
e.stopPropagation();
|
|
236
|
-
void api.openExternal(server.repositoryUrl!);
|
|
237
|
-
}}
|
|
238
|
-
>
|
|
239
|
-
<GithubIcon className="size-3.5" />
|
|
240
|
-
{stars != null && (
|
|
241
|
-
<span className="inline-flex items-center gap-0.5">
|
|
242
|
-
<Star className="size-3 fill-amber-400 text-amber-400" />
|
|
243
|
-
{formatCompactNumber(stars)}
|
|
244
|
-
</span>
|
|
245
|
-
)}
|
|
246
|
-
</button>
|
|
247
|
-
</TooltipTrigger>
|
|
248
|
-
<TooltipContent side="top">Repository</TooltipContent>
|
|
249
|
-
</Tooltip>
|
|
250
|
-
)}
|
|
251
|
-
{server.websiteUrl && (
|
|
252
|
-
<Tooltip>
|
|
253
|
-
<TooltipTrigger asChild>
|
|
254
|
-
<button
|
|
255
|
-
className="inline-flex items-center text-text-muted transition-colors hover:text-text"
|
|
256
|
-
onClick={(e) => {
|
|
257
|
-
e.stopPropagation();
|
|
258
|
-
void api.openExternal(server.websiteUrl!);
|
|
259
|
-
}}
|
|
260
|
-
>
|
|
261
|
-
<Globe className="size-3.5" />
|
|
262
|
-
</button>
|
|
263
|
-
</TooltipTrigger>
|
|
264
|
-
<TooltipContent side="top">Website</TooltipContent>
|
|
265
|
-
</Tooltip>
|
|
266
|
-
)}
|
|
267
|
-
</div>
|
|
268
|
-
{shouldShowDirectInstallButton && (
|
|
269
|
-
<div className="shrink-0">
|
|
270
|
-
<InstallButton
|
|
271
|
-
state={installProgress}
|
|
272
|
-
isInstalled={isInstalled}
|
|
273
|
-
section="mcp"
|
|
274
|
-
cliStatus={cliStatus}
|
|
275
|
-
cliStatusLoading={cliStatusLoading}
|
|
276
|
-
onInstall={() =>
|
|
277
|
-
installMcpServer({
|
|
278
|
-
registryId: server.id,
|
|
279
|
-
serverName: defaultServerName,
|
|
280
|
-
scope: sharedScope,
|
|
281
|
-
envValues: {},
|
|
282
|
-
headers: [],
|
|
283
|
-
})
|
|
284
|
-
}
|
|
285
|
-
onUninstall={() =>
|
|
286
|
-
uninstallMcpServer(
|
|
287
|
-
server.id,
|
|
288
|
-
sharedInstallEntry?.name ?? defaultServerName,
|
|
289
|
-
sharedScope
|
|
290
|
-
)
|
|
291
|
-
}
|
|
292
|
-
size="sm"
|
|
293
|
-
errorMessage={installError}
|
|
294
|
-
/>
|
|
295
|
-
</div>
|
|
296
|
-
)}
|
|
297
|
-
{canAutoInstall && (!shouldShowDirectInstallButton || requiresConfiguration) && (
|
|
298
|
-
<div className="shrink-0">
|
|
299
|
-
<Button
|
|
300
|
-
size="sm"
|
|
301
|
-
variant="outline"
|
|
302
|
-
onClick={(e) => {
|
|
303
|
-
e.stopPropagation();
|
|
304
|
-
onClick(server.id);
|
|
305
|
-
}}
|
|
306
|
-
>
|
|
307
|
-
{isInstalled ? 'Manage' : 'Configure'}
|
|
308
|
-
</Button>
|
|
309
|
-
</div>
|
|
310
|
-
)}
|
|
311
|
-
</div>
|
|
312
|
-
</div>
|
|
313
|
-
);
|
|
314
|
-
};
|