@julianpedro/plugin-dev-ai-hub 0.1.7 → 0.3.0

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.
Files changed (30) hide show
  1. package/dist/api/DevAiHubClient.esm.js +10 -2
  2. package/dist/api/DevAiHubClient.esm.js.map +1 -1
  3. package/dist/components/AssetCard/AssetCard.esm.js +85 -13
  4. package/dist/components/AssetCard/AssetCard.esm.js.map +1 -1
  5. package/dist/components/AssetDetailPanel/AssetDetailPanel.esm.js +272 -85
  6. package/dist/components/AssetDetailPanel/AssetDetailPanel.esm.js.map +1 -1
  7. package/dist/components/AssetFilters/AssetFilters.esm.js +103 -44
  8. package/dist/components/AssetFilters/AssetFilters.esm.js.map +1 -1
  9. package/dist/components/AssetHelpDialog/AssetHelpDialog.esm.js +87 -0
  10. package/dist/components/AssetHelpDialog/AssetHelpDialog.esm.js.map +1 -0
  11. package/dist/components/AssetInstallDialog/AssetInstallDialog.esm.js +328 -108
  12. package/dist/components/AssetInstallDialog/AssetInstallDialog.esm.js.map +1 -1
  13. package/dist/components/DevAiHubPage/DevAiHubPage.esm.js +93 -44
  14. package/dist/components/DevAiHubPage/DevAiHubPage.esm.js.map +1 -1
  15. package/dist/components/McpConfigDialog/McpConfigDialog.esm.js +535 -234
  16. package/dist/components/McpConfigDialog/McpConfigDialog.esm.js.map +1 -1
  17. package/dist/components/ToolIcon/ToolIcon.esm.js +4 -1
  18. package/dist/components/ToolIcon/ToolIcon.esm.js.map +1 -1
  19. package/dist/hooks/index.esm.js +15 -1
  20. package/dist/hooks/index.esm.js.map +1 -1
  21. package/dist/index.d.ts +6 -3
  22. package/dist/index.esm.js +1 -0
  23. package/dist/index.esm.js.map +1 -1
  24. package/dist/locales/es.esm.js +112 -0
  25. package/dist/locales/es.esm.js.map +1 -0
  26. package/dist/locales/pt-BR.esm.js +112 -0
  27. package/dist/locales/pt-BR.esm.js.map +1 -0
  28. package/dist/translation.esm.js +135 -0
  29. package/dist/translation.esm.js.map +1 -0
  30. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"McpConfigDialog.esm.js","sources":["../../../src/components/McpConfigDialog/McpConfigDialog.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport Chip from '@mui/material/Chip';\nimport Collapse from '@mui/material/Collapse';\nimport Dialog from '@mui/material/Dialog';\nimport DialogActions from '@mui/material/DialogActions';\nimport DialogContent from '@mui/material/DialogContent';\nimport DialogTitle from '@mui/material/DialogTitle';\nimport FormControlLabel from '@mui/material/FormControlLabel';\nimport IconButton from '@mui/material/IconButton';\nimport Switch from '@mui/material/Switch';\nimport Tab from '@mui/material/Tab';\nimport Tabs from '@mui/material/Tabs';\nimport Tooltip from '@mui/material/Tooltip';\nimport Typography from '@mui/material/Typography';\nimport { useTheme } from '@mui/material/styles';\nimport ContentCopyIcon from '@mui/icons-material/ContentCopy';\nimport CheckIcon from '@mui/icons-material/Check';\nimport ExpandMoreIcon from '@mui/icons-material/ExpandMore';\nimport StorageIcon from '@mui/icons-material/Storage';\nimport { useApi, discoveryApiRef } from '@backstage/core-plugin-api';\nimport { ToolIcon } from '../ToolIcon';\nimport { useCopyToClipboard, useProviders } from '../../hooks';\nimport type { AiTool } from '@julianpedro/plugin-dev-ai-hub-common';\n\ninterface ToolConfig {\n tool: AiTool;\n label: string;\n file: string;\n description: string;\n buildConfig: (mcpUrl: string) => string;\n}\n\nconst TOOL_CONFIGS: ToolConfig[] = [\n {\n tool: 'claude-code',\n label: 'Claude Code',\n file: '.mcp.json',\n description: 'Add to .mcp.json in your project root (or run via claude mcp add):',\n buildConfig: url => JSON.stringify({\n mcpServers: { 'dev-ai-hub': { type: 'http', url } },\n }, null, 2),\n },\n {\n tool: 'github-copilot',\n label: 'GitHub Copilot',\n file: '.vscode/settings.json',\n description: 'Add to your VS Code settings (.vscode/settings.json or user settings):',\n buildConfig: url => JSON.stringify({\n 'github.copilot.chat.mcp.servers': { 'dev-ai-hub': { type: 'http', url } },\n }, null, 2),\n },\n {\n tool: 'google-gemini',\n label: 'Google Gemini',\n file: 'gemini-config.json',\n description: 'Add to your Gemini CLI configuration:',\n buildConfig: url => JSON.stringify({\n mcpServers: { 'dev-ai-hub': { url } },\n }, null, 2),\n },\n {\n tool: 'cursor',\n label: 'Cursor',\n file: '.cursor/mcp.json',\n description: 'Add to .cursor/mcp.json in your project root:',\n buildConfig: url => JSON.stringify({\n mcpServers: { 'dev-ai-hub': { type: 'http', url } },\n }, null, 2),\n },\n];\n\nfunction providerLabel(target: string): string {\n return target.split('/').pop()?.replace(/\\.git$/, '') ?? target;\n}\n\ninterface McpConfigDialogProps {\n open: boolean;\n onClose: () => void;\n}\n\nexport function McpConfigDialog({ open, onClose }: McpConfigDialogProps) {\n const theme = useTheme();\n const discoveryApi = useApi(discoveryApiRef);\n const { copy: copyUrl, copied: copiedUrl } = useCopyToClipboard();\n const { copy: copySnippet, copied: copiedSnippet } = useCopyToClipboard();\n const [tab, setTab] = useState(0);\n const [baseUrl, setBaseUrl] = useState('');\n const [selectedProvider, setSelectedProvider] = useState<string>('');\n const [proactiveEnabled, setProactiveEnabled] = useState(false);\n const [manualExpanded, setManualExpanded] = useState(false);\n\n const { providers } = useProviders();\n const showProviderFilter = providers.length > 1;\n\n useEffect(() => {\n if (open) {\n discoveryApi.getBaseUrl('dev-ai-hub').then(url => setBaseUrl(url));\n }\n }, [open, discoveryApi]);\n\n const cfg = TOOL_CONFIGS[tab];\n\n const buildMcpUrl = () => {\n if (!baseUrl) return 'loading...';\n const params = new URLSearchParams();\n params.set('tool', cfg.tool);\n if (selectedProvider) params.set('provider', selectedProvider);\n if (proactiveEnabled) params.set('proactive', 'true');\n return `${baseUrl}/mcp?${params.toString()}`;\n };\n\n const mcpUrl = buildMcpUrl();\n const configSnippet = baseUrl ? cfg.buildConfig(mcpUrl) : '';\n\n return (\n <Dialog open={open} onClose={onClose} maxWidth=\"sm\" fullWidth>\n <DialogTitle sx={{ pb: 0 }}>\n <Typography variant=\"h6\" fontWeight={700}>Configure MCP Server</Typography>\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ mt: 0.5 }}>\n Connect your AI tool to the Dev AI Hub via Model Context Protocol.\n </Typography>\n </DialogTitle>\n\n <DialogContent sx={{ pt: 1 }}>\n <Tabs\n value={tab}\n onChange={(_, v) => setTab(v)}\n sx={{ mb: 2, borderBottom: 1, borderColor: 'divider' }}\n >\n {TOOL_CONFIGS.map((t, i) => (\n <Tab\n key={t.tool}\n value={i}\n label={\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>\n <ToolIcon\n tool={t.tool}\n sx={{ fontSize: '1rem', color: theme.palette.mode === 'dark' ? '#fff' : undefined }}\n />\n <span>{t.label}</span>\n </Box>\n }\n />\n ))}\n </Tabs>\n\n {/* Provider filter — only shown when there are 2+ providers */}\n {showProviderFilter && (\n <Box sx={{ mb: 2 }}>\n <Typography variant=\"caption\" fontWeight={600} color=\"text.secondary\" sx={{ textTransform: 'uppercase', letterSpacing: 0.5, display: 'block', mb: 0.75 }}>\n Scope to Provider\n </Typography>\n <Box sx={{ display: 'flex', gap: 0.75, flexWrap: 'wrap' }}>\n <Chip\n label=\"All providers\"\n size=\"small\"\n clickable\n onClick={() => setSelectedProvider('')}\n sx={{\n fontWeight: 600,\n fontSize: '0.75rem',\n borderRadius: 2,\n border: '1.5px solid',\n borderColor: !selectedProvider ? 'text.primary' : 'divider',\n backgroundColor: !selectedProvider ? 'text.primary' : 'transparent',\n color: !selectedProvider ? 'background.paper' : 'text.secondary',\n transition: 'all 0.15s ease',\n }}\n />\n {providers.map(p => {\n const isSelected = selectedProvider === p.id;\n const label = providerLabel(p.target);\n return (\n <Chip\n key={p.id}\n icon={<StorageIcon sx={{ fontSize: '0.8rem !important', color: isSelected ? 'background.paper' : 'inherit' }} />}\n label={label}\n size=\"small\"\n clickable\n onClick={() => setSelectedProvider(isSelected ? '' : p.id)}\n sx={{\n fontWeight: 600,\n fontSize: '0.75rem',\n borderRadius: 2,\n border: '1.5px solid',\n borderColor: isSelected ? 'text.primary' : 'divider',\n backgroundColor: isSelected ? 'text.primary' : 'transparent',\n color: isSelected ? 'background.paper' : 'text.secondary',\n transition: 'all 0.15s ease',\n }}\n />\n );\n })}\n </Box>\n </Box>\n )}\n\n {/* Proactive suggestions toggle */}\n <Box sx={{ mb: 2 }}>\n <FormControlLabel\n control={\n <Switch\n size=\"small\"\n checked={proactiveEnabled}\n onChange={e => setProactiveEnabled(e.target.checked)}\n />\n }\n label={\n <Box>\n <Typography variant=\"body2\" fontWeight={600}>Proactive suggestions</Typography>\n <Typography variant=\"caption\" color=\"text.secondary\">\n The AI will automatically suggest relevant assets based on your project context.\n Disable if you prefer to search manually.\n </Typography>\n </Box>\n }\n sx={{ alignItems: 'flex-start', ml: 0, gap: 1 }}\n />\n </Box>\n\n {/* MCP URL */}\n <Typography variant=\"caption\" fontWeight={600} color=\"text.secondary\" sx={{ textTransform: 'uppercase', letterSpacing: 0.5 }}>\n MCP Endpoint\n </Typography>\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1,\n mt: 0.5,\n mb: 2,\n px: 1.5,\n py: 1,\n borderRadius: 1.5,\n border: '1px solid',\n borderColor: 'divider',\n backgroundColor: theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.03)',\n }}\n >\n <Typography\n variant=\"body2\"\n sx={{ flex: 1, fontFamily: 'monospace', fontSize: '0.8rem', wordBreak: 'break-all' }}\n >\n {mcpUrl}\n </Typography>\n <Tooltip title={copiedUrl ? 'Copied!' : 'Copy URL'}>\n <IconButton size=\"small\" onClick={() => copyUrl(mcpUrl)}>\n {copiedUrl ? <CheckIcon fontSize=\"small\" color=\"success\" /> : <ContentCopyIcon fontSize=\"small\" />}\n </IconButton>\n </Tooltip>\n </Box>\n\n\n {/* Manual config snippet — collapsed by default */}\n <Box\n onClick={() => setManualExpanded(v => !v)}\n sx={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n cursor: 'pointer',\n userSelect: 'none',\n py: 0.75,\n borderTop: '1px solid',\n borderColor: 'divider',\n }}\n >\n <Typography variant=\"caption\" fontWeight={600} color=\"text.secondary\" sx={{ textTransform: 'uppercase', letterSpacing: 0.5 }}>\n Manual config — {cfg.file}\n </Typography>\n <ExpandMoreIcon\n fontSize=\"small\"\n sx={{\n color: 'text.disabled',\n transition: 'transform 0.2s ease',\n transform: manualExpanded ? 'rotate(180deg)' : 'rotate(0deg)',\n }}\n />\n </Box>\n\n <Collapse in={manualExpanded}>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ display: 'block', mb: 1, mt: 0.5 }}>\n {cfg.description}\n </Typography>\n <Box sx={{ position: 'relative' }}>\n <Box\n component=\"pre\"\n sx={{\n m: 0,\n p: 2,\n borderRadius: 2,\n border: '1px solid',\n borderColor: 'divider',\n backgroundColor: theme.palette.mode === 'dark' ? '#0d1117' : '#f6f8fa',\n color: theme.palette.mode === 'dark' ? '#e6edf3' : '#24292f',\n fontFamily: 'monospace',\n fontSize: '0.8rem',\n overflowX: 'auto',\n whiteSpace: 'pre',\n }}\n >\n {configSnippet}\n </Box>\n <Tooltip title={copiedSnippet ? 'Copied!' : 'Copy config'}>\n <IconButton\n size=\"small\"\n onClick={e => { e.stopPropagation(); copySnippet(configSnippet); }}\n sx={{\n position: 'absolute',\n top: 8,\n right: 8,\n backgroundColor: theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.06)',\n '&:hover': {\n backgroundColor: theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.2)' : 'rgba(0,0,0,0.12)',\n },\n }}\n >\n {copiedSnippet ? <CheckIcon fontSize=\"small\" color=\"success\" /> : <ContentCopyIcon fontSize=\"small\" />}\n </IconButton>\n </Tooltip>\n </Box>\n\n <Typography variant=\"caption\" color=\"text.disabled\" sx={{ display: 'block', mt: 1.5 }}>\n 💡 Omit <code>?tool=</code> from the URL to receive assets for all AI tools.\n {showProviderFilter && ' Omit ?provider= to receive assets from all repositories.'}\n {' '}Proactive suggestions add <code>?proactive=true</code> and register the{' '}\n <code>suggest_assets</code> tool and <code>check_for_assets</code> prompt.\n </Typography>\n </Collapse>\n </DialogContent>\n\n <DialogActions>\n <Button onClick={onClose}>Close</Button>\n </DialogActions>\n </Dialog>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"McpConfigDialog.esm.js","sources":["../../../src/components/McpConfigDialog/McpConfigDialog.tsx"],"sourcesContent":["import { useEffect, useMemo, useState } from 'react';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport Chip from '@mui/material/Chip';\nimport Collapse from '@mui/material/Collapse';\nimport Dialog from '@mui/material/Dialog';\nimport Grid from '@mui/material/Grid';\nimport DialogActions from '@mui/material/DialogActions';\nimport DialogContent from '@mui/material/DialogContent';\nimport DialogTitle from '@mui/material/DialogTitle';\nimport Divider from '@mui/material/Divider';\nimport FormControlLabel from '@mui/material/FormControlLabel';\nimport IconButton from '@mui/material/IconButton';\nimport Switch from '@mui/material/Switch';\nimport Tab from '@mui/material/Tab';\nimport Tabs from '@mui/material/Tabs';\nimport Tooltip from '@mui/material/Tooltip';\nimport Typography from '@mui/material/Typography';\nimport { useTheme } from '@mui/material/styles';\nimport ContentCopyIcon from '@mui/icons-material/ContentCopy';\nimport CheckIcon from '@mui/icons-material/Check';\nimport ExpandMoreIcon from '@mui/icons-material/ExpandMore';\nimport StorageIcon from '@mui/icons-material/Storage';\nimport OpenInBrowserIcon from '@mui/icons-material/OpenInBrowser';\nimport AppsIcon from '@mui/icons-material/Apps';\nimport TuneIcon from '@mui/icons-material/Tune';\nimport { useApi, discoveryApiRef } from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { ToolIcon } from '../ToolIcon';\nimport { useCopyToClipboard, useMcpCatalog, useProviders } from '../../hooks';\nimport type { AiTool, McpCatalogEntry } from '@julianpedro/plugin-dev-ai-hub-common';\nimport { devAiHubTranslationRef } from '../../translation';\n\ninterface ToolConfig {\n tool: AiTool;\n label: string;\n file: string;\n description: string;\n buildConfig: (mcpUrl: string) => string;\n}\n\nconst TYPE_ACCENT: Record<string, string> = {\n http: '#2563EB',\n stdio: '#059669',\n};\n\nfunction providerLabel(target: string): string {\n return target.split('/').pop()?.replace(/\\.git$/, '') ?? target;\n}\n\n// ─── MCP Catalog entry card ───────────────────────────────────────────────────\n\ninterface CatalogEntryCardProps {\n entry: McpCatalogEntry;\n}\n\nfunction CatalogEntryCard({ entry }: CatalogEntryCardProps) {\n const { t } = useTranslationRef(devAiHubTranslationRef);\n const accent = TYPE_ACCENT[entry.type] ?? '#64748b';\n\n const handleInstallVscode = () => {\n const config: Record<string, unknown> = { name: entry.id, type: entry.type };\n if (entry.type === 'http') config.url = entry.url;\n if (entry.type === 'stdio') {\n config.command = entry.command;\n if (entry.args?.length) config.args = entry.args;\n if (entry.env && Object.keys(entry.env).length) config.env = entry.env;\n }\n window.location.href = `vscode:mcp/install?${encodeURIComponent(JSON.stringify(config))}`;\n };\n\n const handleInstallCursor = () => {\n const config: Record<string, unknown> = { type: entry.type };\n if (entry.type === 'http') config.url = entry.url;\n if (entry.type === 'stdio') {\n config.command = entry.command;\n if (entry.args?.length) config.args = entry.args;\n if (entry.env && Object.keys(entry.env).length) config.env = entry.env;\n }\n window.location.href = `cursor://anysphere.cursor-deeplink/mcp/install?name=${encodeURIComponent(entry.name)}&config=${btoa(JSON.stringify(config))}`;\n };\n\n const canInstall =\n (entry.type === 'http' && !!entry.url) ||\n (entry.type === 'stdio' && !!entry.command);\n\n return (\n <Box\n sx={{\n border: '1px solid',\n borderColor: 'divider',\n borderLeft: `3px solid ${accent}`,\n borderRadius: 2,\n p: 2,\n display: 'flex',\n flexDirection: 'column',\n gap: 1.25,\n height: '100%',\n minHeight: 148,\n transition: 'all 0.15s ease',\n '&:hover': {\n boxShadow: `0 4px 16px ${accent}25`,\n borderColor: `${accent}60`,\n },\n }}\n >\n <Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 1.25 }}>\n <Box\n sx={{\n width: 48,\n height: 48,\n borderRadius: 2,\n backgroundColor: `${accent}18`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n boxShadow: `0 2px 8px ${accent}20`,\n }}\n >\n {entry.icon ? (\n <Box\n component=\"img\"\n src={entry.icon}\n alt={entry.name}\n sx={{ width: 32, height: 32, objectFit: 'contain' }}\n onError={e => { (e.target as HTMLImageElement).style.display = 'none'; }}\n />\n ) : (\n <StorageIcon sx={{ fontSize: '1.4rem', color: accent }} />\n )}\n </Box>\n\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75, mb: 0.25, flexWrap: 'wrap' }}>\n <Typography variant=\"subtitle2\" fontWeight={700} noWrap title={entry.name} sx={{ flex: 1 }}>\n {entry.name}\n </Typography>\n <Chip\n label={entry.type}\n size=\"small\"\n sx={{\n height: 18,\n fontSize: '0.6rem',\n fontFamily: 'monospace',\n fontWeight: 700,\n bgcolor: `${accent}18`,\n color: accent,\n border: '1px solid',\n borderColor: `${accent}40`,\n }}\n />\n </Box>\n {entry.description && (\n <Typography variant=\"caption\" color=\"text.secondary\" title={entry.description} sx={{ display: 'block', lineHeight: 1.4 }}>\n {entry.description}\n </Typography>\n )}\n {entry.type === 'http' && entry.url && (\n <Typography\n variant=\"caption\"\n sx={{ display: 'block', fontFamily: 'monospace', fontSize: '0.68rem', color: 'text.disabled', mt: 0.25, wordBreak: 'break-all' }}\n >\n {entry.url}\n </Typography>\n )}\n {entry.type === 'stdio' && entry.command && (\n <Typography\n variant=\"caption\"\n sx={{ display: 'block', fontFamily: 'monospace', fontSize: '0.68rem', color: 'text.disabled', mt: 0.25 }}\n >\n {[entry.command, ...(entry.args ?? [])].join(' ')}\n </Typography>\n )}\n </Box>\n </Box>\n\n {canInstall && (\n <Divider sx={{ mt: 'auto' }} />\n )}\n {canInstall && (\n <Box sx={{ display: 'flex', gap: 0.75 }}>\n <Button\n size=\"small\"\n variant=\"outlined\"\n startIcon={<OpenInBrowserIcon sx={{ fontSize: '0.85rem !important' }} />}\n onClick={handleInstallVscode}\n fullWidth\n sx={{\n fontSize: '0.75rem',\n fontWeight: 700,\n py: 0.5,\n borderColor: `${accent}50`,\n color: accent,\n '&:hover': { borderColor: accent, bgcolor: `${accent}0a` },\n }}\n >\n {t('mcpConfigDialog.installInVscode')}\n </Button>\n <Button\n size=\"small\"\n variant=\"outlined\"\n startIcon={<ToolIcon tool=\"cursor\" branded={false} sx={{ fontSize: '0.85rem !important', color: `${accent} !important` }} />}\n onClick={handleInstallCursor}\n fullWidth\n sx={{\n fontSize: '0.75rem',\n fontWeight: 700,\n py: 0.5,\n borderColor: `${accent}50`,\n color: accent,\n '&:hover': { borderColor: accent, bgcolor: `${accent}0a` },\n }}\n >\n {t('mcpConfigDialog.installInCursor')}\n </Button>\n </Box>\n )}\n </Box>\n );\n}\n\n// ─── Main dialog ──────────────────────────────────────────────────────────────\n\ninterface McpConfigDialogProps {\n open: boolean;\n onClose: () => void;\n}\n\nexport function McpConfigDialog({ open, onClose }: McpConfigDialogProps) {\n const theme = useTheme();\n const { t } = useTranslationRef(devAiHubTranslationRef);\n const discoveryApi = useApi(discoveryApiRef);\n const { copy: copyUrl, copied: copiedUrl } = useCopyToClipboard();\n const { copy: copySnippet, copied: copiedSnippet } = useCopyToClipboard();\n const [tab, setTab] = useState(0);\n const [baseUrl, setBaseUrl] = useState('');\n const [selectedProvider, setSelectedProvider] = useState<string>('');\n const [proactiveEnabled, setProactiveEnabled] = useState(false);\n const [toolConfigExpanded, setToolConfigExpanded] = useState(false);\n const [manualExpanded, setManualExpanded] = useState(false);\n\n const { providers } = useProviders();\n const { catalog } = useMcpCatalog();\n const showProviderFilter = providers.length > 1;\n\n const toolConfigs = useMemo<ToolConfig[]>(() => [\n {\n tool: 'claude-code',\n label: 'Claude Code',\n file: '.mcp.json',\n description: t('mcpConfigDialog.claudeConfigDesc'),\n buildConfig: url => JSON.stringify({\n mcpServers: { 'dev-ai-hub': { type: 'http', url } },\n }, null, 2),\n },\n {\n tool: 'github-copilot',\n label: 'GitHub Copilot',\n file: '.vscode/settings.json',\n description: t('mcpConfigDialog.copilotConfigDesc'),\n buildConfig: url => JSON.stringify({\n 'github.copilot.chat.mcp.servers': { 'dev-ai-hub': { type: 'http', url } },\n }, null, 2),\n },\n {\n tool: 'google-gemini',\n label: 'Google Gemini',\n file: 'gemini-config.json',\n description: t('mcpConfigDialog.geminiConfigDesc'),\n buildConfig: url => JSON.stringify({\n mcpServers: { 'dev-ai-hub': { url } },\n }, null, 2),\n },\n {\n tool: 'cursor',\n label: 'Cursor',\n file: '.cursor/mcp.json',\n description: t('mcpConfigDialog.cursorConfigDesc'),\n buildConfig: url => JSON.stringify({\n mcpServers: { 'dev-ai-hub': { type: 'http', url } },\n }, null, 2),\n },\n ], [t]);\n\n useEffect(() => {\n if (open) {\n discoveryApi.getBaseUrl('dev-ai-hub').then(url => setBaseUrl(url));\n }\n }, [open, discoveryApi]);\n\n const cfg = toolConfigs[tab] ?? toolConfigs[0];\n\n const buildMcpUrl = () => {\n if (!baseUrl) return 'loading...';\n const params = new URLSearchParams();\n params.set('tool', cfg.tool);\n if (selectedProvider) params.set('provider', selectedProvider);\n if (proactiveEnabled) params.set('proactive', 'true');\n return `${baseUrl}/mcp?${params.toString()}`;\n };\n\n const mcpUrl = buildMcpUrl();\n const configSnippet = baseUrl ? cfg.buildConfig(mcpUrl) : '';\n\n const handleInstallInVscode = () => {\n if (!baseUrl) return;\n const config = JSON.stringify({ name: 'dev-ai-hub', type: 'http', url: mcpUrl });\n window.location.href = `vscode:mcp/install?${encodeURIComponent(config)}`;\n };\n\n const handleInstallInCursor = () => {\n if (!baseUrl) return;\n const config = btoa(JSON.stringify({ type: 'http', url: mcpUrl }));\n window.location.href = `cursor://anysphere.cursor-deeplink/mcp/install?name=dev-ai-hub&config=${config}`;\n };\n\n const showVscodeButton = cfg.tool === 'github-copilot';\n const showCursorButton = cfg.tool === 'cursor';\n\n return (\n <Dialog open={open} onClose={onClose} maxWidth=\"md\" fullWidth>\n <DialogTitle sx={{ pb: 1 }}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5 }}>\n <Box\n sx={{\n width: 36, height: 36, borderRadius: 1.5,\n background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)',\n display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,\n boxShadow: '0 2px 8px #6366f140',\n }}\n >\n <AppsIcon sx={{ color: '#fff', fontSize: '1.2rem' }} />\n </Box>\n <Box>\n <Typography variant=\"h6\" fontWeight={700} sx={{ lineHeight: 1.2 }}>\n {t('mcpConfigDialog.title')}\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {t('mcpConfigDialog.subtitle')}\n </Typography>\n </Box>\n </Box>\n </DialogTitle>\n\n <DialogContent sx={{ pt: 0 }}>\n {/* ── Section 1: MCP Catalog ── */}\n <Box sx={{ mb: 2 }}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75, mb: 1, pt: 0.5 }}>\n <AppsIcon sx={{ fontSize: '0.95rem', color: 'text.secondary' }} />\n <Typography\n variant=\"caption\"\n fontWeight={700}\n color=\"text.secondary\"\n sx={{ textTransform: 'uppercase', letterSpacing: 0.8, flex: 1 }}\n >\n {t('mcpConfigDialog.catalogTab')}\n </Typography>\n {catalog.length > 0 && (\n <Chip\n label={catalog.length}\n size=\"small\"\n sx={{ height: 18, fontSize: '0.65rem', fontWeight: 700, bgcolor: 'action.selected', color: 'text.secondary', border: '1px solid', borderColor: 'divider' }}\n />\n )}\n </Box>\n\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ mb: 1.5, fontSize: '0.8rem' }}>\n {t('mcpConfigDialog.catalogDescription')}\n </Typography>\n\n {catalog.length === 0 ? (\n <Box\n sx={{\n border: '1px dashed',\n borderColor: 'divider',\n borderRadius: 2,\n p: 3,\n textAlign: 'center',\n }}\n >\n <AppsIcon sx={{ fontSize: '2rem', color: 'text.disabled', mb: 1 }} />\n <Typography variant=\"body2\" color=\"text.secondary\">\n {t('mcpConfigDialog.catalogEmpty')}\n </Typography>\n <Typography variant=\"caption\" color=\"text.disabled\">\n {t('mcpConfigDialog.catalogAddHint')}\n </Typography>\n </Box>\n ) : (\n <Grid container spacing={1.5}>\n {catalog.map(entry => (\n <Grid item xs={12} sm={6} key={entry.id}>\n <CatalogEntryCard entry={entry} />\n </Grid>\n ))}\n </Grid>\n )}\n </Box>\n\n <Divider sx={{ mb: 0 }} />\n\n {/* ── Section 2: Tool Config (collapsible) ── */}\n <Box>\n <Box\n onClick={() => setToolConfigExpanded(v => !v)}\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 0.75,\n cursor: 'pointer',\n userSelect: 'none',\n py: 1.25,\n '&:hover': { opacity: 0.8 },\n }}\n >\n <TuneIcon sx={{ fontSize: '0.95rem', color: 'text.secondary' }} />\n <Typography\n variant=\"caption\"\n fontWeight={700}\n color=\"text.secondary\"\n sx={{ textTransform: 'uppercase', letterSpacing: 0.8, flex: 1 }}\n >\n {t('mcpConfigDialog.toolConfigSection')}\n </Typography>\n <ExpandMoreIcon\n fontSize=\"small\"\n sx={{\n color: 'text.disabled',\n transition: 'transform 0.2s ease',\n transform: toolConfigExpanded ? 'rotate(180deg)' : 'rotate(0deg)',\n }}\n />\n </Box>\n\n <Collapse in={toolConfigExpanded}>\n {/* Tool tabs */}\n <Tabs\n value={tab}\n onChange={(_, v) => setTab(v)}\n sx={{ mb: 2, borderBottom: 1, borderColor: 'divider' }}\n >\n {toolConfigs.map((toolCfg, i) => (\n <Tab\n key={toolCfg.tool}\n value={i}\n sx={{\n color: 'text.secondary',\n minHeight: 40,\n '&.Mui-selected': { color: 'primary.main' },\n '&:hover': {\n backgroundColor: 'transparent',\n color: 'text.primary',\n },\n '&.Mui-selected:hover': {\n backgroundColor: 'transparent',\n },\n }}\n label={\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75 }}>\n <ToolIcon tool={toolCfg.tool} branded={false} sx={{ fontSize: '1rem' }} />\n <span>{toolCfg.label}</span>\n </Box>\n }\n />\n ))}\n </Tabs>\n\n {/* Provider filter — only shown when there are 2+ providers */}\n {showProviderFilter && (\n <Box sx={{ mb: 2 }}>\n <Typography variant=\"caption\" fontWeight={600} color=\"text.secondary\" sx={{ textTransform: 'uppercase', letterSpacing: 0.5, display: 'block', mb: 0.75 }}>\n {t('mcpConfigDialog.scopeToProvider')}\n </Typography>\n <Box sx={{ display: 'flex', gap: 0.75, flexWrap: 'wrap' }}>\n <Chip\n label={t('mcpConfigDialog.allProviders')}\n size=\"small\"\n clickable\n onClick={() => setSelectedProvider('')}\n sx={{\n fontWeight: 600,\n fontSize: '0.75rem',\n borderRadius: 2,\n border: '1.5px solid',\n borderColor: !selectedProvider ? 'text.primary' : 'divider',\n backgroundColor: !selectedProvider ? 'text.primary' : 'transparent',\n color: !selectedProvider ? 'background.paper' : 'text.secondary',\n transition: 'all 0.15s ease',\n }}\n />\n {providers.map(p => {\n const isSelected = selectedProvider === p.id;\n const label = providerLabel(p.target);\n return (\n <Chip\n key={p.id}\n icon={<StorageIcon sx={{ fontSize: '0.8rem !important', color: isSelected ? 'background.paper' : 'inherit' }} />}\n label={label}\n size=\"small\"\n clickable\n onClick={() => setSelectedProvider(isSelected ? '' : p.id)}\n sx={{\n fontWeight: 600,\n fontSize: '0.75rem',\n borderRadius: 2,\n border: '1.5px solid',\n borderColor: isSelected ? 'text.primary' : 'divider',\n backgroundColor: isSelected ? 'text.primary' : 'transparent',\n color: isSelected ? 'background.paper' : 'text.secondary',\n transition: 'all 0.15s ease',\n }}\n />\n );\n })}\n </Box>\n </Box>\n )}\n\n {/* Proactive suggestions toggle */}\n <Box sx={{ mb: 2 }}>\n <FormControlLabel\n control={\n <Switch\n size=\"small\"\n checked={proactiveEnabled}\n onChange={e => setProactiveEnabled(e.target.checked)}\n />\n }\n label={\n <Box>\n <Typography variant=\"body2\" fontWeight={600}>{t('mcpConfigDialog.proactiveSuggestions')}</Typography>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {t('mcpConfigDialog.proactiveDescription')}\n </Typography>\n </Box>\n }\n sx={{ alignItems: 'flex-start', ml: 0, gap: 1 }}\n />\n </Box>\n\n {/* MCP URL */}\n <Typography variant=\"caption\" fontWeight={600} color=\"text.secondary\" sx={{ textTransform: 'uppercase', letterSpacing: 0.5 }}>\n {t('mcpConfigDialog.mcpEndpoint')}\n </Typography>\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1,\n mt: 0.5,\n mb: (showVscodeButton || showCursorButton) ? 1.5 : 1.5,\n px: 1.5,\n py: 1,\n borderRadius: 1.5,\n border: '1px solid',\n borderColor: 'divider',\n backgroundColor: theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.03)',\n }}\n >\n <Typography\n variant=\"body2\"\n sx={{ flex: 1, fontFamily: 'monospace', fontSize: '0.8rem', wordBreak: 'break-all' }}\n >\n {mcpUrl}\n </Typography>\n <Tooltip title={copiedUrl ? t('assetInstallDialog.copied') : t('mcpConfigDialog.copyUrl')}>\n <IconButton size=\"small\" onClick={() => copyUrl(mcpUrl)}>\n {copiedUrl ? <CheckIcon fontSize=\"small\" color=\"success\" /> : <ContentCopyIcon fontSize=\"small\" />}\n </IconButton>\n </Tooltip>\n </Box>\n\n {showVscodeButton && (\n <Button\n variant=\"contained\"\n startIcon={<OpenInBrowserIcon />}\n onClick={handleInstallInVscode}\n disabled={!baseUrl}\n fullWidth\n sx={{ mb: 2, fontSize: '0.8rem' }}\n >\n {t('mcpConfigDialog.installInVscode')}\n </Button>\n )}\n\n {showCursorButton && (\n <Button\n variant=\"contained\"\n startIcon={<ToolIcon tool=\"cursor\" branded={false} sx={{ fontSize: '1rem !important' }} />}\n onClick={handleInstallInCursor}\n disabled={!baseUrl}\n fullWidth\n sx={{ mb: 2, fontSize: '0.8rem' }}\n >\n {t('mcpConfigDialog.installInCursor')}\n </Button>\n )}\n\n <Divider sx={{ mb: 1.5 }} />\n\n {/* Manual config snippet — collapsed by default */}\n <Box\n onClick={() => setManualExpanded(v => !v)}\n sx={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n cursor: 'pointer',\n userSelect: 'none',\n py: 0.75,\n }}\n >\n <Typography variant=\"caption\" fontWeight={600} color=\"text.secondary\" sx={{ textTransform: 'uppercase', letterSpacing: 0.5 }}>\n {t('mcpConfigDialog.manualConfig', { file: cfg.file })}\n </Typography>\n <ExpandMoreIcon\n fontSize=\"small\"\n sx={{\n color: 'text.disabled',\n transition: 'transform 0.2s ease',\n transform: manualExpanded ? 'rotate(180deg)' : 'rotate(0deg)',\n }}\n />\n </Box>\n\n <Collapse in={manualExpanded}>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ display: 'block', mb: 1, mt: 0.5 }}>\n {cfg.description}\n </Typography>\n <Box sx={{ position: 'relative' }}>\n <Box\n component=\"pre\"\n sx={{\n m: 0,\n p: 2,\n borderRadius: 2,\n border: '1px solid',\n borderColor: 'divider',\n backgroundColor: theme.palette.mode === 'dark' ? '#0d1117' : '#f6f8fa',\n color: theme.palette.mode === 'dark' ? '#e6edf3' : '#24292f',\n fontFamily: 'monospace',\n fontSize: '0.8rem',\n overflowX: 'auto',\n whiteSpace: 'pre',\n }}\n >\n {configSnippet}\n </Box>\n <Tooltip title={copiedSnippet ? t('assetInstallDialog.copied') : t('mcpConfigDialog.copyUrl')}>\n <IconButton\n size=\"small\"\n onClick={e => { e.stopPropagation(); copySnippet(configSnippet); }}\n sx={{\n position: 'absolute',\n top: 8,\n right: 8,\n backgroundColor: theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.06)',\n '&:hover': {\n backgroundColor: theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.2)' : 'rgba(0,0,0,0.12)',\n },\n }}\n >\n {copiedSnippet ? <CheckIcon fontSize=\"small\" color=\"success\" /> : <ContentCopyIcon fontSize=\"small\" />}\n </IconButton>\n </Tooltip>\n </Box>\n\n <Typography variant=\"caption\" color=\"text.disabled\" sx={{ display: 'block', mt: 1.5 }}>\n {t('mcpConfigDialog.omitToolHint')}\n </Typography>\n </Collapse>\n </Collapse>\n </Box>\n </DialogContent>\n\n <DialogActions>\n <Button onClick={onClose}>{t('mcpConfigDialog.close')}</Button>\n </DialogActions>\n </Dialog>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -3,6 +3,8 @@ import SvgIcon from '@mui/material/SvgIcon';
3
3
  import AllInclusiveIcon from '@mui/icons-material/AllInclusive';
4
4
  import NearMeIcon from '@mui/icons-material/NearMe';
5
5
  import { siGooglegemini, siGithub, siAnthropic } from 'simple-icons';
6
+ import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
7
+ import { devAiHubTranslationRef } from '../../translation.esm.js';
6
8
 
7
9
  const TOOL_ICON = {
8
10
  "claude-code": { ...siAnthropic, label: "Claude Code" },
@@ -10,8 +12,9 @@ const TOOL_ICON = {
10
12
  "google-gemini": { ...siGooglegemini, label: "Google Gemini" }
11
13
  };
12
14
  function ToolIcon({ tool, branded = true, sx, ...props }) {
15
+ const { t } = useTranslationRef(devAiHubTranslationRef);
13
16
  if (tool === "all") {
14
- return /* @__PURE__ */ jsx(AllInclusiveIcon, { ...props, sx: { color: "text.secondary", ...sx }, titleAccess: "Universal" });
17
+ return /* @__PURE__ */ jsx(AllInclusiveIcon, { ...props, sx: { color: "text.secondary", ...sx }, titleAccess: t("toolIcon.universal") });
15
18
  }
16
19
  if (tool === "cursor") {
17
20
  return /* @__PURE__ */ jsx(
@@ -1 +1 @@
1
- {"version":3,"file":"ToolIcon.esm.js","sources":["../../../src/components/ToolIcon/ToolIcon.tsx"],"sourcesContent":["import SvgIcon, { SvgIconProps } from '@mui/material/SvgIcon';\nimport AllInclusiveIcon from '@mui/icons-material/AllInclusive';\nimport NearMeIcon from '@mui/icons-material/NearMe';\nimport { siAnthropic, siGithub, siGooglegemini } from 'simple-icons';\nimport type { AiTool } from '@julianpedro/plugin-dev-ai-hub-common';\n\ntype SvgTool = Exclude<AiTool, 'all' | 'cursor'>;\n\nconst TOOL_ICON: Record<SvgTool, { path: string; hex: string; label: string }> = {\n 'claude-code': { ...siAnthropic, label: 'Claude Code' },\n 'github-copilot': { ...siGithub, label: 'GitHub Copilot' },\n 'google-gemini': { ...siGooglegemini, label: 'Google Gemini' },\n};\n\ninterface ToolIconProps extends Omit<SvgIconProps, 'color'> {\n tool: AiTool;\n /** Use the brand's official color. Defaults to true. */\n branded?: boolean;\n}\n\nexport function ToolIcon({ tool, branded = true, sx, ...props }: ToolIconProps) {\n if (tool === 'all') {\n return <AllInclusiveIcon {...props} sx={{ color: 'text.secondary', ...sx }} titleAccess=\"Universal\" />;\n }\n\n if (tool === 'cursor') {\n return (\n <NearMeIcon\n {...props}\n sx={{ color: branded ? 'text.primary' : 'inherit', ...sx }}\n titleAccess=\"Cursor\"\n />\n );\n }\n\n const cfg = TOOL_ICON[tool as SvgTool];\n if (!cfg) return null;\n\n return (\n <SvgIcon\n {...props}\n sx={{ color: branded ? `#${cfg.hex}` : 'inherit', ...sx }}\n titleAccess={cfg.label}\n viewBox=\"0 0 24 24\"\n >\n <path d={cfg.path} />\n </SvgIcon>\n );\n}\n"],"names":[],"mappings":";;;;;;AAQA,MAAM,SAAA,GAA2E;AAAA,EAC/E,aAAA,EAAkB,EAAE,GAAG,WAAA,EAAgB,OAAO,aAAA,EAAc;AAAA,EAC5D,gBAAA,EAAkB,EAAE,GAAG,QAAA,EAAgB,OAAO,gBAAA,EAAiB;AAAA,EAC/D,eAAA,EAAkB,EAAE,GAAG,cAAA,EAAgB,OAAO,eAAA;AAChD,CAAA;AAQO,SAAS,QAAA,CAAS,EAAE,IAAA,EAAM,OAAA,GAAU,MAAM,EAAA,EAAI,GAAG,OAAM,EAAkB;AAC9E,EAAA,IAAI,SAAS,KAAA,EAAO;AAClB,IAAA,uBAAO,GAAA,CAAC,gBAAA,EAAA,EAAkB,GAAG,KAAA,EAAO,EAAA,EAAI,EAAE,KAAA,EAAO,gBAAA,EAAkB,GAAG,EAAA,EAAG,EAAG,WAAA,EAAY,WAAA,EAAY,CAAA;AAAA,EACtG;AAEA,EAAA,IAAI,SAAS,QAAA,EAAU;AACrB,IAAA,uBACE,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACE,GAAG,KAAA;AAAA,QACJ,IAAI,EAAE,KAAA,EAAO,UAAU,cAAA,GAAiB,SAAA,EAAW,GAAG,EAAA,EAAG;AAAA,QACzD,WAAA,EAAY;AAAA;AAAA,KACd;AAAA,EAEJ;AAEA,EAAA,MAAM,GAAA,GAAM,UAAU,IAAe,CAAA;AACrC,EAAA,IAAI,CAAC,KAAK,OAAO,IAAA;AAEjB,EAAA,uBACE,GAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACE,GAAG,KAAA;AAAA,MACJ,EAAA,EAAI,EAAE,KAAA,EAAO,OAAA,GAAU,CAAA,CAAA,EAAI,IAAI,GAAG,CAAA,CAAA,GAAK,SAAA,EAAW,GAAG,EAAA,EAAG;AAAA,MACxD,aAAa,GAAA,CAAI,KAAA;AAAA,MACjB,OAAA,EAAQ,WAAA;AAAA,MAER,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAG,GAAA,CAAI,IAAA,EAAM;AAAA;AAAA,GACrB;AAEJ;;;;"}
1
+ {"version":3,"file":"ToolIcon.esm.js","sources":["../../../src/components/ToolIcon/ToolIcon.tsx"],"sourcesContent":["import SvgIcon, { SvgIconProps } from '@mui/material/SvgIcon';\nimport AllInclusiveIcon from '@mui/icons-material/AllInclusive';\nimport NearMeIcon from '@mui/icons-material/NearMe';\nimport { siAnthropic, siGithub, siGooglegemini } from 'simple-icons';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport type { AiTool } from '@julianpedro/plugin-dev-ai-hub-common';\nimport { devAiHubTranslationRef } from '../../translation';\n\ntype SvgTool = Exclude<AiTool, 'all' | 'cursor'>;\n\nconst TOOL_ICON: Record<SvgTool, { path: string; hex: string; label: string }> = {\n 'claude-code': { ...siAnthropic, label: 'Claude Code' },\n 'github-copilot': { ...siGithub, label: 'GitHub Copilot' },\n 'google-gemini': { ...siGooglegemini, label: 'Google Gemini' },\n};\n\ninterface ToolIconProps extends Omit<SvgIconProps, 'color'> {\n tool: AiTool;\n /** Use the brand's official color. Defaults to true. */\n branded?: boolean;\n}\n\nexport function ToolIcon({ tool, branded = true, sx, ...props }: ToolIconProps) {\n const { t } = useTranslationRef(devAiHubTranslationRef);\n\n if (tool === 'all') {\n return <AllInclusiveIcon {...props} sx={{ color: 'text.secondary', ...sx }} titleAccess={t('toolIcon.universal')} />;\n }\n\n if (tool === 'cursor') {\n return (\n <NearMeIcon\n {...props}\n sx={{ color: branded ? 'text.primary' : 'inherit', ...sx }}\n titleAccess=\"Cursor\"\n />\n );\n }\n\n const cfg = TOOL_ICON[tool as SvgTool];\n if (!cfg) return null;\n\n return (\n <SvgIcon\n {...props}\n sx={{ color: branded ? `#${cfg.hex}` : 'inherit', ...sx }}\n titleAccess={cfg.label}\n viewBox=\"0 0 24 24\"\n >\n <path d={cfg.path} />\n </SvgIcon>\n );\n}\n"],"names":[],"mappings":";;;;;;;;AAUA,MAAM,SAAA,GAA2E;AAAA,EAC/E,aAAA,EAAkB,EAAE,GAAG,WAAA,EAAgB,OAAO,aAAA,EAAc;AAAA,EAC5D,gBAAA,EAAkB,EAAE,GAAG,QAAA,EAAgB,OAAO,gBAAA,EAAiB;AAAA,EAC/D,eAAA,EAAkB,EAAE,GAAG,cAAA,EAAgB,OAAO,eAAA;AAChD,CAAA;AAQO,SAAS,QAAA,CAAS,EAAE,IAAA,EAAM,OAAA,GAAU,MAAM,EAAA,EAAI,GAAG,OAAM,EAAkB;AAC9E,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,sBAAsB,CAAA;AAEtD,EAAA,IAAI,SAAS,KAAA,EAAO;AAClB,IAAA,uBAAO,GAAA,CAAC,gBAAA,EAAA,EAAkB,GAAG,KAAA,EAAO,IAAI,EAAE,KAAA,EAAO,gBAAA,EAAkB,GAAG,EAAA,EAAG,EAAG,WAAA,EAAa,CAAA,CAAE,oBAAoB,CAAA,EAAG,CAAA;AAAA,EACpH;AAEA,EAAA,IAAI,SAAS,QAAA,EAAU;AACrB,IAAA,uBACE,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACE,GAAG,KAAA;AAAA,QACJ,IAAI,EAAE,KAAA,EAAO,UAAU,cAAA,GAAiB,SAAA,EAAW,GAAG,EAAA,EAAG;AAAA,QACzD,WAAA,EAAY;AAAA;AAAA,KACd;AAAA,EAEJ;AAEA,EAAA,MAAM,GAAA,GAAM,UAAU,IAAe,CAAA;AACrC,EAAA,IAAI,CAAC,KAAK,OAAO,IAAA;AAEjB,EAAA,uBACE,GAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACE,GAAG,KAAA;AAAA,MACJ,EAAA,EAAI,EAAE,KAAA,EAAO,OAAA,GAAU,CAAA,CAAA,EAAI,IAAI,GAAG,CAAA,CAAA,GAAK,SAAA,EAAW,GAAG,EAAA,EAAG;AAAA,MACxD,aAAa,GAAA,CAAI,KAAA;AAAA,MACjB,OAAA,EAAQ,WAAA;AAAA,MAER,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAG,GAAA,CAAI,IAAA,EAAM;AAAA;AAAA,GACrB;AAEJ;;;;"}
@@ -97,6 +97,20 @@ function useStats() {
97
97
  }, [api]);
98
98
  return { stats, loading, error };
99
99
  }
100
+ function useMcpCatalog() {
101
+ const api = useApi(devAiHubApiRef);
102
+ const [catalog, setCatalog] = useState([]);
103
+ const [loading, setLoading] = useState(false);
104
+ const [error, setError] = useState(null);
105
+ useEffect(() => {
106
+ setLoading(true);
107
+ api.getMcpCatalog().then((data) => {
108
+ setCatalog(data);
109
+ setError(null);
110
+ }).catch((err) => setError(err)).finally(() => setLoading(false));
111
+ }, [api]);
112
+ return { catalog, loading, error };
113
+ }
100
114
  function useCopyToClipboard() {
101
115
  const [copied, setCopied] = useState(false);
102
116
  const timerRef = useRef(null);
@@ -110,5 +124,5 @@ function useCopyToClipboard() {
110
124
  return { copy, copied };
111
125
  }
112
126
 
113
- export { useAssetDetail, useAssets, useCopyToClipboard, useProviders, useStats };
127
+ export { useAssetDetail, useAssets, useCopyToClipboard, useMcpCatalog, useProviders, useStats };
114
128
  //# sourceMappingURL=index.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../../src/hooks/index.ts"],"sourcesContent":["import { useState, useEffect, useCallback, useRef } from 'react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { devAiHubApiRef } from '../api/DevAiHubClient';\nimport type {\n AiAsset,\n AiAssetListResponse,\n AiHubProvider,\n AiHubStats,\n AssetListFilter,\n} from '@julianpedro/plugin-dev-ai-hub-common';\n\nfunction useDebounce<T>(value: T, delay: number): T {\n const [debounced, setDebounced] = useState(value);\n useEffect(() => {\n const timer = setTimeout(() => setDebounced(value), delay);\n return () => clearTimeout(timer);\n }, [value, delay]);\n return debounced;\n}\n\nexport function useAssets(filter: AssetListFilter) {\n const api = useApi(devAiHubApiRef);\n const [result, setResult] = useState<AiAssetListResponse | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const debouncedSearch = useDebounce(filter.search, 300);\n\n const effectiveFilter = { ...filter, search: debouncedSearch };\n const filterKey = JSON.stringify(effectiveFilter);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n api\n .listAssets(effectiveFilter)\n .then(data => {\n if (!cancelled) {\n setResult(data);\n setError(null);\n }\n })\n .catch(err => {\n if (!cancelled) setError(err);\n })\n .finally(() => {\n if (!cancelled) setLoading(false);\n });\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [filterKey, api]);\n\n return { result, loading, error };\n}\n\nexport function useAssetDetail(id: string | null) {\n const api = useApi(devAiHubApiRef);\n const [asset, setAsset] = useState<AiAsset | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n if (!id) {\n setAsset(null);\n return () => {};\n }\n let cancelled = false;\n setLoading(true);\n api\n .getAsset(id)\n .then(data => {\n if (!cancelled) {\n setAsset(data);\n setError(null);\n }\n })\n .catch(err => {\n if (!cancelled) setError(err);\n })\n .finally(() => {\n if (!cancelled) setLoading(false);\n });\n return () => {\n cancelled = true;\n };\n }, [id, api]);\n\n return { asset, loading, error };\n}\n\nexport function useProviders() {\n const api = useApi(devAiHubApiRef);\n const [providers, setProviders] = useState<AiHubProvider[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const load = useCallback(() => {\n setLoading(true);\n api\n .listProviders()\n .then(data => {\n setProviders(data);\n setError(null);\n })\n .catch(err => setError(err))\n .finally(() => setLoading(false));\n }, [api]);\n\n useEffect(() => {\n load();\n }, [load]);\n\n return { providers, loading, error, reload: load };\n}\n\nexport function useStats() {\n const api = useApi(devAiHubApiRef);\n const [stats, setStats] = useState<AiHubStats | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n setLoading(true);\n api\n .getStats()\n .then(data => {\n setStats(data);\n setError(null);\n })\n .catch(err => setError(err))\n .finally(() => setLoading(false));\n }, [api]);\n\n return { stats, loading, error };\n}\n\nexport function useCopyToClipboard() {\n const [copied, setCopied] = useState(false);\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const copy = useCallback((text: string) => {\n navigator.clipboard.writeText(text).then(() => {\n setCopied(true);\n if (timerRef.current) clearTimeout(timerRef.current);\n timerRef.current = setTimeout(() => setCopied(false), 2000);\n });\n }, []);\n\n return { copy, copied };\n}\n"],"names":[],"mappings":";;;;AAWA,SAAS,WAAA,CAAe,OAAU,KAAA,EAAkB;AAClD,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,KAAK,CAAA;AAChD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,YAAA,CAAa,KAAK,GAAG,KAAK,CAAA;AACzD,IAAA,OAAO,MAAM,aAAa,KAAK,CAAA;AAAA,EACjC,CAAA,EAAG,CAAC,KAAA,EAAO,KAAK,CAAC,CAAA;AACjB,EAAA,OAAO,SAAA;AACT;AAEO,SAAS,UAAU,MAAA,EAAyB;AACjD,EAAA,MAAM,GAAA,GAAM,OAAO,cAAc,CAAA;AACjC,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,SAAqC,IAAI,CAAA;AACrE,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAuB,IAAI,CAAA;AAErD,EAAA,MAAM,eAAA,GAAkB,WAAA,CAAY,MAAA,CAAO,MAAA,EAAQ,GAAG,CAAA;AAEtD,EAAA,MAAM,eAAA,GAAkB,EAAE,GAAG,MAAA,EAAQ,QAAQ,eAAA,EAAgB;AAC7D,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,SAAA,CAAU,eAAe,CAAA;AAEhD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,SAAA,GAAY,KAAA;AAChB,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,GAAA,CACG,UAAA,CAAW,eAAe,CAAA,CAC1B,IAAA,CAAK,CAAA,IAAA,KAAQ;AACZ,MAAA,IAAI,CAAC,SAAA,EAAW;AACd,QAAA,SAAA,CAAU,IAAI,CAAA;AACd,QAAA,QAAA,CAAS,IAAI,CAAA;AAAA,MACf;AAAA,IACF,CAAC,CAAA,CACA,KAAA,CAAM,CAAA,GAAA,KAAO;AACZ,MAAA,IAAI,CAAC,SAAA,EAAW,QAAA,CAAS,GAAG,CAAA;AAAA,IAC9B,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM;AACb,MAAA,IAAI,CAAC,SAAA,EAAW,UAAA,CAAW,KAAK,CAAA;AAAA,IAClC,CAAC,CAAA;AACH,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,IAAA;AAAA,IACd,CAAA;AAAA,EAEF,CAAA,EAAG,CAAC,SAAA,EAAW,GAAG,CAAC,CAAA;AAEnB,EAAA,OAAO,EAAE,MAAA,EAAQ,OAAA,EAAS,KAAA,EAAM;AAClC;AAEO,SAAS,eAAe,EAAA,EAAmB;AAChD,EAAA,MAAM,GAAA,GAAM,OAAO,cAAc,CAAA;AACjC,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAyB,IAAI,CAAA;AACvD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAuB,IAAI,CAAA;AAErD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,EAAA,EAAI;AACP,MAAA,QAAA,CAAS,IAAI,CAAA;AACb,MAAA,OAAO,MAAM;AAAA,MAAC,CAAA;AAAA,IAChB;AACA,IAAA,IAAI,SAAA,GAAY,KAAA;AAChB,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,GAAA,CACG,QAAA,CAAS,EAAE,CAAA,CACX,IAAA,CAAK,CAAA,IAAA,KAAQ;AACZ,MAAA,IAAI,CAAC,SAAA,EAAW;AACd,QAAA,QAAA,CAAS,IAAI,CAAA;AACb,QAAA,QAAA,CAAS,IAAI,CAAA;AAAA,MACf;AAAA,IACF,CAAC,CAAA,CACA,KAAA,CAAM,CAAA,GAAA,KAAO;AACZ,MAAA,IAAI,CAAC,SAAA,EAAW,QAAA,CAAS,GAAG,CAAA;AAAA,IAC9B,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM;AACb,MAAA,IAAI,CAAC,SAAA,EAAW,UAAA,CAAW,KAAK,CAAA;AAAA,IAClC,CAAC,CAAA;AACH,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,IAAA;AAAA,IACd,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,EAAA,EAAI,GAAG,CAAC,CAAA;AAEZ,EAAA,OAAO,EAAE,KAAA,EAAO,OAAA,EAAS,KAAA,EAAM;AACjC;AAEO,SAAS,YAAA,GAAe;AAC7B,EAAA,MAAM,GAAA,GAAM,OAAO,cAAc,CAAA;AACjC,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,QAAA,CAA0B,EAAE,CAAA;AAC9D,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAuB,IAAI,CAAA;AAErD,EAAA,MAAM,IAAA,GAAO,YAAY,MAAM;AAC7B,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,GAAA,CACG,aAAA,EAAc,CACd,IAAA,CAAK,CAAA,IAAA,KAAQ;AACZ,MAAA,YAAA,CAAa,IAAI,CAAA;AACjB,MAAA,QAAA,CAAS,IAAI,CAAA;AAAA,IACf,CAAC,CAAA,CACA,KAAA,CAAM,CAAA,GAAA,KAAO,QAAA,CAAS,GAAG,CAAC,CAAA,CAC1B,OAAA,CAAQ,MAAM,UAAA,CAAW,KAAK,CAAC,CAAA;AAAA,EACpC,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAER,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAA,EAAK;AAAA,EACP,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAA,OAAO,EAAE,SAAA,EAAW,OAAA,EAAS,KAAA,EAAO,QAAQ,IAAA,EAAK;AACnD;AAEO,SAAS,QAAA,GAAW;AACzB,EAAA,MAAM,GAAA,GAAM,OAAO,cAAc,CAAA;AACjC,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAA4B,IAAI,CAAA;AAC1D,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAuB,IAAI,CAAA;AAErD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,GAAA,CACG,QAAA,EAAS,CACT,IAAA,CAAK,CAAA,IAAA,KAAQ;AACZ,MAAA,QAAA,CAAS,IAAI,CAAA;AACb,MAAA,QAAA,CAAS,IAAI,CAAA;AAAA,IACf,CAAC,CAAA,CACA,KAAA,CAAM,CAAA,GAAA,KAAO,QAAA,CAAS,GAAG,CAAC,CAAA,CAC1B,OAAA,CAAQ,MAAM,UAAA,CAAW,KAAK,CAAC,CAAA;AAAA,EACpC,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAER,EAAA,OAAO,EAAE,KAAA,EAAO,OAAA,EAAS,KAAA,EAAM;AACjC;AAEO,SAAS,kBAAA,GAAqB;AACnC,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,SAAS,KAAK,CAAA;AAC1C,EAAA,MAAM,QAAA,GAAW,OAA6C,IAAI,CAAA;AAElE,EAAA,MAAM,IAAA,GAAO,WAAA,CAAY,CAAC,IAAA,KAAiB;AACzC,IAAA,SAAA,CAAU,SAAA,CAAU,SAAA,CAAU,IAAI,CAAA,CAAE,KAAK,MAAM;AAC7C,MAAA,SAAA,CAAU,IAAI,CAAA;AACd,MAAA,IAAI,QAAA,CAAS,OAAA,EAAS,YAAA,CAAa,QAAA,CAAS,OAAO,CAAA;AACnD,MAAA,QAAA,CAAS,UAAU,UAAA,CAAW,MAAM,SAAA,CAAU,KAAK,GAAG,GAAI,CAAA;AAAA,IAC5D,CAAC,CAAA;AAAA,EACH,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,OAAO,EAAE,MAAM,MAAA,EAAO;AACxB;;;;"}
1
+ {"version":3,"file":"index.esm.js","sources":["../../src/hooks/index.ts"],"sourcesContent":["import { useState, useEffect, useCallback, useRef } from 'react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { devAiHubApiRef } from '../api/DevAiHubClient';\nimport type {\n AiAsset,\n AiAssetListResponse,\n AiHubProvider,\n AiHubStats,\n AssetListFilter,\n McpCatalogEntry,\n} from '@julianpedro/plugin-dev-ai-hub-common';\n\nfunction useDebounce<T>(value: T, delay: number): T {\n const [debounced, setDebounced] = useState(value);\n useEffect(() => {\n const timer = setTimeout(() => setDebounced(value), delay);\n return () => clearTimeout(timer);\n }, [value, delay]);\n return debounced;\n}\n\nexport function useAssets(filter: AssetListFilter) {\n const api = useApi(devAiHubApiRef);\n const [result, setResult] = useState<AiAssetListResponse | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const debouncedSearch = useDebounce(filter.search, 300);\n\n const effectiveFilter = { ...filter, search: debouncedSearch };\n const filterKey = JSON.stringify(effectiveFilter);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n api\n .listAssets(effectiveFilter)\n .then(data => {\n if (!cancelled) {\n setResult(data);\n setError(null);\n }\n })\n .catch(err => {\n if (!cancelled) setError(err);\n })\n .finally(() => {\n if (!cancelled) setLoading(false);\n });\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [filterKey, api]);\n\n return { result, loading, error };\n}\n\nexport function useAssetDetail(id: string | null) {\n const api = useApi(devAiHubApiRef);\n const [asset, setAsset] = useState<AiAsset | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n if (!id) {\n setAsset(null);\n return () => {};\n }\n let cancelled = false;\n setLoading(true);\n api\n .getAsset(id)\n .then(data => {\n if (!cancelled) {\n setAsset(data);\n setError(null);\n }\n })\n .catch(err => {\n if (!cancelled) setError(err);\n })\n .finally(() => {\n if (!cancelled) setLoading(false);\n });\n return () => {\n cancelled = true;\n };\n }, [id, api]);\n\n return { asset, loading, error };\n}\n\nexport function useProviders() {\n const api = useApi(devAiHubApiRef);\n const [providers, setProviders] = useState<AiHubProvider[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const load = useCallback(() => {\n setLoading(true);\n api\n .listProviders()\n .then(data => {\n setProviders(data);\n setError(null);\n })\n .catch(err => setError(err))\n .finally(() => setLoading(false));\n }, [api]);\n\n useEffect(() => {\n load();\n }, [load]);\n\n return { providers, loading, error, reload: load };\n}\n\nexport function useStats() {\n const api = useApi(devAiHubApiRef);\n const [stats, setStats] = useState<AiHubStats | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n setLoading(true);\n api\n .getStats()\n .then(data => {\n setStats(data);\n setError(null);\n })\n .catch(err => setError(err))\n .finally(() => setLoading(false));\n }, [api]);\n\n return { stats, loading, error };\n}\n\nexport function useMcpCatalog() {\n const api = useApi(devAiHubApiRef);\n const [catalog, setCatalog] = useState<McpCatalogEntry[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n setLoading(true);\n api\n .getMcpCatalog()\n .then(data => {\n setCatalog(data);\n setError(null);\n })\n .catch(err => setError(err))\n .finally(() => setLoading(false));\n }, [api]);\n\n return { catalog, loading, error };\n}\n\nexport function useCopyToClipboard() {\n const [copied, setCopied] = useState(false);\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const copy = useCallback((text: string) => {\n navigator.clipboard.writeText(text).then(() => {\n setCopied(true);\n if (timerRef.current) clearTimeout(timerRef.current);\n timerRef.current = setTimeout(() => setCopied(false), 2000);\n });\n }, []);\n\n return { copy, copied };\n}\n"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { ComponentType } from 'react';
3
3
  import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
4
- import { AssetListFilter, AiAssetListResponse, AiAsset, AiHubProvider, AiHubStats } from '@julianpedro/plugin-dev-ai-hub-common';
4
+ import { AssetListFilter, AiAssetListResponse, AiAsset, AiHubProvider, AiHubStats, McpCatalogEntry } from '@julianpedro/plugin-dev-ai-hub-common';
5
5
 
6
6
  declare const devAiHubPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugin<{
7
7
  root: _backstage_frontend_plugin_api.RouteRef<undefined>;
@@ -89,13 +89,16 @@ interface DevAiHubApi {
89
89
  listAssets(filter?: AssetListFilter): Promise<AiAssetListResponse>;
90
90
  getAsset(id: string): Promise<AiAsset>;
91
91
  getAssetRaw(id: string): Promise<string>;
92
- /** Returns the absolute URL for the download endpoint (zip for skills, md for others). */
93
- getDownloadUrl(id: string): Promise<string>;
92
+ /** Returns the absolute URL for the download endpoint (zip for skills/bundles, md for others). */
93
+ getDownloadUrl(id: string, tool?: string): Promise<string>;
94
+ /** Returns the absolute URL for the .agent.md endpoint used in VSCode deep links. */
95
+ getAgentMdUrl(id: string): Promise<string>;
94
96
  trackInstall(id: string): Promise<void>;
95
97
  listProviders(): Promise<AiHubProvider[]>;
96
98
  getProviderStatus(id: string): Promise<AiHubProvider>;
97
99
  triggerSync(id: string): Promise<void>;
98
100
  getStats(): Promise<AiHubStats>;
101
+ getMcpCatalog(): Promise<McpCatalogEntry[]>;
99
102
  }
100
103
 
101
104
  declare const rootRouteRef: _backstage_frontend_plugin_api.RouteRef<undefined>;
package/dist/index.esm.js CHANGED
@@ -2,4 +2,5 @@ export { devAiHubPlugin } from './plugin.esm.js';
2
2
  export { DevAiHubPage } from './pluginLegacy.esm.js';
3
3
  export { devAiHubApiRef } from './api/DevAiHubClient.esm.js';
4
4
  export { rootRouteRef } from './routes.esm.js';
5
+ export { devAiHubTranslationRef } from './translation.esm.js';
5
6
  //# sourceMappingURL=index.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;"}
1
+ {"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -0,0 +1,112 @@
1
+ var es = {
2
+ "toolIcon.universal": "Universal",
3
+ "assetCard.newBadge": "Nuevo",
4
+ "assetCard.updatedBadge": "Actualizado",
5
+ "assetCard.installTooltip": "Instalar en el editor",
6
+ "assetCard.detailsTooltip": "Ver detalles",
7
+ "assetCard.helpTooltip": "Gu\xEDa de uso",
8
+ "assetCard.mcpsRequired": "MCPs requeridos",
9
+ "assetCard.bundleFooter": "{{count}} assets \xB7 {{author}}",
10
+ "assetCard.versionFooter": "v{{version}} \xB7 {{author}}",
11
+ "assetCard.moreTags": "+{{count}}",
12
+ "assetDetailPanel.loading": "Cargando...",
13
+ "assetDetailPanel.tabPreview": "Vista previa",
14
+ "assetDetailPanel.tabMetadata": "Metadatos",
15
+ "assetDetailPanel.tabRawYaml": "YAML sin formato",
16
+ "assetDetailPanel.bundlePreviewTitle": "Contenido del bundle \u2014 {{count}} assets",
17
+ "assetDetailPanel.bundleItemNotSynced": "No sincronizado \u2014 {{ref}}",
18
+ "assetDetailPanel.metaAuthor": "Autor",
19
+ "assetDetailPanel.metaVersion": "Versi\xF3n",
20
+ "assetDetailPanel.metaProvider": "Proveedor",
21
+ "assetDetailPanel.metaCommit": "Commit",
22
+ "assetDetailPanel.metaLastSynced": "\xDAltima sincronizaci\xF3n",
23
+ "assetDetailPanel.metaBranch": "Rama",
24
+ "assetDetailPanel.compatibleTools": "Herramientas compatibles",
25
+ "assetDetailPanel.tagsLabel": "Etiquetas",
26
+ "assetDetailPanel.bundleContents": "Contenido del bundle ({{count}} assets)",
27
+ "assetDetailPanel.bundleItemNotSyncedYet": "A\xFAn no sincronizado \u2014 {{ref}}",
28
+ "assetDetailPanel.bundledFiles": "Archivos incluidos",
29
+ "assetDetailPanel.zipDescription": "Se descarga como .zip con todos los archivos anteriores.",
30
+ "assetDetailPanel.repository": "Repositorio",
31
+ "assetDetailPanel.copyMarkdown": "Copiar Markdown",
32
+ "assetDetailPanel.openInRepo": "Abrir en el repositorio",
33
+ "assetDetailPanel.copiedMessage": "\xA1Markdown copiado al portapapeles!",
34
+ "assetFilters.searchPlaceholder": "Buscar assets por nombre, descripci\xF3n o contenido\u2026",
35
+ "assetFilters.typeHeader": "Tipo",
36
+ "assetFilters.typeAll": "Todos",
37
+ "assetFilters.aiToolHeader": "Herramienta de IA",
38
+ "assetFilters.allTools": "Todas las herramientas",
39
+ "assetFilters.providerHeader": "Proveedor",
40
+ "assetFilters.tagsHeader": "Etiquetas",
41
+ "assetFilters.tagsShowMore": "+{{count}} m\xE1s",
42
+ "assetFilters.tagsShowLess": "Ver menos",
43
+ "assetInstallDialog.bundledSkillTitle": "Skill con archivos \u2014 se descarga como .zip",
44
+ "assetInstallDialog.bundledSkillDescription": "Esta skill incluye archivos de recursos junto al SKILL.md. Extraiga el zip y coloque todos los archivos en el directorio de la skill.",
45
+ "assetInstallDialog.installPathLabel": "Ruta de instalaci\xF3n",
46
+ "assetInstallDialog.installInVscode": "Instalar en VSCode",
47
+ "assetInstallDialog.copied": "\xA1Copiado!",
48
+ "assetInstallDialog.copyTooltip": "Copiar contenido markdown",
49
+ "assetInstallDialog.copyContent": "Copiar contenido",
50
+ "assetInstallDialog.downloadZipTooltip": "Descargar como .zip con todos los archivos",
51
+ "assetInstallDialog.downloadTooltip": "Descargar archivo con el nombre correcto",
52
+ "assetInstallDialog.downloadZip": "Descargar .zip",
53
+ "assetInstallDialog.download": "Descargar",
54
+ "assetInstallDialog.stepProgress": "Paso {{current}} de {{total}}",
55
+ "assetInstallDialog.notSyncedTitle": "Este asset a\xFAn no ha sido sincronizado.",
56
+ "assetInstallDialog.notSyncedRef": "Ref: {{ref}}",
57
+ "assetInstallDialog.dialogTitleBundle": "Instalar Bundle: {{name}}",
58
+ "assetInstallDialog.dialogSubtitleBundle": "Instale cada asset del bundle paso a paso.",
59
+ "assetInstallDialog.dialogTitle": "Instalar: {{name}}",
60
+ "assetInstallDialog.dialogSubtitle": "Copie el contenido y coloque el archivo en la ruta indicada para su herramienta.",
61
+ "assetInstallDialog.bundleProgress": "{{current}} / {{total}} assets",
62
+ "assetInstallDialog.bundleEmpty": "Este bundle a\xFAn no tiene elementos.",
63
+ "assetInstallDialog.downloadBundle": "Descargar Bundle .zip",
64
+ "assetInstallDialog.back": "Volver",
65
+ "assetInstallDialog.next": "Siguiente",
66
+ "assetInstallDialog.finish": "Finalizar",
67
+ "assetInstallDialog.close": "Cerrar",
68
+ "mcpConfigDialog.title": "Configuraci\xF3n MCP",
69
+ "mcpConfigDialog.subtitle": "Explore el cat\xE1logo de servidores MCP listos para instalar o configure el MCP de Dev AI Hub para su herramienta de IA.",
70
+ "mcpConfigDialog.catalogTab": "Cat\xE1logo MCP",
71
+ "mcpConfigDialog.catalogDescription": "Servidores MCP preconfigurados que puede instalar con un clic en VSCode o Cursor.",
72
+ "mcpConfigDialog.catalogEmpty": "No hay servidores MCP configurados en el cat\xE1logo.",
73
+ "mcpConfigDialog.catalogAddHint": "Agregue un archivo mcp-catalog.yaml en la ra\xEDz de su repositorio de assets para gestionar el cat\xE1logo.",
74
+ "mcpConfigDialog.toolConfigSection": "Configurar MCP de Dev AI Hub",
75
+ "mcpConfigDialog.scopeToProvider": "Filtrar por Proveedor",
76
+ "mcpConfigDialog.allProviders": "Todos los proveedores",
77
+ "mcpConfigDialog.proactiveSuggestions": "Sugerencias proactivas",
78
+ "mcpConfigDialog.proactiveDescription": "La IA sugerir\xE1 autom\xE1ticamente assets relevantes seg\xFAn el contexto de su proyecto. Desact\xEDvelo si prefiere buscar manualmente.",
79
+ "mcpConfigDialog.mcpEndpoint": "Endpoint MCP",
80
+ "mcpConfigDialog.copyUrl": "Copiar URL",
81
+ "mcpConfigDialog.installInVscode": "Instalar en VSCode",
82
+ "mcpConfigDialog.installInCursor": "Instalar en Cursor",
83
+ "mcpConfigDialog.manualConfig": "Config manual \u2014 {{file}}",
84
+ "mcpConfigDialog.claudeConfigDesc": "Agregue a .mcp.json en la ra\xEDz del proyecto (o ejecute via claude mcp add):",
85
+ "mcpConfigDialog.copilotConfigDesc": "Agregue a la configuraci\xF3n de VS Code (.vscode/settings.json o configuraci\xF3n de usuario):",
86
+ "mcpConfigDialog.geminiConfigDesc": "Agregue a su configuraci\xF3n del Gemini CLI:",
87
+ "mcpConfigDialog.cursorConfigDesc": "Agregue a .cursor/mcp.json en la ra\xEDz del proyecto:",
88
+ "mcpConfigDialog.omitToolHint": "Omita ?tool= para recibir todos los assets independientemente de la herramienta.",
89
+ "mcpConfigDialog.close": "Cerrar",
90
+ "devAiHubPage.title": "Dev AI Hub",
91
+ "devAiHubPage.subtitle": "Assets de IA centralizados para su equipo",
92
+ "devAiHubPage.statsInstructions": "{{count}} Instructions",
93
+ "devAiHubPage.statsAgents": "{{count}} Agents",
94
+ "devAiHubPage.statsSkills": "{{count}} Skills",
95
+ "devAiHubPage.statsWorkflows": "{{count}} Workflows",
96
+ "devAiHubPage.lastSync": "\xDAltima sync: {{time}}",
97
+ "devAiHubPage.configMcp": "MCP Servers",
98
+ "devAiHubPage.assetCountOne": "{{count}} asset",
99
+ "devAiHubPage.assetCountOther": "{{count}} assets",
100
+ "devAiHubPage.providerCountOne": "{{count}} proveedor",
101
+ "devAiHubPage.providerCountOther": "{{count}} proveedores",
102
+ "devAiHubPage.totalStats": "{{totalAssets}} assets \xB7 {{providers}}",
103
+ "devAiHubPage.noAssetsTitle": "No se encontraron assets",
104
+ "devAiHubPage.noAssetsSubtitle": "Intente ajustar los filtros o los t\xE9rminos de b\xFAsqueda.",
105
+ "devAiHubPage.timeJustNow": "justo ahora",
106
+ "devAiHubPage.timeMinutesAgo": "hace {{count}}min",
107
+ "devAiHubPage.timeHoursAgo": "hace {{count}}h",
108
+ "devAiHubPage.timeDaysAgo": "hace {{count}}d"
109
+ };
110
+
111
+ export { es as default };
112
+ //# sourceMappingURL=es.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"es.esm.js","sources":["../../src/locales/es.ts"],"sourcesContent":["export default {\n 'toolIcon.universal': 'Universal',\n\n 'assetCard.newBadge': 'Nuevo',\n 'assetCard.updatedBadge': 'Actualizado',\n 'assetCard.installTooltip': 'Instalar en el editor',\n 'assetCard.detailsTooltip': 'Ver detalles',\n 'assetCard.helpTooltip': 'Guía de uso',\n 'assetCard.mcpsRequired': 'MCPs requeridos',\n 'assetCard.bundleFooter': '{{count}} assets · {{author}}',\n 'assetCard.versionFooter': 'v{{version}} · {{author}}',\n 'assetCard.moreTags': '+{{count}}',\n\n 'assetDetailPanel.loading': 'Cargando...',\n 'assetDetailPanel.tabPreview': 'Vista previa',\n 'assetDetailPanel.tabMetadata': 'Metadatos',\n 'assetDetailPanel.tabRawYaml': 'YAML sin formato',\n 'assetDetailPanel.bundlePreviewTitle': 'Contenido del bundle — {{count}} assets',\n 'assetDetailPanel.bundleItemNotSynced': 'No sincronizado — {{ref}}',\n 'assetDetailPanel.metaAuthor': 'Autor',\n 'assetDetailPanel.metaVersion': 'Versión',\n 'assetDetailPanel.metaProvider': 'Proveedor',\n 'assetDetailPanel.metaCommit': 'Commit',\n 'assetDetailPanel.metaLastSynced': 'Última sincronización',\n 'assetDetailPanel.metaBranch': 'Rama',\n 'assetDetailPanel.compatibleTools': 'Herramientas compatibles',\n 'assetDetailPanel.tagsLabel': 'Etiquetas',\n 'assetDetailPanel.bundleContents': 'Contenido del bundle ({{count}} assets)',\n 'assetDetailPanel.bundleItemNotSyncedYet': 'Aún no sincronizado — {{ref}}',\n 'assetDetailPanel.bundledFiles': 'Archivos incluidos',\n 'assetDetailPanel.zipDescription': 'Se descarga como .zip con todos los archivos anteriores.',\n 'assetDetailPanel.repository': 'Repositorio',\n 'assetDetailPanel.copyMarkdown': 'Copiar Markdown',\n 'assetDetailPanel.openInRepo': 'Abrir en el repositorio',\n 'assetDetailPanel.copiedMessage': '¡Markdown copiado al portapapeles!',\n\n 'assetFilters.searchPlaceholder': 'Buscar assets por nombre, descripción o contenido…',\n 'assetFilters.typeHeader': 'Tipo',\n 'assetFilters.typeAll': 'Todos',\n 'assetFilters.aiToolHeader': 'Herramienta de IA',\n 'assetFilters.allTools': 'Todas las herramientas',\n 'assetFilters.providerHeader': 'Proveedor',\n 'assetFilters.tagsHeader': 'Etiquetas',\n 'assetFilters.tagsShowMore': '+{{count}} más',\n 'assetFilters.tagsShowLess': 'Ver menos',\n\n 'assetInstallDialog.bundledSkillTitle': 'Skill con archivos — se descarga como .zip',\n 'assetInstallDialog.bundledSkillDescription': 'Esta skill incluye archivos de recursos junto al SKILL.md. Extraiga el zip y coloque todos los archivos en el directorio de la skill.',\n 'assetInstallDialog.installPathLabel': 'Ruta de instalación',\n 'assetInstallDialog.installInVscode': 'Instalar en VSCode',\n 'assetInstallDialog.copied': '¡Copiado!',\n 'assetInstallDialog.copyTooltip': 'Copiar contenido markdown',\n 'assetInstallDialog.copyContent': 'Copiar contenido',\n 'assetInstallDialog.downloadZipTooltip': 'Descargar como .zip con todos los archivos',\n 'assetInstallDialog.downloadTooltip': 'Descargar archivo con el nombre correcto',\n 'assetInstallDialog.downloadZip': 'Descargar .zip',\n 'assetInstallDialog.download': 'Descargar',\n 'assetInstallDialog.stepProgress': 'Paso {{current}} de {{total}}',\n 'assetInstallDialog.notSyncedTitle': 'Este asset aún no ha sido sincronizado.',\n 'assetInstallDialog.notSyncedRef': 'Ref: {{ref}}',\n 'assetInstallDialog.dialogTitleBundle': 'Instalar Bundle: {{name}}',\n 'assetInstallDialog.dialogSubtitleBundle': 'Instale cada asset del bundle paso a paso.',\n 'assetInstallDialog.dialogTitle': 'Instalar: {{name}}',\n 'assetInstallDialog.dialogSubtitle': 'Copie el contenido y coloque el archivo en la ruta indicada para su herramienta.',\n 'assetInstallDialog.bundleProgress': '{{current}} / {{total}} assets',\n 'assetInstallDialog.bundleEmpty': 'Este bundle aún no tiene elementos.',\n 'assetInstallDialog.downloadBundle': 'Descargar Bundle .zip',\n 'assetInstallDialog.back': 'Volver',\n 'assetInstallDialog.next': 'Siguiente',\n 'assetInstallDialog.finish': 'Finalizar',\n 'assetInstallDialog.close': 'Cerrar',\n\n 'mcpConfigDialog.title': 'Configuración MCP',\n 'mcpConfigDialog.subtitle': 'Explore el catálogo de servidores MCP listos para instalar o configure el MCP de Dev AI Hub para su herramienta de IA.',\n 'mcpConfigDialog.catalogTab': 'Catálogo MCP',\n 'mcpConfigDialog.catalogDescription': 'Servidores MCP preconfigurados que puede instalar con un clic en VSCode o Cursor.',\n 'mcpConfigDialog.catalogEmpty': 'No hay servidores MCP configurados en el catálogo.',\n 'mcpConfigDialog.catalogAddHint': 'Agregue un archivo mcp-catalog.yaml en la raíz de su repositorio de assets para gestionar el catálogo.',\n 'mcpConfigDialog.toolConfigSection': 'Configurar MCP de Dev AI Hub',\n 'mcpConfigDialog.scopeToProvider': 'Filtrar por Proveedor',\n 'mcpConfigDialog.allProviders': 'Todos los proveedores',\n 'mcpConfigDialog.proactiveSuggestions': 'Sugerencias proactivas',\n 'mcpConfigDialog.proactiveDescription': 'La IA sugerirá automáticamente assets relevantes según el contexto de su proyecto. Desactívelo si prefiere buscar manualmente.',\n 'mcpConfigDialog.mcpEndpoint': 'Endpoint MCP',\n 'mcpConfigDialog.copyUrl': 'Copiar URL',\n 'mcpConfigDialog.installInVscode': 'Instalar en VSCode',\n 'mcpConfigDialog.installInCursor': 'Instalar en Cursor',\n 'mcpConfigDialog.manualConfig': 'Config manual — {{file}}',\n 'mcpConfigDialog.claudeConfigDesc': 'Agregue a .mcp.json en la raíz del proyecto (o ejecute via claude mcp add):',\n 'mcpConfigDialog.copilotConfigDesc': 'Agregue a la configuración de VS Code (.vscode/settings.json o configuración de usuario):',\n 'mcpConfigDialog.geminiConfigDesc': 'Agregue a su configuración del Gemini CLI:',\n 'mcpConfigDialog.cursorConfigDesc': 'Agregue a .cursor/mcp.json en la raíz del proyecto:',\n 'mcpConfigDialog.omitToolHint': 'Omita ?tool= para recibir todos los assets independientemente de la herramienta.',\n 'mcpConfigDialog.close': 'Cerrar',\n\n 'devAiHubPage.title': 'Dev AI Hub',\n 'devAiHubPage.subtitle': 'Assets de IA centralizados para su equipo',\n 'devAiHubPage.statsInstructions': '{{count}} Instructions',\n 'devAiHubPage.statsAgents': '{{count}} Agents',\n 'devAiHubPage.statsSkills': '{{count}} Skills',\n 'devAiHubPage.statsWorkflows': '{{count}} Workflows',\n 'devAiHubPage.lastSync': 'Última sync: {{time}}',\n 'devAiHubPage.configMcp': 'MCP Servers',\n 'devAiHubPage.assetCountOne': '{{count}} asset',\n 'devAiHubPage.assetCountOther': '{{count}} assets',\n 'devAiHubPage.providerCountOne': '{{count}} proveedor',\n 'devAiHubPage.providerCountOther': '{{count}} proveedores',\n 'devAiHubPage.totalStats': '{{totalAssets}} assets · {{providers}}',\n 'devAiHubPage.noAssetsTitle': 'No se encontraron assets',\n 'devAiHubPage.noAssetsSubtitle': 'Intente ajustar los filtros o los términos de búsqueda.',\n 'devAiHubPage.timeJustNow': 'justo ahora',\n 'devAiHubPage.timeMinutesAgo': 'hace {{count}}min',\n 'devAiHubPage.timeHoursAgo': 'hace {{count}}h',\n 'devAiHubPage.timeDaysAgo': 'hace {{count}}d',\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,112 @@
1
+ var ptBR = {
2
+ "toolIcon.universal": "Universal",
3
+ "assetCard.newBadge": "Novo",
4
+ "assetCard.updatedBadge": "Atualizado",
5
+ "assetCard.installTooltip": "Instalar no editor",
6
+ "assetCard.detailsTooltip": "Ver detalhes",
7
+ "assetCard.helpTooltip": "Guia de uso",
8
+ "assetCard.mcpsRequired": "MCPs requeridos",
9
+ "assetCard.bundleFooter": "{{count}} assets \xB7 {{author}}",
10
+ "assetCard.versionFooter": "v{{version}} \xB7 {{author}}",
11
+ "assetCard.moreTags": "+{{count}}",
12
+ "assetDetailPanel.loading": "Carregando...",
13
+ "assetDetailPanel.tabPreview": "Visualiza\xE7\xE3o",
14
+ "assetDetailPanel.tabMetadata": "Metadados",
15
+ "assetDetailPanel.tabRawYaml": "YAML bruto",
16
+ "assetDetailPanel.bundlePreviewTitle": "Conte\xFAdo do bundle \u2014 {{count}} assets",
17
+ "assetDetailPanel.bundleItemNotSynced": "N\xE3o sincronizado \u2014 {{ref}}",
18
+ "assetDetailPanel.metaAuthor": "Autor",
19
+ "assetDetailPanel.metaVersion": "Vers\xE3o",
20
+ "assetDetailPanel.metaProvider": "Provedor",
21
+ "assetDetailPanel.metaCommit": "Commit",
22
+ "assetDetailPanel.metaLastSynced": "\xDAltima sincroniza\xE7\xE3o",
23
+ "assetDetailPanel.metaBranch": "Branch",
24
+ "assetDetailPanel.compatibleTools": "Ferramentas compat\xEDveis",
25
+ "assetDetailPanel.tagsLabel": "Tags",
26
+ "assetDetailPanel.bundleContents": "Conte\xFAdo do bundle ({{count}} assets)",
27
+ "assetDetailPanel.bundleItemNotSyncedYet": "Ainda n\xE3o sincronizado \u2014 {{ref}}",
28
+ "assetDetailPanel.bundledFiles": "Arquivos inclu\xEDdos",
29
+ "assetDetailPanel.zipDescription": "Baixa como .zip contendo todos os arquivos acima.",
30
+ "assetDetailPanel.repository": "Reposit\xF3rio",
31
+ "assetDetailPanel.copyMarkdown": "Copiar Markdown",
32
+ "assetDetailPanel.openInRepo": "Abrir no reposit\xF3rio",
33
+ "assetDetailPanel.copiedMessage": "Markdown copiado para a \xE1rea de transfer\xEAncia!",
34
+ "assetFilters.searchPlaceholder": "Buscar assets por nome, descri\xE7\xE3o ou conte\xFAdo\u2026",
35
+ "assetFilters.typeHeader": "Tipo",
36
+ "assetFilters.typeAll": "Todos",
37
+ "assetFilters.aiToolHeader": "Ferramenta de IA",
38
+ "assetFilters.allTools": "Todas as ferramentas",
39
+ "assetFilters.providerHeader": "Provedor",
40
+ "assetFilters.tagsHeader": "Tags",
41
+ "assetFilters.tagsShowMore": "+{{count}} mais",
42
+ "assetFilters.tagsShowLess": "Ver menos",
43
+ "assetInstallDialog.bundledSkillTitle": "Skill com arquivos \u2014 baixa como .zip",
44
+ "assetInstallDialog.bundledSkillDescription": "Esta skill inclui arquivos de recursos junto ao SKILL.md. Extraia o zip e coloque todos os arquivos no diret\xF3rio da skill.",
45
+ "assetInstallDialog.installPathLabel": "Caminho de instala\xE7\xE3o",
46
+ "assetInstallDialog.installInVscode": "Instalar no VSCode",
47
+ "assetInstallDialog.copied": "Copiado!",
48
+ "assetInstallDialog.copyTooltip": "Copiar conte\xFAdo markdown",
49
+ "assetInstallDialog.copyContent": "Copiar conte\xFAdo",
50
+ "assetInstallDialog.downloadZipTooltip": "Baixar como .zip com todos os arquivos",
51
+ "assetInstallDialog.downloadTooltip": "Baixar arquivo com o nome correto",
52
+ "assetInstallDialog.downloadZip": "Baixar .zip",
53
+ "assetInstallDialog.download": "Baixar",
54
+ "assetInstallDialog.stepProgress": "Passo {{current}} de {{total}}",
55
+ "assetInstallDialog.notSyncedTitle": "Este asset ainda n\xE3o foi sincronizado.",
56
+ "assetInstallDialog.notSyncedRef": "Ref: {{ref}}",
57
+ "assetInstallDialog.dialogTitleBundle": "Instalar Bundle: {{name}}",
58
+ "assetInstallDialog.dialogSubtitleBundle": "Instale cada asset do bundle passo a passo.",
59
+ "assetInstallDialog.dialogTitle": "Instalar: {{name}}",
60
+ "assetInstallDialog.dialogSubtitle": "Copie o conte\xFAdo e coloque o arquivo no caminho indicado para sua ferramenta.",
61
+ "assetInstallDialog.bundleProgress": "{{current}} / {{total}} assets",
62
+ "assetInstallDialog.bundleEmpty": "Este bundle ainda n\xE3o tem itens.",
63
+ "assetInstallDialog.downloadBundle": "Baixar Bundle .zip",
64
+ "assetInstallDialog.back": "Voltar",
65
+ "assetInstallDialog.next": "Pr\xF3ximo",
66
+ "assetInstallDialog.finish": "Concluir",
67
+ "assetInstallDialog.close": "Fechar",
68
+ "mcpConfigDialog.title": "Configura\xE7\xE3o MCP",
69
+ "mcpConfigDialog.subtitle": "Explore o cat\xE1logo de servidores MCP prontos para instalar ou configure o MCP do Dev AI Hub para sua ferramenta de IA.",
70
+ "mcpConfigDialog.catalogTab": "Cat\xE1logo MCP",
71
+ "mcpConfigDialog.catalogDescription": "Servidores MCP pr\xE9-configurados que voc\xEA pode instalar com um clique no VSCode ou Cursor.",
72
+ "mcpConfigDialog.catalogEmpty": "Nenhum servidor MCP configurado no cat\xE1logo.",
73
+ "mcpConfigDialog.catalogAddHint": "Adicione um arquivo mcp-catalog.yaml na raiz do seu reposit\xF3rio de assets para gerenciar o cat\xE1logo.",
74
+ "mcpConfigDialog.toolConfigSection": "Configurar MCP do Dev AI Hub",
75
+ "mcpConfigDialog.scopeToProvider": "Filtrar por Provedor",
76
+ "mcpConfigDialog.allProviders": "Todos os provedores",
77
+ "mcpConfigDialog.proactiveSuggestions": "Sugest\xF5es proativas",
78
+ "mcpConfigDialog.proactiveDescription": "A IA sugerir\xE1 automaticamente assets relevantes com base no contexto do seu projeto. Desative se preferir buscar manualmente.",
79
+ "mcpConfigDialog.mcpEndpoint": "Endpoint MCP",
80
+ "mcpConfigDialog.copyUrl": "Copiar URL",
81
+ "mcpConfigDialog.installInVscode": "Instalar no VSCode",
82
+ "mcpConfigDialog.installInCursor": "Instalar no Cursor",
83
+ "mcpConfigDialog.manualConfig": "Config manual \u2014 {{file}}",
84
+ "mcpConfigDialog.claudeConfigDesc": "Adicione ao .mcp.json na raiz do projeto (ou execute via claude mcp add):",
85
+ "mcpConfigDialog.copilotConfigDesc": "Adicione \xE0s configura\xE7\xF5es do VS Code (.vscode/settings.json ou configura\xE7\xF5es do usu\xE1rio):",
86
+ "mcpConfigDialog.geminiConfigDesc": "Adicione \xE0 configura\xE7\xE3o do Gemini CLI:",
87
+ "mcpConfigDialog.cursorConfigDesc": "Adicione ao .cursor/mcp.json na raiz do projeto:",
88
+ "mcpConfigDialog.omitToolHint": "Omita ?tool= para receber todos os assets independente da ferramenta.",
89
+ "mcpConfigDialog.close": "Fechar",
90
+ "devAiHubPage.title": "Dev AI Hub",
91
+ "devAiHubPage.subtitle": "Assets de IA centralizados para o seu time",
92
+ "devAiHubPage.statsInstructions": "{{count}} Instructions",
93
+ "devAiHubPage.statsAgents": "{{count}} Agents",
94
+ "devAiHubPage.statsSkills": "{{count}} Skills",
95
+ "devAiHubPage.statsWorkflows": "{{count}} Workflows",
96
+ "devAiHubPage.lastSync": "\xDAltima sync: {{time}}",
97
+ "devAiHubPage.configMcp": "MCP Servers",
98
+ "devAiHubPage.assetCountOne": "{{count}} asset",
99
+ "devAiHubPage.assetCountOther": "{{count}} assets",
100
+ "devAiHubPage.providerCountOne": "{{count}} provedor",
101
+ "devAiHubPage.providerCountOther": "{{count}} provedores",
102
+ "devAiHubPage.totalStats": "{{totalAssets}} assets \xB7 {{providers}}",
103
+ "devAiHubPage.noAssetsTitle": "Nenhum asset encontrado",
104
+ "devAiHubPage.noAssetsSubtitle": "Tente ajustar os filtros ou os termos de busca.",
105
+ "devAiHubPage.timeJustNow": "agora mesmo",
106
+ "devAiHubPage.timeMinutesAgo": "h\xE1 {{count}}min",
107
+ "devAiHubPage.timeHoursAgo": "h\xE1 {{count}}h",
108
+ "devAiHubPage.timeDaysAgo": "h\xE1 {{count}}d"
109
+ };
110
+
111
+ export { ptBR as default };
112
+ //# sourceMappingURL=pt-BR.esm.js.map