@nospt/plugin-dev-ai-hub 0.1.0 → 0.2.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.
- package/dev/index.tsx +17 -217
- package/dist/api/DevAiHubClient.esm.js +2 -0
- package/dist/api/DevAiHubClient.esm.js.map +1 -1
- package/dist/components/AssetCard/AssetCard.esm.js +60 -134
- package/dist/components/AssetCard/AssetCard.esm.js.map +1 -1
- package/dist/components/AssetCard/AssetCard.module.css.esm.js +8 -0
- package/dist/components/AssetCard/AssetCard.module.css.esm.js.map +1 -0
- package/dist/components/AssetDetailPanel/AssetDetailPanel.esm.js +175 -281
- package/dist/components/AssetDetailPanel/AssetDetailPanel.esm.js.map +1 -1
- package/dist/components/AssetDetailPanel/AssetDetailPanel.module.css.esm.js +8 -0
- package/dist/components/AssetDetailPanel/AssetDetailPanel.module.css.esm.js.map +1 -0
- package/dist/components/AssetFilters/AssetFilters.esm.js +94 -134
- package/dist/components/AssetFilters/AssetFilters.esm.js.map +1 -1
- package/dist/components/AssetFilters/AssetFilters.module.css.esm.js +8 -0
- package/dist/components/AssetFilters/AssetFilters.module.css.esm.js.map +1 -0
- package/dist/components/AssetInstallDialog/AssetInstallDialog.esm.js +70 -126
- package/dist/components/AssetInstallDialog/AssetInstallDialog.esm.js.map +1 -1
- package/dist/components/AssetInstallDialog/AssetInstallDialog.module.css.esm.js +8 -0
- package/dist/components/AssetInstallDialog/AssetInstallDialog.module.css.esm.js.map +1 -0
- package/dist/components/DevAiHubPage/DevAiHubPage.esm.js +64 -189
- package/dist/components/DevAiHubPage/DevAiHubPage.esm.js.map +1 -1
- package/dist/components/DevAiHubPage/DevAiHubPage.module.css.esm.js +8 -0
- package/dist/components/DevAiHubPage/DevAiHubPage.module.css.esm.js.map +1 -0
- package/dist/components/McpConfigPage/McpConfigPage.esm.js +200 -0
- package/dist/components/McpConfigPage/McpConfigPage.esm.js.map +1 -0
- package/dist/components/McpConfigPage/McpConfigPage.module.css.esm.js +8 -0
- package/dist/components/McpConfigPage/McpConfigPage.module.css.esm.js.map +1 -0
- package/dist/components/McpConfigPage/index.esm.js +6 -0
- package/dist/components/McpConfigPage/index.esm.js.map +1 -0
- package/dist/components/ToolIcon/ToolIcon.esm.js +25 -13
- package/dist/components/ToolIcon/ToolIcon.esm.js.map +1 -1
- package/dist/index.d.ts +10 -5
- package/dist/index.esm.js +1 -1
- package/dist/node_modules_dist/style-inject/dist/style-inject.es.esm.js +29 -0
- package/dist/node_modules_dist/style-inject/dist/style-inject.es.esm.js.map +1 -0
- package/dist/plugin.esm.js +22 -4
- package/dist/plugin.esm.js.map +1 -1
- package/dist/routes.esm.js +2 -1
- package/dist/routes.esm.js.map +1 -1
- package/package.json +24 -14
- package/package.json-prepack +24 -14
- package/src/components/AssetCard/AssetCard.module.css +153 -0
- package/src/components/AssetCard/AssetCard.tsx +79 -148
- package/src/components/AssetDetailPanel/AssetDetailPanel.module.css +207 -0
- package/src/components/AssetDetailPanel/AssetDetailPanel.tsx +228 -292
- package/src/components/AssetFilters/AssetFilters.module.css +67 -0
- package/src/components/AssetFilters/AssetFilters.tsx +136 -178
- package/src/components/AssetInstallDialog/AssetInstallDialog.module.css +72 -0
- package/src/components/AssetInstallDialog/AssetInstallDialog.tsx +95 -135
- package/src/components/DevAiHubPage/DevAiHubPage.module.css +105 -0
- package/src/components/DevAiHubPage/DevAiHubPage.tsx +73 -222
- package/src/components/McpConfigDialog/McpConfigDialog.module.css +111 -0
- package/src/components/McpConfigDialog/McpConfigDialog.tsx +178 -208
- package/src/components/McpConfigPage/McpConfigPage.module.css +121 -0
- package/src/components/McpConfigPage/McpConfigPage.tsx +242 -0
- package/src/components/McpConfigPage/index.ts +1 -0
- package/src/components/ToolIcon/ToolIcon.tsx +31 -15
- package/src/css-modules.d.ts +4 -0
- package/src/index.ts +1 -1
- package/src/plugin.tsx +21 -1
- package/src/routes.ts +1 -0
- package/tests/e2e/.auth.json +14 -0
- package/tests/e2e/asset-detail.spec.ts +90 -0
- package/tests/e2e/asset-filtering.spec.ts +145 -0
- package/tests/e2e/asset-installation.spec.ts +74 -0
- package/tests/e2e/dev-ai-hub-page.spec.ts +89 -0
- package/tests/e2e/fixtures/base.ts +61 -0
- package/tests/e2e/fixtures/mock-api.ts +221 -0
- package/tests/e2e/mcp-config.spec.ts +88 -0
- package/dist/components/McpConfigDialog/McpConfigDialog.esm.js +0 -274
- package/dist/components/McpConfigDialog/McpConfigDialog.esm.js.map +0 -1
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useState, useEffect } from 'react';
|
|
3
|
+
import { Text, Tabs, TabList, Tab, TabPanel, Box, Flex, ToggleButton, Switch, TooltipTrigger, ButtonIcon, Tooltip } from '@backstage/ui';
|
|
4
|
+
import { RiDatabase2Line, RiCheckLine, RiFileCopyLine } from '@remixicon/react';
|
|
5
|
+
import { useApi, discoveryApiRef } from '@backstage/core-plugin-api';
|
|
6
|
+
import { ToolIcon } from '../ToolIcon/ToolIcon.esm.js';
|
|
7
|
+
import { useCopyToClipboard, useProviders } from '../../hooks/index.esm.js';
|
|
8
|
+
import styles from './McpConfigPage.module.css.esm.js';
|
|
9
|
+
|
|
10
|
+
const TOOL_CONFIGS = [
|
|
11
|
+
{
|
|
12
|
+
tool: "claude-code",
|
|
13
|
+
label: "Claude Code",
|
|
14
|
+
file: ".mcp.json",
|
|
15
|
+
description: "Add to .mcp.json in your project root (or run via claude mcp add):",
|
|
16
|
+
buildConfig: (url) => JSON.stringify({
|
|
17
|
+
mcpServers: { "dev-ai-hub": { type: "http", url } }
|
|
18
|
+
}, null, 2)
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
tool: "github-copilot",
|
|
22
|
+
label: "GitHub Copilot",
|
|
23
|
+
file: ".vscode/settings.json",
|
|
24
|
+
description: "Add to your VS Code settings (.vscode/settings.json or user settings):",
|
|
25
|
+
buildConfig: (url) => JSON.stringify({
|
|
26
|
+
"github.copilot.chat.mcp.servers": { "dev-ai-hub": { type: "http", url } }
|
|
27
|
+
}, null, 2)
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
tool: "google-gemini",
|
|
31
|
+
label: "Google Gemini",
|
|
32
|
+
file: "gemini-config.json",
|
|
33
|
+
description: "Add to your Gemini CLI configuration:",
|
|
34
|
+
buildConfig: (url) => JSON.stringify({
|
|
35
|
+
mcpServers: { "dev-ai-hub": { url } }
|
|
36
|
+
}, null, 2)
|
|
37
|
+
}
|
|
38
|
+
];
|
|
39
|
+
function providerLabel(target) {
|
|
40
|
+
return target.split("/").pop()?.replace(/\.git$/, "") ?? target;
|
|
41
|
+
}
|
|
42
|
+
function McpConfigPage() {
|
|
43
|
+
const discoveryApi = useApi(discoveryApiRef);
|
|
44
|
+
const { copy: copyUrl, copied: copiedUrl } = useCopyToClipboard();
|
|
45
|
+
const { copy: copySnippet, copied: copiedSnippet } = useCopyToClipboard();
|
|
46
|
+
const [selectedToolKey, setSelectedToolKey] = useState("claude-code");
|
|
47
|
+
const [baseUrl, setBaseUrl] = useState("");
|
|
48
|
+
const [selectedProvider, setSelectedProvider] = useState("");
|
|
49
|
+
const [proactiveEnabled, setProactiveEnabled] = useState(false);
|
|
50
|
+
const { providers } = useProviders();
|
|
51
|
+
const showProviderFilter = providers.length > 1;
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
discoveryApi.getBaseUrl("dev-ai-hub").then((url) => setBaseUrl(url));
|
|
54
|
+
}, [discoveryApi]);
|
|
55
|
+
const cfg = TOOL_CONFIGS.find((t) => t.tool === selectedToolKey) ?? TOOL_CONFIGS[0];
|
|
56
|
+
const buildMcpUrl = () => {
|
|
57
|
+
if (!baseUrl) return "loading...";
|
|
58
|
+
const params = new URLSearchParams();
|
|
59
|
+
params.set("tool", cfg.tool);
|
|
60
|
+
if (selectedProvider) params.set("provider", selectedProvider);
|
|
61
|
+
if (proactiveEnabled) params.set("proactive", "true");
|
|
62
|
+
return `${baseUrl}/mcp?${params.toString()}`;
|
|
63
|
+
};
|
|
64
|
+
const mcpUrl = buildMcpUrl();
|
|
65
|
+
const configSnippet = baseUrl ? cfg.buildConfig(mcpUrl) : "";
|
|
66
|
+
const [isDark, setIsDark] = useState(() => {
|
|
67
|
+
if (typeof document === "undefined") return false;
|
|
68
|
+
return document.documentElement.getAttribute("data-theme-mode") === "dark" || document.body.getAttribute("data-theme-mode") === "dark";
|
|
69
|
+
});
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
const getIsDark = () => document.documentElement.getAttribute("data-theme-mode") === "dark" || document.body.getAttribute("data-theme-mode") === "dark";
|
|
72
|
+
const observer = new MutationObserver(() => setIsDark(getIsDark()));
|
|
73
|
+
observer.observe(document.documentElement, { attributes: true, attributeFilter: ["data-theme-mode"] });
|
|
74
|
+
observer.observe(document.body, { attributes: true, attributeFilter: ["data-theme-mode"] });
|
|
75
|
+
return () => observer.disconnect();
|
|
76
|
+
}, []);
|
|
77
|
+
return /* @__PURE__ */ jsxs("div", { className: styles.pageRoot, children: [
|
|
78
|
+
/* @__PURE__ */ jsx(Text, { variant: "title-small", weight: "bold", children: "Configure MCP Server" }),
|
|
79
|
+
/* @__PURE__ */ jsx(Text, { variant: "body-small", color: "secondary", className: styles.subtitle, children: "Connect your AI tool to the Dev AI Hub via Model Context Protocol." }),
|
|
80
|
+
/* @__PURE__ */ jsx("div", { className: styles.configContent, children: /* @__PURE__ */ jsxs(Tabs, { selectedKey: selectedToolKey, onSelectionChange: (key) => setSelectedToolKey(key), children: [
|
|
81
|
+
/* @__PURE__ */ jsx(TabList, { className: styles.tabBar, children: TOOL_CONFIGS.map((t) => /* @__PURE__ */ jsx(Tab, { id: t.tool, children: /* @__PURE__ */ jsxs("span", { className: styles.tabContent, children: [
|
|
82
|
+
/* @__PURE__ */ jsx(ToolIcon, { tool: t.tool, size: 16 }),
|
|
83
|
+
/* @__PURE__ */ jsx("span", { children: t.label })
|
|
84
|
+
] }) }, t.tool)) }),
|
|
85
|
+
TOOL_CONFIGS.map((t) => /* @__PURE__ */ jsxs(TabPanel, { id: t.tool, children: [
|
|
86
|
+
showProviderFilter && /* @__PURE__ */ jsxs(Box, { className: styles.providerSection, children: [
|
|
87
|
+
/* @__PURE__ */ jsx(Text, { variant: "body-x-small", color: "secondary", className: styles.sectionLabel, children: "Scope to Provider" }),
|
|
88
|
+
/* @__PURE__ */ jsxs(Flex, { className: styles.chipsRow, children: [
|
|
89
|
+
/* @__PURE__ */ jsx(
|
|
90
|
+
ToggleButton,
|
|
91
|
+
{
|
|
92
|
+
id: "all-providers",
|
|
93
|
+
size: "small",
|
|
94
|
+
className: styles.filterChip,
|
|
95
|
+
isSelected: !selectedProvider,
|
|
96
|
+
onChange: () => setSelectedProvider(""),
|
|
97
|
+
style: {
|
|
98
|
+
borderColor: !selectedProvider ? "var(--bui-fg-primary)" : "var(--bui-border-1)",
|
|
99
|
+
backgroundColor: !selectedProvider ? "var(--bui-fg-primary)" : "transparent",
|
|
100
|
+
color: !selectedProvider ? "var(--bui-bg-neutral-1)" : "var(--bui-fg-secondary)"
|
|
101
|
+
},
|
|
102
|
+
children: "All providers"
|
|
103
|
+
}
|
|
104
|
+
),
|
|
105
|
+
providers.map((p) => {
|
|
106
|
+
const isSelected = selectedProvider === p.id;
|
|
107
|
+
const label = providerLabel(p.target);
|
|
108
|
+
return /* @__PURE__ */ jsx(
|
|
109
|
+
ToggleButton,
|
|
110
|
+
{
|
|
111
|
+
id: p.id,
|
|
112
|
+
size: "small",
|
|
113
|
+
className: styles.filterChip,
|
|
114
|
+
iconStart: /* @__PURE__ */ jsx(RiDatabase2Line, { size: 12, style: { color: isSelected ? "var(--bui-bg-neutral-1)" : "inherit" } }),
|
|
115
|
+
isSelected,
|
|
116
|
+
onChange: () => setSelectedProvider(isSelected ? "" : p.id),
|
|
117
|
+
style: {
|
|
118
|
+
borderColor: isSelected ? "var(--bui-fg-primary)" : "var(--bui-border-1)",
|
|
119
|
+
backgroundColor: isSelected ? "var(--bui-fg-primary)" : "transparent",
|
|
120
|
+
color: isSelected ? "var(--bui-bg-neutral-1)" : "var(--bui-fg-secondary)"
|
|
121
|
+
},
|
|
122
|
+
children: label
|
|
123
|
+
},
|
|
124
|
+
p.id
|
|
125
|
+
);
|
|
126
|
+
})
|
|
127
|
+
] })
|
|
128
|
+
] }),
|
|
129
|
+
/* @__PURE__ */ jsx(Flex, { className: styles.proactiveSection, children: /* @__PURE__ */ jsxs(Flex, { className: styles.proactiveRow, children: [
|
|
130
|
+
/* @__PURE__ */ jsx(
|
|
131
|
+
Switch,
|
|
132
|
+
{
|
|
133
|
+
isSelected: proactiveEnabled,
|
|
134
|
+
onChange: setProactiveEnabled,
|
|
135
|
+
"aria-label": "Proactive suggestions"
|
|
136
|
+
}
|
|
137
|
+
),
|
|
138
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
139
|
+
/* @__PURE__ */ jsx(Text, { variant: "body-small", weight: "bold", children: "Proactive suggestions" }),
|
|
140
|
+
/* @__PURE__ */ jsx(Text, { variant: "body-x-small", color: "secondary", children: "The AI will automatically suggest relevant assets based on your project context. Disable if you prefer to search manually." })
|
|
141
|
+
] })
|
|
142
|
+
] }) }),
|
|
143
|
+
/* @__PURE__ */ jsxs(Box, { className: styles.urlSection, children: [
|
|
144
|
+
/* @__PURE__ */ jsx(Text, { variant: "body-x-small", color: "secondary", className: styles.sectionLabel, children: "MCP Endpoint" }),
|
|
145
|
+
/* @__PURE__ */ jsxs(Flex, { className: styles.urlBox, children: [
|
|
146
|
+
/* @__PURE__ */ jsx(Text, { variant: "body-small", className: styles.urlText, children: mcpUrl }),
|
|
147
|
+
/* @__PURE__ */ jsxs(TooltipTrigger, { children: [
|
|
148
|
+
/* @__PURE__ */ jsx(
|
|
149
|
+
ButtonIcon,
|
|
150
|
+
{
|
|
151
|
+
"aria-label": copiedUrl ? "Copied!" : "Copy URL",
|
|
152
|
+
icon: copiedUrl ? /* @__PURE__ */ jsx(RiCheckLine, { size: 14, style: { color: "var(--bui-fg-success)" } }) : /* @__PURE__ */ jsx(RiFileCopyLine, { size: 14 }),
|
|
153
|
+
variant: "tertiary",
|
|
154
|
+
onPress: () => copyUrl(mcpUrl)
|
|
155
|
+
}
|
|
156
|
+
),
|
|
157
|
+
/* @__PURE__ */ jsx(Tooltip, { children: copiedUrl ? "Copied!" : "Copy URL" })
|
|
158
|
+
] })
|
|
159
|
+
] })
|
|
160
|
+
] }),
|
|
161
|
+
/* @__PURE__ */ jsx(Text, { variant: "body-x-small", color: "secondary", className: styles.sectionLabel, children: t.file }),
|
|
162
|
+
/* @__PURE__ */ jsx(Text, { variant: "body-x-small", color: "secondary", style: { display: "block", marginBottom: "var(--bui-space-2)", marginTop: "var(--bui-space-1)" }, children: t.description }),
|
|
163
|
+
/* @__PURE__ */ jsxs("div", { className: styles.snippetContainer, children: [
|
|
164
|
+
/* @__PURE__ */ jsx("pre", { className: `${styles.snippetPre} ${isDark ? styles.snippetPreDark : styles.snippetPreLight}`, children: configSnippet }),
|
|
165
|
+
/* @__PURE__ */ jsxs(TooltipTrigger, { children: [
|
|
166
|
+
/* @__PURE__ */ jsx(
|
|
167
|
+
ButtonIcon,
|
|
168
|
+
{
|
|
169
|
+
"aria-label": "Copy config",
|
|
170
|
+
className: styles.copySnippetButton,
|
|
171
|
+
icon: copiedSnippet ? /* @__PURE__ */ jsx(RiCheckLine, { size: 14, style: { color: "var(--bui-fg-success)" } }) : /* @__PURE__ */ jsx(RiFileCopyLine, { size: 14 }),
|
|
172
|
+
variant: "tertiary",
|
|
173
|
+
onPress: () => copySnippet(configSnippet)
|
|
174
|
+
}
|
|
175
|
+
),
|
|
176
|
+
/* @__PURE__ */ jsx(Tooltip, { children: copiedSnippet ? "Copied!" : "Copy config" })
|
|
177
|
+
] })
|
|
178
|
+
] }),
|
|
179
|
+
/* @__PURE__ */ jsxs(Text, { variant: "body-x-small", color: "secondary", className: styles.hint, children: [
|
|
180
|
+
"\u{1F4A1} Omit ",
|
|
181
|
+
/* @__PURE__ */ jsx("code", { children: "?tool=" }),
|
|
182
|
+
" from the URL to receive assets for all AI tools.",
|
|
183
|
+
showProviderFilter && " Omit ?provider= to receive assets from all repositories.",
|
|
184
|
+
" ",
|
|
185
|
+
"Proactive suggestions add ",
|
|
186
|
+
/* @__PURE__ */ jsx("code", { children: "?proactive=true" }),
|
|
187
|
+
" and register the",
|
|
188
|
+
" ",
|
|
189
|
+
/* @__PURE__ */ jsx("code", { children: "suggest_assets" }),
|
|
190
|
+
" tool and ",
|
|
191
|
+
/* @__PURE__ */ jsx("code", { children: "check_for_assets" }),
|
|
192
|
+
" prompt."
|
|
193
|
+
] })
|
|
194
|
+
] }, t.tool))
|
|
195
|
+
] }) })
|
|
196
|
+
] });
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export { McpConfigPage };
|
|
200
|
+
//# sourceMappingURL=McpConfigPage.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"McpConfigPage.esm.js","sources":["../../../src/components/McpConfigPage/McpConfigPage.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport {\n Box, Flex, Text, ButtonIcon, ToggleButton, Switch,\n Tabs, TabList, Tab, TabPanel,\n Tooltip, TooltipTrigger,\n} from '@backstage/ui';\nimport { RiFileCopyLine, RiCheckLine, RiDatabase2Line } from '@remixicon/react';\nimport { useApi, discoveryApiRef } from '@backstage/core-plugin-api';\nimport { ToolIcon } from '../ToolIcon';\nimport { useCopyToClipboard, useProviders } from '../../hooks';\nimport type { AiTool } from '@nospt/plugin-dev-ai-hub-common';\nimport styles from './McpConfigPage.module.css';\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\nfunction providerLabel(target: string): string {\n return target.split('/').pop()?.replace(/\\.git$/, '') ?? target;\n}\n\nexport function McpConfigPage() {\n const discoveryApi = useApi(discoveryApiRef);\n const { copy: copyUrl, copied: copiedUrl } = useCopyToClipboard();\n const { copy: copySnippet, copied: copiedSnippet } = useCopyToClipboard();\n const [selectedToolKey, setSelectedToolKey] = useState<string>('claude-code');\n const [baseUrl, setBaseUrl] = useState('');\n const [selectedProvider, setSelectedProvider] = useState<string>('');\n const [proactiveEnabled, setProactiveEnabled] = useState(false);\n\n const { providers } = useProviders();\n const showProviderFilter = providers.length > 1;\n\n useEffect(() => {\n discoveryApi.getBaseUrl('dev-ai-hub').then(url => setBaseUrl(url));\n }, [discoveryApi]);\n\n const cfg = TOOL_CONFIGS.find(t => t.tool === selectedToolKey) ?? TOOL_CONFIGS[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 [isDark, setIsDark] = useState(() => {\n if (typeof document === 'undefined') return false;\n return document.documentElement.getAttribute('data-theme-mode') === 'dark' ||\n document.body.getAttribute('data-theme-mode') === 'dark';\n });\n\n useEffect(() => {\n const getIsDark = () =>\n document.documentElement.getAttribute('data-theme-mode') === 'dark' ||\n document.body.getAttribute('data-theme-mode') === 'dark';\n\n const observer = new MutationObserver(() => setIsDark(getIsDark()));\n observer.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme-mode'] });\n observer.observe(document.body, { attributes: true, attributeFilter: ['data-theme-mode'] });\n return () => observer.disconnect();\n }, []);\n\n return (\n <div className={styles.pageRoot}>\n <Text variant=\"title-small\" weight=\"bold\">Configure MCP Server</Text>\n <Text variant=\"body-small\" color=\"secondary\" className={styles.subtitle}>\n Connect your AI tool to the Dev AI Hub via Model Context Protocol.\n </Text>\n\n <div className={styles.configContent}>\n <Tabs selectedKey={selectedToolKey} onSelectionChange={key => setSelectedToolKey(key as string)}>\n <TabList className={styles.tabBar}>\n {TOOL_CONFIGS.map(t => (\n <Tab key={t.tool} id={t.tool}>\n <span className={styles.tabContent}>\n <ToolIcon tool={t.tool} size={16} />\n <span>{t.label}</span>\n </span>\n </Tab>\n ))}\n </TabList>\n\n {TOOL_CONFIGS.map(t => (\n <TabPanel key={t.tool} id={t.tool}>\n {showProviderFilter && (\n <Box className={styles.providerSection}>\n <Text variant=\"body-x-small\" color=\"secondary\" className={styles.sectionLabel}>\n Scope to Provider\n </Text>\n <Flex className={styles.chipsRow}>\n <ToggleButton\n id=\"all-providers\"\n size=\"small\"\n className={styles.filterChip}\n isSelected={!selectedProvider}\n onChange={() => setSelectedProvider('')}\n style={{\n borderColor: !selectedProvider ? 'var(--bui-fg-primary)' : 'var(--bui-border-1)',\n backgroundColor: !selectedProvider ? 'var(--bui-fg-primary)' : 'transparent',\n color: !selectedProvider ? 'var(--bui-bg-neutral-1)' : 'var(--bui-fg-secondary)',\n }}\n >\n All providers\n </ToggleButton>\n {providers.map(p => {\n const isSelected = selectedProvider === p.id;\n const label = providerLabel(p.target);\n return (\n <ToggleButton\n key={p.id}\n id={p.id}\n size=\"small\"\n className={styles.filterChip}\n iconStart={<RiDatabase2Line size={12} style={{ color: isSelected ? 'var(--bui-bg-neutral-1)' : 'inherit' }} />}\n isSelected={isSelected}\n onChange={() => setSelectedProvider(isSelected ? '' : p.id)}\n style={{\n borderColor: isSelected ? 'var(--bui-fg-primary)' : 'var(--bui-border-1)',\n backgroundColor: isSelected ? 'var(--bui-fg-primary)' : 'transparent',\n color: isSelected ? 'var(--bui-bg-neutral-1)' : 'var(--bui-fg-secondary)',\n }}\n >\n {label}\n </ToggleButton>\n );\n })}\n </Flex>\n </Box>\n )}\n\n <Flex className={styles.proactiveSection}>\n <Flex className={styles.proactiveRow}>\n <Switch\n isSelected={proactiveEnabled}\n onChange={setProactiveEnabled}\n aria-label=\"Proactive suggestions\"\n />\n <Box>\n <Text variant=\"body-small\" weight=\"bold\">Proactive suggestions</Text>\n <Text variant=\"body-x-small\" color=\"secondary\">\n The AI will automatically suggest relevant assets based on your project context.\n Disable if you prefer to search manually.\n </Text>\n </Box>\n </Flex>\n </Flex>\n\n <Box className={styles.urlSection}>\n <Text variant=\"body-x-small\" color=\"secondary\" className={styles.sectionLabel}>\n MCP Endpoint\n </Text>\n <Flex className={styles.urlBox}>\n <Text variant=\"body-small\" className={styles.urlText}>\n {mcpUrl}\n </Text>\n <TooltipTrigger>\n <ButtonIcon\n aria-label={copiedUrl ? 'Copied!' : 'Copy URL'}\n icon={copiedUrl ? <RiCheckLine size={14} style={{ color: 'var(--bui-fg-success)' }} /> : <RiFileCopyLine size={14} />}\n variant=\"tertiary\"\n onPress={() => copyUrl(mcpUrl)}\n />\n <Tooltip>{copiedUrl ? 'Copied!' : 'Copy URL'}</Tooltip>\n </TooltipTrigger>\n </Flex>\n </Box>\n\n <Text variant=\"body-x-small\" color=\"secondary\" className={styles.sectionLabel}>\n {t.file}\n </Text>\n <Text variant=\"body-x-small\" color=\"secondary\" style={{ display: 'block', marginBottom: 'var(--bui-space-2)', marginTop: 'var(--bui-space-1)' }}>\n {t.description}\n </Text>\n <div className={styles.snippetContainer}>\n <pre className={`${styles.snippetPre} ${isDark ? styles.snippetPreDark : styles.snippetPreLight}`}>\n {configSnippet}\n </pre>\n <TooltipTrigger>\n <ButtonIcon\n aria-label=\"Copy config\"\n className={styles.copySnippetButton}\n icon={copiedSnippet ? <RiCheckLine size={14} style={{ color: 'var(--bui-fg-success)' }} /> : <RiFileCopyLine size={14} />}\n variant=\"tertiary\"\n onPress={() => copySnippet(configSnippet)}\n />\n <Tooltip>{copiedSnippet ? 'Copied!' : 'Copy config'}</Tooltip>\n </TooltipTrigger>\n </div>\n\n <Text variant=\"body-x-small\" color=\"secondary\" className={styles.hint}>\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 </Text>\n </TabPanel>\n ))}\n </Tabs>\n </div>\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import styleInject from '../../node_modules_dist/style-inject/dist/style-inject.es.esm.js';
|
|
2
|
+
|
|
3
|
+
var css_248z = "@layer components {\n .McpConfigPage_pageRoot__fc0e9afedd {\n padding: var(--bui-space-6);\n }\n\n .McpConfigPage_subtitle__fc0e9afedd {\n margin-top: var(--bui-space-1);\n display: block;\n }\n\n .McpConfigPage_configContent__fc0e9afedd {\n margin-top: var(--bui-space-6);\n max-width: 720px;\n }\n\n .McpConfigPage_tabBar__fc0e9afedd {\n margin-bottom: var(--bui-space-4);\n border-bottom: 1px solid var(--bui-border-1);\n }\n\n .McpConfigPage_tabContent__fc0e9afedd {\n display: flex;\n align-items: center;\n gap: var(--bui-space-2);\n }\n\n .McpConfigPage_sectionLabel__fc0e9afedd {\n text-transform: uppercase;\n letter-spacing: 0.5px;\n display: block;\n margin-bottom: 6px;\n font-weight: 600;\n }\n\n .McpConfigPage_providerSection__fc0e9afedd {\n margin-bottom: var(--bui-space-4);\n }\n\n .McpConfigPage_chipsRow__fc0e9afedd {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n }\n\n .McpConfigPage_filterChip__fc0e9afedd {\n font-weight: 600;\n font-size: 0.75rem;\n border-radius: var(--bui-radius-2);\n border: 1.5px solid;\n transition: all 0.15s ease;\n cursor: pointer;\n }\n\n .McpConfigPage_proactiveSection__fc0e9afedd {\n margin-bottom: var(--bui-space-4);\n }\n\n .McpConfigPage_proactiveRow__fc0e9afedd {\n display: flex;\n align-items: flex-start;\n gap: var(--bui-space-2);\n }\n\n .McpConfigPage_urlSection__fc0e9afedd {\n margin-bottom: var(--bui-space-4);\n }\n\n .McpConfigPage_urlBox__fc0e9afedd {\n display: flex;\n align-items: center;\n gap: var(--bui-space-2);\n margin-top: var(--bui-space-1);\n padding: var(--bui-space-2) var(--bui-space-3);\n border-radius: var(--bui-radius-2);\n border: 1px solid var(--bui-border-1);\n background-color: var(--bui-bg-neutral-1-hover);\n }\n\n .McpConfigPage_urlText__fc0e9afedd {\n flex: 1;\n font-family: monospace;\n font-size: 0.8rem;\n word-break: break-all;\n }\n\n .McpConfigPage_snippetContainer__fc0e9afedd {\n position: relative;\n }\n\n .McpConfigPage_snippetPre__fc0e9afedd {\n margin: 0;\n padding: var(--bui-space-4);\n border-radius: var(--bui-radius-2);\n border: 1px solid var(--bui-border-1);\n font-family: monospace;\n font-size: 0.8rem;\n overflow-x: auto;\n white-space: pre;\n }\n\n .McpConfigPage_snippetPreLight__fc0e9afedd {\n background-color: #f6f8fa;\n color: #24292f;\n }\n\n .McpConfigPage_snippetPreDark__fc0e9afedd {\n background-color: #1E1E1E;\n color: #DCDDE1;\n }\n\n .McpConfigPage_copySnippetButton__fc0e9afedd {\n position: absolute;\n top: 8px;\n right: 8px;\n }\n\n .McpConfigPage_hint__fc0e9afedd {\n display: block;\n margin-top: var(--bui-space-3);\n }\n}\n";
|
|
4
|
+
var styles = {"pageRoot":"McpConfigPage_pageRoot__fc0e9afedd","subtitle":"McpConfigPage_subtitle__fc0e9afedd","configContent":"McpConfigPage_configContent__fc0e9afedd","tabBar":"McpConfigPage_tabBar__fc0e9afedd","tabContent":"McpConfigPage_tabContent__fc0e9afedd","sectionLabel":"McpConfigPage_sectionLabel__fc0e9afedd","providerSection":"McpConfigPage_providerSection__fc0e9afedd","chipsRow":"McpConfigPage_chipsRow__fc0e9afedd","filterChip":"McpConfigPage_filterChip__fc0e9afedd","proactiveSection":"McpConfigPage_proactiveSection__fc0e9afedd","proactiveRow":"McpConfigPage_proactiveRow__fc0e9afedd","urlSection":"McpConfigPage_urlSection__fc0e9afedd","urlBox":"McpConfigPage_urlBox__fc0e9afedd","urlText":"McpConfigPage_urlText__fc0e9afedd","snippetContainer":"McpConfigPage_snippetContainer__fc0e9afedd","snippetPre":"McpConfigPage_snippetPre__fc0e9afedd","snippetPreLight":"McpConfigPage_snippetPreLight__fc0e9afedd","snippetPreDark":"McpConfigPage_snippetPreDark__fc0e9afedd","copySnippetButton":"McpConfigPage_copySnippetButton__fc0e9afedd","hint":"McpConfigPage_hint__fc0e9afedd"};
|
|
5
|
+
styleInject(css_248z);
|
|
6
|
+
|
|
7
|
+
export { styles as default };
|
|
8
|
+
//# sourceMappingURL=McpConfigPage.module.css.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"McpConfigPage.module.css.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import
|
|
3
|
-
import AllInclusiveIcon from '@mui/icons-material/AllInclusive';
|
|
4
|
-
import NearMeIcon from '@mui/icons-material/NearMe';
|
|
2
|
+
import { RiInfinityLine, RiNavigationLine } from '@remixicon/react';
|
|
5
3
|
import { siGooglegemini, siGithub, siAnthropic } from 'simple-icons';
|
|
6
4
|
|
|
7
5
|
const TOOL_ICON = {
|
|
@@ -9,29 +7,43 @@ const TOOL_ICON = {
|
|
|
9
7
|
"github-copilot": { ...siGithub, label: "GitHub Copilot" },
|
|
10
8
|
"google-gemini": { ...siGooglegemini, label: "Google Gemini" }
|
|
11
9
|
};
|
|
12
|
-
function ToolIcon({ tool, branded = true,
|
|
10
|
+
function ToolIcon({ tool, branded = true, className, style, size = 20 }) {
|
|
13
11
|
if (tool === "all") {
|
|
14
|
-
return /* @__PURE__ */ jsx(
|
|
12
|
+
return /* @__PURE__ */ jsx(
|
|
13
|
+
RiInfinityLine,
|
|
14
|
+
{
|
|
15
|
+
size,
|
|
16
|
+
className,
|
|
17
|
+
style: { color: "var(--bui-fg-secondary)", ...style },
|
|
18
|
+
"aria-label": "Universal"
|
|
19
|
+
}
|
|
20
|
+
);
|
|
15
21
|
}
|
|
16
22
|
if (tool === "cursor") {
|
|
17
23
|
return /* @__PURE__ */ jsx(
|
|
18
|
-
|
|
24
|
+
RiNavigationLine,
|
|
19
25
|
{
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
26
|
+
size,
|
|
27
|
+
className,
|
|
28
|
+
style: { color: branded ? "var(--bui-fg-primary)" : "inherit", ...style },
|
|
29
|
+
"aria-label": "Cursor"
|
|
23
30
|
}
|
|
24
31
|
);
|
|
25
32
|
}
|
|
26
33
|
const cfg = TOOL_ICON[tool];
|
|
27
34
|
if (!cfg) return null;
|
|
28
35
|
return /* @__PURE__ */ jsx(
|
|
29
|
-
|
|
36
|
+
"svg",
|
|
30
37
|
{
|
|
31
|
-
|
|
32
|
-
sx: { color: branded ? `#${cfg.hex}` : "inherit", ...sx },
|
|
33
|
-
titleAccess: cfg.label,
|
|
38
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
34
39
|
viewBox: "0 0 24 24",
|
|
40
|
+
width: size,
|
|
41
|
+
height: size,
|
|
42
|
+
fill: "currentColor",
|
|
43
|
+
className,
|
|
44
|
+
style: { color: branded ? `#${cfg.hex}` : "inherit", ...style },
|
|
45
|
+
"aria-label": cfg.label,
|
|
46
|
+
role: "img",
|
|
35
47
|
children: /* @__PURE__ */ jsx("path", { d: cfg.path })
|
|
36
48
|
}
|
|
37
49
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToolIcon.esm.js","sources":["../../../src/components/ToolIcon/ToolIcon.tsx"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"ToolIcon.esm.js","sources":["../../../src/components/ToolIcon/ToolIcon.tsx"],"sourcesContent":["import type { CSSProperties } from 'react';\nimport { RiInfinityLine, RiNavigationLine } from '@remixicon/react';\nimport { siAnthropic, siGithub, siGooglegemini } from 'simple-icons';\nimport type { AiTool } from '@nospt/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 {\n tool: AiTool;\n /** Use the brand's official color. Defaults to true. */\n branded?: boolean;\n className?: string;\n style?: CSSProperties;\n /** Icon size in pixels. Defaults to 20. */\n size?: number;\n}\n\nexport function ToolIcon({ tool, branded = true, className, style, size = 20 }: ToolIconProps) {\n if (tool === 'all') {\n return (\n <RiInfinityLine\n size={size}\n className={className}\n style={{ color: 'var(--bui-fg-secondary)', ...style }}\n aria-label=\"Universal\"\n />\n );\n }\n\n if (tool === 'cursor') {\n return (\n <RiNavigationLine\n size={size}\n className={className}\n style={{ color: branded ? 'var(--bui-fg-primary)' : 'inherit', ...style }}\n aria-label=\"Cursor\"\n />\n );\n }\n\n const cfg = TOOL_ICON[tool as SvgTool];\n if (!cfg) return null;\n\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n fill=\"currentColor\"\n className={className}\n style={{ color: branded ? `#${cfg.hex}` : 'inherit', ...style }}\n aria-label={cfg.label}\n role=\"img\"\n >\n <path d={cfg.path} />\n </svg>\n );\n}\n"],"names":[],"mappings":";;;;AAOA,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;AAYO,SAAS,QAAA,CAAS,EAAE,IAAA,EAAM,OAAA,GAAU,MAAM,SAAA,EAAW,KAAA,EAAO,IAAA,GAAO,EAAA,EAAG,EAAkB;AAC7F,EAAA,IAAI,SAAS,KAAA,EAAO;AAClB,IAAA,uBACE,GAAA;AAAA,MAAC,cAAA;AAAA,MAAA;AAAA,QACC,IAAA;AAAA,QACA,SAAA;AAAA,QACA,KAAA,EAAO,EAAE,KAAA,EAAO,yBAAA,EAA2B,GAAG,KAAA,EAAM;AAAA,QACpD,YAAA,EAAW;AAAA;AAAA,KACb;AAAA,EAEJ;AAEA,EAAA,IAAI,SAAS,QAAA,EAAU;AACrB,IAAA,uBACE,GAAA;AAAA,MAAC,gBAAA;AAAA,MAAA;AAAA,QACC,IAAA;AAAA,QACA,SAAA;AAAA,QACA,OAAO,EAAE,KAAA,EAAO,UAAU,uBAAA,GAA0B,SAAA,EAAW,GAAG,KAAA,EAAM;AAAA,QACxE,YAAA,EAAW;AAAA;AAAA,KACb;AAAA,EAEJ;AAEA,EAAA,MAAM,GAAA,GAAM,UAAU,IAAe,CAAA;AACrC,EAAA,IAAI,CAAC,KAAK,OAAO,IAAA;AAEjB,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAM,4BAAA;AAAA,MACN,OAAA,EAAQ,WAAA;AAAA,MACR,KAAA,EAAO,IAAA;AAAA,MACP,MAAA,EAAQ,IAAA;AAAA,MACR,IAAA,EAAK,cAAA;AAAA,MACL,SAAA;AAAA,MACA,KAAA,EAAO,EAAE,KAAA,EAAO,OAAA,GAAU,CAAA,CAAA,EAAI,IAAI,GAAG,CAAA,CAAA,GAAK,SAAA,EAAW,GAAG,KAAA,EAAM;AAAA,MAC9D,cAAY,GAAA,CAAI,KAAA;AAAA,MAChB,IAAA,EAAK,KAAA;AAAA,MAEL,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAG,GAAA,CAAI,IAAA,EAAM;AAAA;AAAA,GACrB;AAEJ;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { AssetListFilter, AiAssetListResponse, AiAsset, AiHubProvider, AiHubStat
|
|
|
5
5
|
|
|
6
6
|
declare const devAiHubPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugin<{
|
|
7
7
|
root: _backstage_frontend_plugin_api.RouteRef<undefined>;
|
|
8
|
+
mcpConfig: _backstage_frontend_plugin_api.RouteRef<undefined>;
|
|
8
9
|
}, {}, {
|
|
9
10
|
"api:dev-ai-hub": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
10
11
|
kind: "api";
|
|
@@ -18,8 +19,12 @@ declare const devAiHubPlugin: _backstage_frontend_plugin_api.OverridableFrontend
|
|
|
18
19
|
"nav-item:dev-ai-hub": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
19
20
|
kind: "nav-item";
|
|
20
21
|
name: undefined;
|
|
21
|
-
config: {
|
|
22
|
-
|
|
22
|
+
config: {
|
|
23
|
+
title: string | undefined;
|
|
24
|
+
};
|
|
25
|
+
configInput: {
|
|
26
|
+
title?: string | undefined;
|
|
27
|
+
};
|
|
23
28
|
output: _backstage_frontend_plugin_api.ExtensionDataRef<{
|
|
24
29
|
title: string;
|
|
25
30
|
icon: _backstage_frontend_plugin_api.IconComponent;
|
|
@@ -40,8 +45,8 @@ declare const devAiHubPlugin: _backstage_frontend_plugin_api.OverridableFrontend
|
|
|
40
45
|
title: string | undefined;
|
|
41
46
|
};
|
|
42
47
|
configInput: {
|
|
43
|
-
title?: string | undefined;
|
|
44
48
|
path?: string | undefined;
|
|
49
|
+
title?: string | undefined;
|
|
45
50
|
};
|
|
46
51
|
output: _backstage_frontend_plugin_api.ExtensionDataRef<string, "core.routing.path", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.RouteRef<_backstage_frontend_plugin_api.AnyRouteRefParams>, "core.routing.ref", {
|
|
47
52
|
optional: true;
|
|
@@ -64,7 +69,6 @@ declare const devAiHubPlugin: _backstage_frontend_plugin_api.OverridableFrontend
|
|
|
64
69
|
}>;
|
|
65
70
|
};
|
|
66
71
|
params: {
|
|
67
|
-
defaultPath?: [Error: `Use the 'path' param instead`];
|
|
68
72
|
path: string;
|
|
69
73
|
title?: string;
|
|
70
74
|
icon?: _backstage_frontend_plugin_api.IconElement;
|
|
@@ -99,6 +103,7 @@ interface DevAiHubApi {
|
|
|
99
103
|
}
|
|
100
104
|
|
|
101
105
|
declare const rootRouteRef: _backstage_frontend_plugin_api.RouteRef<undefined>;
|
|
106
|
+
declare const mcpConfigRouteRef: _backstage_frontend_plugin_api.RouteRef<undefined>;
|
|
102
107
|
|
|
103
|
-
export { DevAiHubPage, devAiHubApiRef, devAiHubPlugin, rootRouteRef };
|
|
108
|
+
export { DevAiHubPage, devAiHubApiRef, devAiHubPlugin, mcpConfigRouteRef, rootRouteRef };
|
|
104
109
|
export type { DevAiHubApi };
|
package/dist/index.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { devAiHubPlugin } from './plugin.esm.js';
|
|
2
2
|
export { DevAiHubPage } from './pluginLegacy.esm.js';
|
|
3
3
|
export { devAiHubApiRef } from './api/DevAiHubClient.esm.js';
|
|
4
|
-
export { rootRouteRef } from './routes.esm.js';
|
|
4
|
+
export { mcpConfigRouteRef, rootRouteRef } from './routes.esm.js';
|
|
5
5
|
//# sourceMappingURL=index.esm.js.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
function styleInject(css, ref) {
|
|
2
|
+
if ( ref === void 0 ) ref = {};
|
|
3
|
+
var insertAt = ref.insertAt;
|
|
4
|
+
|
|
5
|
+
if (!css || typeof document === 'undefined') { return; }
|
|
6
|
+
|
|
7
|
+
var head = document.head || document.getElementsByTagName('head')[0];
|
|
8
|
+
var style = document.createElement('style');
|
|
9
|
+
style.type = 'text/css';
|
|
10
|
+
|
|
11
|
+
if (insertAt === 'top') {
|
|
12
|
+
if (head.firstChild) {
|
|
13
|
+
head.insertBefore(style, head.firstChild);
|
|
14
|
+
} else {
|
|
15
|
+
head.appendChild(style);
|
|
16
|
+
}
|
|
17
|
+
} else {
|
|
18
|
+
head.appendChild(style);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (style.styleSheet) {
|
|
22
|
+
style.styleSheet.cssText = css;
|
|
23
|
+
} else {
|
|
24
|
+
style.appendChild(document.createTextNode(css));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export { styleInject as default };
|
|
29
|
+
//# sourceMappingURL=style-inject.es.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"style-inject.es.esm.js","sources":["../../../../../../node_modules/style-inject/dist/style-inject.es.js"],"sourcesContent":["function styleInject(css, ref) {\n if ( ref === void 0 ) ref = {};\n var insertAt = ref.insertAt;\n\n if (!css || typeof document === 'undefined') { return; }\n\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n\n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild);\n } else {\n head.appendChild(style);\n }\n } else {\n head.appendChild(style);\n }\n\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n}\n\nexport default styleInject;\n"],"names":[],"mappings":"AAAA,SAAS,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE;AAC/B,EAAE,KAAK,GAAG,KAAK,MAAM,GAAG,GAAG,GAAG,EAAE;AAChC,EAAE,IAAI,QAAQ,GAAG,GAAG,CAAC,QAAQ;;AAE7B,EAAE,IAAI,CAAC,GAAG,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,EAAE,OAAO,CAAC;;AAEzD,EAAE,IAAI,IAAI,GAAG,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACtE,EAAE,IAAI,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC;AAC7C,EAAE,KAAK,CAAC,IAAI,GAAG,UAAU;;AAEzB,EAAE,IAAI,QAAQ,KAAK,KAAK,EAAE;AAC1B,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE;AACzB,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC;AAC/C,IAAI,CAAC,MAAM;AACX,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;AAC7B,IAAI;AACJ,EAAE,CAAC,MAAM;AACT,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;AAC3B,EAAE;;AAEF,EAAE,IAAI,KAAK,CAAC,UAAU,EAAE;AACxB,IAAI,KAAK,CAAC,UAAU,CAAC,OAAO,GAAG,GAAG;AAClC,EAAE,CAAC,MAAM;AACT,IAAI,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;AACnD,EAAE;AACF;;;;","x_google_ignoreList":[0]}
|
package/dist/plugin.esm.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { createFrontendPlugin, ApiBlueprint, createApiFactory, fetchApiRef, discoveryApiRef, PageBlueprint, NavItemBlueprint } from '@backstage/frontend-plugin-api';
|
|
2
|
+
import { createFrontendPlugin, ApiBlueprint, createApiFactory, fetchApiRef, discoveryApiRef, PageBlueprint, SubPageBlueprint, NavItemBlueprint } from '@backstage/frontend-plugin-api';
|
|
3
3
|
import HubIcon from '@mui/icons-material/Hub';
|
|
4
4
|
import { DevAiHubClient, devAiHubApiRef } from './api/DevAiHubClient.esm.js';
|
|
5
|
-
import { rootRouteRef } from './routes.esm.js';
|
|
5
|
+
import { mcpConfigRouteRef, rootRouteRef } from './routes.esm.js';
|
|
6
6
|
|
|
7
7
|
const devAiHubPlugin = createFrontendPlugin({
|
|
8
8
|
pluginId: "dev-ai-hub",
|
|
9
9
|
routes: {
|
|
10
|
-
root: rootRouteRef
|
|
10
|
+
root: rootRouteRef,
|
|
11
|
+
mcpConfig: mcpConfigRouteRef
|
|
11
12
|
},
|
|
12
13
|
extensions: [
|
|
13
14
|
ApiBlueprint.make({
|
|
@@ -22,10 +23,27 @@ const devAiHubPlugin = createFrontendPlugin({
|
|
|
22
23
|
PageBlueprint.make({
|
|
23
24
|
params: {
|
|
24
25
|
path: "/dev-ai-hub",
|
|
25
|
-
|
|
26
|
+
title: "Dev AI Hub",
|
|
27
|
+
routeRef: rootRouteRef
|
|
28
|
+
}
|
|
29
|
+
}),
|
|
30
|
+
SubPageBlueprint.make({
|
|
31
|
+
name: "browse",
|
|
32
|
+
params: {
|
|
33
|
+
path: "browse",
|
|
34
|
+
title: "Browse",
|
|
26
35
|
loader: () => import('./components/DevAiHubPage/index.esm.js').then((m) => /* @__PURE__ */ jsx(m.DevAiHubPage, {}))
|
|
27
36
|
}
|
|
28
37
|
}),
|
|
38
|
+
SubPageBlueprint.make({
|
|
39
|
+
name: "mcp-config",
|
|
40
|
+
params: {
|
|
41
|
+
path: "mcp-config",
|
|
42
|
+
title: "Configure MCP",
|
|
43
|
+
routeRef: mcpConfigRouteRef,
|
|
44
|
+
loader: () => import('./components/McpConfigPage/index.esm.js').then((m) => /* @__PURE__ */ jsx(m.McpConfigPage, {}))
|
|
45
|
+
}
|
|
46
|
+
}),
|
|
29
47
|
NavItemBlueprint.make({
|
|
30
48
|
params: {
|
|
31
49
|
title: "AI Hub",
|
package/dist/plugin.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.esm.js","sources":["../src/plugin.tsx"],"sourcesContent":["import {\n createFrontendPlugin,\n PageBlueprint,\n ApiBlueprint,\n NavItemBlueprint,\n createApiFactory,\n discoveryApiRef,\n fetchApiRef,\n} from '@backstage/frontend-plugin-api';\nimport HubIcon from '@mui/icons-material/Hub';\nimport { devAiHubApiRef, DevAiHubClient } from './api/DevAiHubClient';\nimport { rootRouteRef } from './routes';\n\nexport const devAiHubPlugin = createFrontendPlugin({\n pluginId: 'dev-ai-hub',\n routes: {\n root: rootRouteRef,\n },\n extensions: [\n ApiBlueprint.make({\n params: defineParams =>\n defineParams(\n createApiFactory({\n api: devAiHubApiRef,\n deps: { discoveryApi: discoveryApiRef, fetchApi: fetchApiRef },\n factory: ({ discoveryApi, fetchApi }) =>\n new DevAiHubClient(discoveryApi, fetchApi),\n }),\n ),\n }),\n PageBlueprint.make({\n params: {\n path: '/dev-ai-hub',\n routeRef: rootRouteRef,\n loader: () =>\n import('./components/DevAiHubPage').then(m => <m.DevAiHubPage />),\n },\n }),\n NavItemBlueprint.make({\n params: {\n title: 'AI Hub',\n routeRef: rootRouteRef,\n icon: HubIcon,\n },\n }),\n ],\n});\n"],"names":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"plugin.esm.js","sources":["../src/plugin.tsx"],"sourcesContent":["import {\n createFrontendPlugin,\n PageBlueprint,\n SubPageBlueprint,\n ApiBlueprint,\n NavItemBlueprint,\n createApiFactory,\n discoveryApiRef,\n fetchApiRef,\n} from '@backstage/frontend-plugin-api';\nimport HubIcon from '@mui/icons-material/Hub';\nimport { devAiHubApiRef, DevAiHubClient } from './api/DevAiHubClient';\nimport { rootRouteRef, mcpConfigRouteRef } from './routes';\n\nexport const devAiHubPlugin = createFrontendPlugin({\n pluginId: 'dev-ai-hub',\n routes: {\n root: rootRouteRef,\n mcpConfig: mcpConfigRouteRef,\n },\n extensions: [\n ApiBlueprint.make({\n params: defineParams =>\n defineParams(\n createApiFactory({\n api: devAiHubApiRef,\n deps: { discoveryApi: discoveryApiRef, fetchApi: fetchApiRef },\n factory: ({ discoveryApi, fetchApi }) =>\n new DevAiHubClient(discoveryApi, fetchApi),\n }),\n ),\n }),\n PageBlueprint.make({\n params: {\n path: '/dev-ai-hub',\n title: 'Dev AI Hub',\n routeRef: rootRouteRef,\n },\n }),\n SubPageBlueprint.make({\n name: 'browse',\n params: {\n path: 'browse',\n title: 'Browse',\n loader: () =>\n import('./components/DevAiHubPage').then(m => <m.DevAiHubPage />),\n },\n }),\n SubPageBlueprint.make({\n name: 'mcp-config',\n params: {\n path: 'mcp-config',\n title: 'Configure MCP',\n routeRef: mcpConfigRouteRef,\n loader: () =>\n import('./components/McpConfigPage').then(m => <m.McpConfigPage />),\n },\n }),\n NavItemBlueprint.make({\n params: {\n title: 'AI Hub',\n routeRef: rootRouteRef,\n icon: HubIcon,\n },\n }),\n ],\n});\n"],"names":[],"mappings":";;;;;;AAcO,MAAM,iBAAiB,oBAAA,CAAqB;AAAA,EACjD,QAAA,EAAU,YAAA;AAAA,EACV,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM,YAAA;AAAA,IACN,SAAA,EAAW;AAAA,GACb;AAAA,EACA,UAAA,EAAY;AAAA,IACV,aAAa,IAAA,CAAK;AAAA,MAChB,QAAQ,CAAA,YAAA,KACN,YAAA;AAAA,QACE,gBAAA,CAAiB;AAAA,UACf,GAAA,EAAK,cAAA;AAAA,UACL,IAAA,EAAM,EAAE,YAAA,EAAc,eAAA,EAAiB,UAAU,WAAA,EAAY;AAAA,UAC7D,OAAA,EAAS,CAAC,EAAE,YAAA,EAAc,UAAS,KACjC,IAAI,cAAA,CAAe,YAAA,EAAc,QAAQ;AAAA,SAC5C;AAAA;AACH,KACH,CAAA;AAAA,IACD,cAAc,IAAA,CAAK;AAAA,MACjB,MAAA,EAAQ;AAAA,QACN,IAAA,EAAM,aAAA;AAAA,QACN,KAAA,EAAO,YAAA;AAAA,QACP,QAAA,EAAU;AAAA;AACZ,KACD,CAAA;AAAA,IACD,iBAAiB,IAAA,CAAK;AAAA,MACpB,IAAA,EAAM,QAAA;AAAA,MACN,MAAA,EAAQ;AAAA,QACN,IAAA,EAAM,QAAA;AAAA,QACN,KAAA,EAAO,QAAA;AAAA,QACP,MAAA,EAAQ,MACN,OAAO,wCAA2B,CAAA,CAAE,IAAA,CAAK,CAAA,CAAA,qBAAK,GAAA,CAAC,CAAA,CAAE,YAAA,EAAF,EAAe,CAAE;AAAA;AACpE,KACD,CAAA;AAAA,IACD,iBAAiB,IAAA,CAAK;AAAA,MACpB,IAAA,EAAM,YAAA;AAAA,MACN,MAAA,EAAQ;AAAA,QACN,IAAA,EAAM,YAAA;AAAA,QACN,KAAA,EAAO,eAAA;AAAA,QACP,QAAA,EAAU,iBAAA;AAAA,QACV,MAAA,EAAQ,MACN,OAAO,yCAA4B,CAAA,CAAE,IAAA,CAAK,CAAA,CAAA,qBAAK,GAAA,CAAC,CAAA,CAAE,aAAA,EAAF,EAAgB,CAAE;AAAA;AACtE,KACD,CAAA;AAAA,IACD,iBAAiB,IAAA,CAAK;AAAA,MACpB,MAAA,EAAQ;AAAA,QACN,KAAA,EAAO,QAAA;AAAA,QACP,QAAA,EAAU,YAAA;AAAA,QACV,IAAA,EAAM;AAAA;AACR,KACD;AAAA;AAEL,CAAC;;;;"}
|
package/dist/routes.esm.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createRouteRef } from '@backstage/frontend-plugin-api';
|
|
2
2
|
|
|
3
3
|
const rootRouteRef = createRouteRef();
|
|
4
|
+
const mcpConfigRouteRef = createRouteRef();
|
|
4
5
|
|
|
5
|
-
export { rootRouteRef };
|
|
6
|
+
export { mcpConfigRouteRef, rootRouteRef };
|
|
6
7
|
//# sourceMappingURL=routes.esm.js.map
|
package/dist/routes.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.esm.js","sources":["../src/routes.ts"],"sourcesContent":["import { createRouteRef } from '@backstage/frontend-plugin-api';\n\nexport const rootRouteRef = createRouteRef();\n"],"names":[],"mappings":";;AAEO,MAAM,eAAe,cAAA;;;;"}
|
|
1
|
+
{"version":3,"file":"routes.esm.js","sources":["../src/routes.ts"],"sourcesContent":["import { createRouteRef } from '@backstage/frontend-plugin-api';\n\nexport const rootRouteRef = createRouteRef();\nexport const mcpConfigRouteRef = createRouteRef();\n"],"names":[],"mappings":";;AAEO,MAAM,eAAe,cAAA;AACrB,MAAM,oBAAoB,cAAA;;;;"}
|
package/package.json
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nospt/plugin-dev-ai-hub",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Frontend plugin for Dev AI Hub",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "./dist/index.esm.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/nosportugal/backstage-plugin-dev-ai-hub"
|
|
11
|
+
},
|
|
8
12
|
"publishConfig": {
|
|
9
13
|
"access": "public"
|
|
10
14
|
},
|
|
@@ -41,35 +45,41 @@
|
|
|
41
45
|
"lint": "backstage-cli package lint",
|
|
42
46
|
"prepack": "backstage-cli package prepack",
|
|
43
47
|
"postpack": "backstage-cli package postpack",
|
|
44
|
-
"test": "backstage-cli package test --passWithNoTests",
|
|
48
|
+
"test": "backstage-cli package test --passWithNoTests --watchAll=false",
|
|
49
|
+
"test:e2e": "playwright test",
|
|
50
|
+
"test:e2e:ui": "playwright test --ui",
|
|
51
|
+
"test:e2e:debug": "playwright test --debug",
|
|
45
52
|
"tsc": "tsc --noEmit"
|
|
46
53
|
},
|
|
47
54
|
"dependencies": {
|
|
48
|
-
"@backstage/core-components": "
|
|
49
|
-
"@backstage/core-plugin-api": "
|
|
50
|
-
"@backstage/frontend-plugin-api": "
|
|
55
|
+
"@backstage/core-components": "^0.18.9",
|
|
56
|
+
"@backstage/core-plugin-api": "^1.12.5",
|
|
57
|
+
"@backstage/frontend-plugin-api": "^0.16.2",
|
|
58
|
+
"@backstage/ui": "^0.14.3",
|
|
51
59
|
"@mui/icons-material": "^5.15.0",
|
|
52
60
|
"@mui/material": "^5.15.0",
|
|
53
|
-
"@nospt/plugin-dev-ai-hub-common": "
|
|
61
|
+
"@nospt/plugin-dev-ai-hub-common": "^0.2.0",
|
|
62
|
+
"@remixicon/react": "^4.6.0",
|
|
54
63
|
"react-markdown": "^9.0.0",
|
|
55
64
|
"react-syntax-highlighter": "^16.1.1",
|
|
56
65
|
"remark-gfm": "^4.0.1",
|
|
57
66
|
"simple-icons": "^13.0.0"
|
|
58
67
|
},
|
|
59
68
|
"devDependencies": {
|
|
60
|
-
"@backstage/cli": "
|
|
61
|
-
"@backstage/dev-utils": "
|
|
62
|
-
"@
|
|
69
|
+
"@backstage/cli": "^0.36.1",
|
|
70
|
+
"@backstage/dev-utils": "^1.1.22",
|
|
71
|
+
"@playwright/test": "^1.60.0",
|
|
72
|
+
"@testing-library/dom": "^10.0.0",
|
|
63
73
|
"@testing-library/jest-dom": "^6.0.0",
|
|
64
|
-
"@testing-library/react": "^
|
|
65
|
-
"@types/jest": "^
|
|
74
|
+
"@testing-library/react": "^16.3.1",
|
|
75
|
+
"@types/jest": "^30.0.0",
|
|
66
76
|
"@types/react": "^18.0.0",
|
|
67
77
|
"@types/react-syntax-highlighter": "^15.0.0",
|
|
68
|
-
"jest": "^
|
|
69
|
-
"
|
|
78
|
+
"jest": "^30.2.0",
|
|
79
|
+
"jsdom": "^27.1.0",
|
|
70
80
|
"react": "^18.0.0",
|
|
71
81
|
"react-dom": "^18.0.0",
|
|
72
|
-
"react-router-dom": "^6.
|
|
82
|
+
"react-router-dom": "^6.30.2"
|
|
73
83
|
},
|
|
74
84
|
"peerDependencies": {
|
|
75
85
|
"react": "^18.0.0",
|