feat(market): show certification badges in Core marketplace (#2615)

This commit is contained in:
RockChinQ
2026-09-30 18:52:00 +08:00
committed by GitHub
parent 5a31ac75fc
commit 5f3eb34baf
14 changed files with 108 additions and 0 deletions
@@ -298,6 +298,7 @@ function MarketPageContent({
iconURL,
githubURL: plugin.repository,
version: plugin.latest_version,
certificationStatus: plugin.certification_status,
components: plugin.components || {},
tags: plugin.tags || [],
type: plugin.type,
@@ -57,6 +57,7 @@ function pluginToVO(
iconURL,
githubURL: plugin.repository,
version: plugin.latest_version,
certificationStatus: plugin.certification_status,
components: plugin.components,
tags: plugin.tags || [],
type: plugin.type,
@@ -1,3 +1,4 @@
import { CertifiedPluginBadge } from '@/components/market/CertifiedPluginBadge';
import { PluginMarketCardVO } from './PluginMarketCardVO';
import { useRef, useState, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
@@ -276,6 +277,9 @@ export default function PluginMarketCardComponent({
<span className="truncate">{typeLabel}</span>
</Badge>
)}
{cardVO.certificationStatus === 'issued' && (
<CertifiedPluginBadge compact />
)}
</div>
</div>
@@ -9,6 +9,7 @@ export interface IPluginMarketCardVO {
iconURL: string;
githubURL: string;
version: string;
certificationStatus?: string;
components?: Record<string, number>;
tags?: string[];
type?: 'plugin' | 'mcp' | 'skill';
@@ -29,6 +30,7 @@ export class PluginMarketCardVO implements IPluginMarketCardVO {
installCount: number;
likeCount: number;
version: string;
certificationStatus?: string;
components?: Record<string, number>;
tags?: string[];
type?: 'plugin' | 'mcp' | 'skill';
@@ -46,6 +48,7 @@ export class PluginMarketCardVO implements IPluginMarketCardVO {
this.likeCount = prop.likeCount ?? 0;
this.pluginId = prop.pluginId;
this.version = prop.version;
this.certificationStatus = prop.certificationStatus;
this.components = prop.components;
this.tags = prop.tags;
this.type = prop.type;
@@ -36,6 +36,7 @@ export enum PluginV4Status {
}
export interface PluginV4 {
certification_status?: string;
id: number;
plugin_id: string;
mcp_id?: string;
@@ -0,0 +1,58 @@
'use client';
import { BadgeCheck } from 'lucide-react';
import { useTranslation } from 'react-i18next';
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from '@/components/ui/tooltip';
export function CertifiedPluginBadge({
compact = false,
}: {
compact?: boolean;
}) {
const { t, i18n } = useTranslation();
const language = i18n.language.startsWith('zh')
? 'zh'
: i18n.language.startsWith('ja')
? 'ja'
: 'en';
const docsURL = `https://langbot.app/docs/${language}/plugin/certified-plugins`;
return (
<TooltipProvider delayDuration={200}>
<Tooltip>
<TooltipTrigger asChild>
<a
href={docsURL}
target="_blank"
rel="noopener noreferrer"
aria-label={`${t('market.certifiedPlugin')}: ${t('market.certificationLearnMore')}`}
onClick={(event) => event.stopPropagation()}
className={`inline-flex shrink-0 items-center gap-1 rounded border border-emerald-600/25 bg-emerald-50 text-emerald-700 dark:bg-emerald-950/40 dark:text-emerald-400 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-emerald-500 ${compact ? 'h-4 px-0.5' : 'px-2 py-0.5 text-xs font-medium'}`}
>
<BadgeCheck
aria-hidden="true"
className={compact ? 'h-3 w-3' : 'h-3.5 w-3.5'}
/>
{!compact && t('market.certifiedPlugin')}
</a>
</TooltipTrigger>
<TooltipContent className="max-w-72 text-xs">
<p>{t('market.certificationTooltip')}</p>
<a
href={docsURL}
target="_blank"
rel="noopener noreferrer"
className="mt-1 inline-block underline underline-offset-2"
onClick={(event) => event.stopPropagation()}
>
{t('market.certificationLearnMore')}
</a>
</TooltipContent>
</Tooltip>
</TooltipProvider>
);
}
+5
View File
@@ -1624,6 +1624,11 @@ const enUS = {
},
},
market: {
certifiedPlugin: 'Certified plugin',
certificationTooltip:
'This version has passed a review of data isolation and compatibility with shared runtimes, and its package is signed.',
certificationLearnMore: 'Learn about certification',
runnerUsage: 'Runner usage',
runnerUsageAll: 'All',
runnerUsageAgent: 'Agent / Pipeline',
+5
View File
@@ -1655,6 +1655,11 @@ const esES = {
},
},
market: {
certifiedPlugin: 'Plugin certificado',
certificationTooltip:
'Esta versión ha superado la revisión de aislamiento de datos y compatibilidad con entornos compartidos. El paquete está firmado.',
certificationLearnMore: 'Acerca de la certificación',
runnerUsage: 'Uso del ejecutor',
runnerUsageAll: 'Todos',
runnerUsageAgent: 'Agent / Flujo',
+5
View File
@@ -1639,6 +1639,11 @@ const jaJP = {
},
},
market: {
certifiedPlugin: '認証済みプラグイン',
certificationTooltip:
'このバージョンはデータ分離と共有実行環境との互換性の審査に合格し、パッケージに署名されています。',
certificationLearnMore: 'プラグイン認証について',
runnerUsage: 'ランナーの用途',
runnerUsageAll: 'すべて',
runnerUsageAgent: 'Agent / パイプライン',
+5
View File
@@ -1651,6 +1651,11 @@ const ruRU = {
},
},
market: {
certifiedPlugin: 'Сертифицированный плагин',
certificationTooltip:
'Эта версия прошла проверку изоляции данных и совместимости с общей средой выполнения. Пакет подписан.',
certificationLearnMore: 'О сертификации',
runnerUsage: 'Назначение исполнителя',
runnerUsageAll: 'Все',
runnerUsageAgent: 'Agent / Конвейер',
+5
View File
@@ -1593,6 +1593,11 @@ const thTH = {
},
},
market: {
certifiedPlugin: 'ปลั๊กอินที่ผ่านการรับรอง',
certificationTooltip:
'เวอร์ชันนี้ผ่านการตรวจสอบการแยกข้อมูลและความเข้ากันได้กับสภาพแวดล้อมรันร่วมกัน และแพ็กเกจได้รับการลงนามแล้ว',
certificationLearnMore: 'เกี่ยวกับการรับรองปลั๊กอิน',
runnerUsage: 'การใช้งานรันเนอร์',
runnerUsageAll: 'ทั้งหมด',
runnerUsageAgent: 'Agent / ไปป์ไลน์',
+5
View File
@@ -1619,6 +1619,11 @@ const viVN = {
},
},
market: {
certifiedPlugin: 'Plugin được chứng nhận',
certificationTooltip:
'Phiên bản này đã vượt qua đánh giá về cách ly dữ liệu và khả năng tương thích với môi trường chạy dùng chung. Gói đã được ký.',
certificationLearnMore: 'Tìm hiểu về chứng nhận',
runnerUsage: 'Mục đích trình chạy',
runnerUsageAll: 'Tất cả',
runnerUsageAgent: 'Agent / Pipeline',
+5
View File
@@ -1531,6 +1531,11 @@ const zhHans = {
},
},
market: {
certifiedPlugin: '认证插件',
certificationTooltip:
'此版本已通过数据隔离与共享运行环境兼容性审核,插件包已签名。',
certificationLearnMore: '了解插件认证',
runnerUsage: '运行器用途',
runnerUsageAll: '全部',
runnerUsageAgent: 'Agent / 流水线',
+5
View File
@@ -1529,6 +1529,11 @@ const zhHant = {
},
},
market: {
certifiedPlugin: '認證外掛',
certificationTooltip:
'此版本已通過資料隔離與共享執行環境相容性審核,外掛套件已簽章。',
certificationLearnMore: '瞭解外掛認證',
runnerUsage: '運行器用途',
runnerUsageAll: '全部',
runnerUsageAgent: 'Agent / 流水線',