@julianpedro/plugin-dev-ai-hub 0.2.0 → 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.
- package/dist/api/DevAiHubClient.esm.js +10 -2
- package/dist/api/DevAiHubClient.esm.js.map +1 -1
- package/dist/components/AssetCard/AssetCard.esm.js +85 -13
- package/dist/components/AssetCard/AssetCard.esm.js.map +1 -1
- package/dist/components/AssetDetailPanel/AssetDetailPanel.esm.js +272 -85
- package/dist/components/AssetDetailPanel/AssetDetailPanel.esm.js.map +1 -1
- package/dist/components/AssetFilters/AssetFilters.esm.js +103 -44
- package/dist/components/AssetFilters/AssetFilters.esm.js.map +1 -1
- package/dist/components/AssetHelpDialog/AssetHelpDialog.esm.js +87 -0
- package/dist/components/AssetHelpDialog/AssetHelpDialog.esm.js.map +1 -0
- package/dist/components/AssetInstallDialog/AssetInstallDialog.esm.js +328 -108
- package/dist/components/AssetInstallDialog/AssetInstallDialog.esm.js.map +1 -1
- package/dist/components/DevAiHubPage/DevAiHubPage.esm.js +93 -44
- package/dist/components/DevAiHubPage/DevAiHubPage.esm.js.map +1 -1
- package/dist/components/McpConfigDialog/McpConfigDialog.esm.js +535 -234
- package/dist/components/McpConfigDialog/McpConfigDialog.esm.js.map +1 -1
- package/dist/components/ToolIcon/ToolIcon.esm.js +4 -1
- package/dist/components/ToolIcon/ToolIcon.esm.js.map +1 -1
- package/dist/hooks/index.esm.js +15 -1
- package/dist/hooks/index.esm.js.map +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.esm.js +1 -0
- package/dist/index.esm.js.map +1 -1
- package/dist/locales/es.esm.js +112 -0
- package/dist/locales/es.esm.js.map +1 -0
- package/dist/locales/pt-BR.esm.js +112 -0
- package/dist/locales/pt-BR.esm.js.map +1 -0
- package/dist/translation.esm.js +135 -0
- package/dist/translation.esm.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import ReactMarkdown from 'react-markdown';
|
|
3
|
+
import remarkGfm from 'remark-gfm';
|
|
4
|
+
import Box from '@mui/material/Box';
|
|
5
|
+
import Button from '@mui/material/Button';
|
|
6
|
+
import Dialog from '@mui/material/Dialog';
|
|
7
|
+
import DialogActions from '@mui/material/DialogActions';
|
|
8
|
+
import DialogContent from '@mui/material/DialogContent';
|
|
9
|
+
import DialogTitle from '@mui/material/DialogTitle';
|
|
10
|
+
import IconButton from '@mui/material/IconButton';
|
|
11
|
+
import Typography from '@mui/material/Typography';
|
|
12
|
+
import CloseIcon from '@mui/icons-material/Close';
|
|
13
|
+
import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
|
|
14
|
+
import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
|
|
15
|
+
import { devAiHubTranslationRef } from '../../translation.esm.js';
|
|
16
|
+
|
|
17
|
+
function AssetHelpDialog({ asset, onClose }) {
|
|
18
|
+
const { t } = useTranslationRef(devAiHubTranslationRef);
|
|
19
|
+
return /* @__PURE__ */ jsxs(Dialog, { open: !!asset, onClose, maxWidth: "md", fullWidth: true, children: [
|
|
20
|
+
/* @__PURE__ */ jsxs(DialogTitle, { sx: { display: "flex", alignItems: "center", gap: 1, pr: 6 }, children: [
|
|
21
|
+
/* @__PURE__ */ jsx(HelpOutlineIcon, { sx: { color: "text.secondary", fontSize: "1.3rem", flexShrink: 0 } }),
|
|
22
|
+
/* @__PURE__ */ jsxs(Box, { sx: { flex: 1, minWidth: 0 }, children: [
|
|
23
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h6", fontWeight: 700, noWrap: true, children: asset?.label ?? asset?.name ?? "" }),
|
|
24
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", sx: { fontWeight: 400 }, children: t("assetCard.helpTooltip") })
|
|
25
|
+
] }),
|
|
26
|
+
/* @__PURE__ */ jsx(
|
|
27
|
+
IconButton,
|
|
28
|
+
{
|
|
29
|
+
size: "small",
|
|
30
|
+
onClick: onClose,
|
|
31
|
+
sx: { position: "absolute", right: 12, top: 12 },
|
|
32
|
+
children: /* @__PURE__ */ jsx(CloseIcon, { fontSize: "small" })
|
|
33
|
+
}
|
|
34
|
+
)
|
|
35
|
+
] }),
|
|
36
|
+
/* @__PURE__ */ jsx(DialogContent, { dividers: true, children: /* @__PURE__ */ jsx(
|
|
37
|
+
Box,
|
|
38
|
+
{
|
|
39
|
+
sx: {
|
|
40
|
+
"& h1,h2,h3,h4,h5,h6": { mt: 2, mb: 1, fontWeight: 700 },
|
|
41
|
+
"& h1": { mt: 0 },
|
|
42
|
+
"& p": { mb: 1, lineHeight: 1.7 },
|
|
43
|
+
"& ul, & ol": { pl: 2.5, mb: 1 },
|
|
44
|
+
"& li": { mb: 0.5 },
|
|
45
|
+
"& blockquote": {
|
|
46
|
+
borderLeft: "3px solid",
|
|
47
|
+
borderColor: "primary.main",
|
|
48
|
+
pl: 1.5,
|
|
49
|
+
color: "text.secondary",
|
|
50
|
+
my: 1,
|
|
51
|
+
ml: 0
|
|
52
|
+
},
|
|
53
|
+
"& table": { width: "100%", borderCollapse: "collapse", mb: 1 },
|
|
54
|
+
"& th, & td": {
|
|
55
|
+
border: "1px solid",
|
|
56
|
+
borderColor: "divider",
|
|
57
|
+
px: 1.5,
|
|
58
|
+
py: 0.75,
|
|
59
|
+
fontSize: "0.875rem"
|
|
60
|
+
},
|
|
61
|
+
"& th": { backgroundColor: "action.hover", fontWeight: 700 },
|
|
62
|
+
"& code": {
|
|
63
|
+
bgcolor: "action.hover",
|
|
64
|
+
px: 0.5,
|
|
65
|
+
py: 0.2,
|
|
66
|
+
borderRadius: 0.5,
|
|
67
|
+
fontFamily: "monospace",
|
|
68
|
+
fontSize: "0.875em"
|
|
69
|
+
},
|
|
70
|
+
"& pre": {
|
|
71
|
+
bgcolor: "action.hover",
|
|
72
|
+
borderRadius: 1,
|
|
73
|
+
p: 1.5,
|
|
74
|
+
overflow: "auto",
|
|
75
|
+
my: 1,
|
|
76
|
+
"& code": { bgcolor: "transparent", px: 0, py: 0 }
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
children: /* @__PURE__ */ jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], children: asset?.helpText ?? "" })
|
|
80
|
+
}
|
|
81
|
+
) }),
|
|
82
|
+
/* @__PURE__ */ jsx(DialogActions, { sx: { px: 2, py: 1.5 }, children: /* @__PURE__ */ jsx(Button, { onClick: onClose, sx: { ml: "auto" }, children: t("assetInstallDialog.close") }) })
|
|
83
|
+
] });
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export { AssetHelpDialog };
|
|
87
|
+
//# sourceMappingURL=AssetHelpDialog.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssetHelpDialog.esm.js","sources":["../../../src/components/AssetHelpDialog/AssetHelpDialog.tsx"],"sourcesContent":["import ReactMarkdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\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 IconButton from '@mui/material/IconButton';\nimport Typography from '@mui/material/Typography';\nimport CloseIcon from '@mui/icons-material/Close';\nimport HelpOutlineIcon from '@mui/icons-material/HelpOutline';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport type { AiAssetSummary } from '@julianpedro/plugin-dev-ai-hub-common';\nimport { devAiHubTranslationRef } from '../../translation';\n\ninterface AssetHelpDialogProps {\n asset: AiAssetSummary | null;\n onClose: () => void;\n}\n\nexport function AssetHelpDialog({ asset, onClose }: AssetHelpDialogProps) {\n const { t } = useTranslationRef(devAiHubTranslationRef);\n\n return (\n <Dialog open={!!asset} onClose={onClose} maxWidth=\"md\" fullWidth>\n <DialogTitle sx={{ display: 'flex', alignItems: 'center', gap: 1, pr: 6 }}>\n <HelpOutlineIcon sx={{ color: 'text.secondary', fontSize: '1.3rem', flexShrink: 0 }} />\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Typography variant=\"h6\" fontWeight={700} noWrap>\n {asset?.label ?? asset?.name ?? ''}\n </Typography>\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ fontWeight: 400 }}>\n {t('assetCard.helpTooltip')}\n </Typography>\n </Box>\n <IconButton\n size=\"small\"\n onClick={onClose}\n sx={{ position: 'absolute', right: 12, top: 12 }}\n >\n <CloseIcon fontSize=\"small\" />\n </IconButton>\n </DialogTitle>\n\n <DialogContent dividers>\n <Box\n sx={{\n '& h1,h2,h3,h4,h5,h6': { mt: 2, mb: 1, fontWeight: 700 },\n '& h1': { mt: 0 },\n '& p': { mb: 1, lineHeight: 1.7 },\n '& ul, & ol': { pl: 2.5, mb: 1 },\n '& li': { mb: 0.5 },\n '& blockquote': {\n borderLeft: '3px solid',\n borderColor: 'primary.main',\n pl: 1.5,\n color: 'text.secondary',\n my: 1,\n ml: 0,\n },\n '& table': { width: '100%', borderCollapse: 'collapse', mb: 1 },\n '& th, & td': {\n border: '1px solid',\n borderColor: 'divider',\n px: 1.5,\n py: 0.75,\n fontSize: '0.875rem',\n },\n '& th': { backgroundColor: 'action.hover', fontWeight: 700 },\n '& code': {\n bgcolor: 'action.hover',\n px: 0.5,\n py: 0.2,\n borderRadius: 0.5,\n fontFamily: 'monospace',\n fontSize: '0.875em',\n },\n '& pre': {\n bgcolor: 'action.hover',\n borderRadius: 1,\n p: 1.5,\n overflow: 'auto',\n my: 1,\n '& code': { bgcolor: 'transparent', px: 0, py: 0 },\n },\n }}\n >\n <ReactMarkdown remarkPlugins={[remarkGfm]}>\n {asset?.helpText ?? ''}\n </ReactMarkdown>\n </Box>\n </DialogContent>\n\n <DialogActions sx={{ px: 2, py: 1.5 }}>\n <Button onClick={onClose} sx={{ ml: 'auto' }}>\n {t('assetInstallDialog.close')}\n </Button>\n </DialogActions>\n </Dialog>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,24 +1,31 @@
|
|
|
1
|
-
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
1
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import Box from '@mui/material/Box';
|
|
4
|
-
import Chip from '@mui/material/Chip';
|
|
5
4
|
import Button from '@mui/material/Button';
|
|
5
|
+
import Chip from '@mui/material/Chip';
|
|
6
6
|
import CircularProgress from '@mui/material/CircularProgress';
|
|
7
7
|
import Dialog from '@mui/material/Dialog';
|
|
8
8
|
import DialogActions from '@mui/material/DialogActions';
|
|
9
9
|
import DialogContent from '@mui/material/DialogContent';
|
|
10
10
|
import DialogTitle from '@mui/material/DialogTitle';
|
|
11
|
+
import LinearProgress from '@mui/material/LinearProgress';
|
|
11
12
|
import Tooltip from '@mui/material/Tooltip';
|
|
12
13
|
import Typography from '@mui/material/Typography';
|
|
13
14
|
import ContentCopyIcon from '@mui/icons-material/ContentCopy';
|
|
14
15
|
import DownloadIcon from '@mui/icons-material/Download';
|
|
15
16
|
import CheckIcon from '@mui/icons-material/Check';
|
|
16
17
|
import FolderZipIcon from '@mui/icons-material/FolderZip';
|
|
18
|
+
import OpenInBrowserIcon from '@mui/icons-material/OpenInBrowser';
|
|
19
|
+
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
|
|
20
|
+
import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
|
|
21
|
+
import Inventory2Icon from '@mui/icons-material/Inventory2';
|
|
17
22
|
import { getInstallPathsForAsset } from '@julianpedro/plugin-dev-ai-hub-common';
|
|
18
|
-
import { useApi } from '@backstage/core-plugin-api';
|
|
23
|
+
import { useApi, discoveryApiRef } from '@backstage/core-plugin-api';
|
|
24
|
+
import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
|
|
19
25
|
import { devAiHubApiRef } from '../../api/DevAiHubClient.esm.js';
|
|
20
26
|
import { useAssetDetail } from '../../hooks/index.esm.js';
|
|
21
27
|
import { ToolIcon } from '../ToolIcon/ToolIcon.esm.js';
|
|
28
|
+
import { devAiHubTranslationRef } from '../../translation.esm.js';
|
|
22
29
|
|
|
23
30
|
const TOOL_LABELS = {
|
|
24
31
|
"claude-code": "Claude Code",
|
|
@@ -26,16 +33,31 @@ const TOOL_LABELS = {
|
|
|
26
33
|
"google-gemini": "Google Gemini",
|
|
27
34
|
"cursor": "Cursor"
|
|
28
35
|
};
|
|
29
|
-
function
|
|
36
|
+
function canUseVscodeDeepLink(type, tools, installPath) {
|
|
37
|
+
if (type !== "agent" && type !== "instruction") return false;
|
|
38
|
+
if (!tools.includes("github-copilot")) return false;
|
|
39
|
+
if (installPath && !installPath.startsWith(".github/")) return false;
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
function buildVscodeRedirectUrl(asset, backendUrl) {
|
|
43
|
+
const safeName = (asset.label ?? asset.name).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
44
|
+
const filename = asset.type === "instruction" ? `${safeName}.instructions.md` : `${safeName}.agent.md`;
|
|
45
|
+
const fileUrl = `${backendUrl}/assets/${encodeURIComponent(asset.id)}/agent-md/${filename}`;
|
|
46
|
+
const vscodeUri = `vscode:chat-agent/install?url=${encodeURIComponent(fileUrl)}`;
|
|
47
|
+
return `https://vscode.dev/redirect?url=${encodeURIComponent(vscodeUri)}`;
|
|
48
|
+
}
|
|
49
|
+
function SingleAssetView({ asset }) {
|
|
30
50
|
const [copiedTool, setCopiedTool] = useState(null);
|
|
31
51
|
const api = useApi(devAiHubApiRef);
|
|
32
|
-
const
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
52
|
+
const discoveryApi = useApi(discoveryApiRef);
|
|
53
|
+
const { t } = useTranslationRef(devAiHubTranslationRef);
|
|
54
|
+
const resourcePaths = asset.resourcesContent ? Object.keys(asset.resourcesContent) : [];
|
|
55
|
+
const isZipSkill = asset.type === "skill" && resourcePaths.length > 0;
|
|
56
|
+
const installPaths = getInstallPathsForAsset(asset.type, asset.tools, asset.name, {
|
|
57
|
+
installPath: asset.installPath,
|
|
58
|
+
installPaths: asset.installPaths
|
|
59
|
+
});
|
|
37
60
|
const handleCopy = (tool) => {
|
|
38
|
-
if (!asset) return;
|
|
39
61
|
navigator.clipboard.writeText(asset.content).then(() => {
|
|
40
62
|
setCopiedTool(tool);
|
|
41
63
|
setTimeout(() => setCopiedTool(null), 2e3);
|
|
@@ -43,10 +65,7 @@ function AssetInstallDialog({ assetId, onClose }) {
|
|
|
43
65
|
api.trackInstall(asset.id).catch(() => {
|
|
44
66
|
});
|
|
45
67
|
};
|
|
46
|
-
const resourcePaths = asset?.resourcesContent ? Object.keys(asset.resourcesContent) : [];
|
|
47
|
-
const isZipSkill = asset?.type === "skill" && resourcePaths.length > 0;
|
|
48
68
|
const handleDownload = async (_tool, installPath) => {
|
|
49
|
-
if (!asset) return;
|
|
50
69
|
if (isZipSkill) {
|
|
51
70
|
const url = await api.getDownloadUrl(asset.id);
|
|
52
71
|
const a = document.createElement("a");
|
|
@@ -66,98 +85,86 @@ function AssetInstallDialog({ assetId, onClose }) {
|
|
|
66
85
|
api.trackInstall(asset.id).catch(() => {
|
|
67
86
|
});
|
|
68
87
|
};
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
/* @__PURE__ */
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
/* @__PURE__ */
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
] }),
|
|
139
|
-
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "text.secondary", sx: { display: "block", mb: 0.5 }, children: "Install path" }),
|
|
140
|
-
/* @__PURE__ */ jsx(
|
|
141
|
-
Box,
|
|
88
|
+
const handleInstallInVscode = async () => {
|
|
89
|
+
const backendUrl = await discoveryApi.getBaseUrl("dev-ai-hub");
|
|
90
|
+
const a = document.createElement("a");
|
|
91
|
+
a.href = buildVscodeRedirectUrl(asset, backendUrl);
|
|
92
|
+
a.target = "_blank";
|
|
93
|
+
a.rel = "noopener noreferrer";
|
|
94
|
+
document.body.appendChild(a);
|
|
95
|
+
a.click();
|
|
96
|
+
document.body.removeChild(a);
|
|
97
|
+
api.trackInstall(asset.id).catch(() => {
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
const showVscodeButton = canUseVscodeDeepLink(asset.type, asset.tools, installPaths["github-copilot"]);
|
|
101
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
102
|
+
isZipSkill && /* @__PURE__ */ jsxs(
|
|
103
|
+
Box,
|
|
104
|
+
{
|
|
105
|
+
sx: {
|
|
106
|
+
border: "1px solid",
|
|
107
|
+
borderColor: "info.main",
|
|
108
|
+
borderRadius: 2,
|
|
109
|
+
p: 1.5,
|
|
110
|
+
bgcolor: (theme) => `${theme.palette.info.main}12`,
|
|
111
|
+
mb: 0.5
|
|
112
|
+
},
|
|
113
|
+
children: [
|
|
114
|
+
/* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1, mb: 1 }, children: [
|
|
115
|
+
/* @__PURE__ */ jsx(FolderZipIcon, { sx: { fontSize: "1rem", color: "info.main" } }),
|
|
116
|
+
/* @__PURE__ */ jsx(Typography, { variant: "subtitle2", fontWeight: 700, color: "info.main", children: t("assetInstallDialog.bundledSkillTitle") })
|
|
117
|
+
] }),
|
|
118
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "text.secondary", sx: { display: "block", mb: 1 }, children: t("assetInstallDialog.bundledSkillDescription") }),
|
|
119
|
+
/* @__PURE__ */ jsxs(Box, { sx: { display: "flex", gap: 0.5, flexWrap: "wrap" }, children: [
|
|
120
|
+
/* @__PURE__ */ jsx(Chip, { label: "SKILL.md", size: "small", sx: { fontFamily: "monospace", fontSize: "0.7rem", height: 20 } }),
|
|
121
|
+
resourcePaths.map((p) => /* @__PURE__ */ jsx(Chip, { label: p, size: "small", variant: "outlined", sx: { fontFamily: "monospace", fontSize: "0.7rem", height: 20 } }, p))
|
|
122
|
+
] })
|
|
123
|
+
]
|
|
124
|
+
}
|
|
125
|
+
),
|
|
126
|
+
Object.entries(installPaths).map(([tool, installPath]) => /* @__PURE__ */ jsxs(
|
|
127
|
+
Box,
|
|
128
|
+
{
|
|
129
|
+
sx: { border: "1px solid", borderColor: "divider", borderRadius: 2, p: 1.5 },
|
|
130
|
+
children: [
|
|
131
|
+
/* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1, mb: 1 }, children: [
|
|
132
|
+
/* @__PURE__ */ jsx(ToolIcon, { tool, sx: { fontSize: "1rem" } }),
|
|
133
|
+
/* @__PURE__ */ jsx(Typography, { variant: "subtitle2", fontWeight: 700, children: TOOL_LABELS[tool] ?? tool })
|
|
134
|
+
] }),
|
|
135
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "text.secondary", sx: { display: "block", mb: 0.5 }, children: t("assetInstallDialog.installPathLabel") }),
|
|
136
|
+
/* @__PURE__ */ jsx(
|
|
137
|
+
Box,
|
|
138
|
+
{
|
|
139
|
+
sx: {
|
|
140
|
+
bgcolor: "action.hover",
|
|
141
|
+
border: "1px solid",
|
|
142
|
+
borderColor: "divider",
|
|
143
|
+
borderRadius: 1,
|
|
144
|
+
px: 1.5,
|
|
145
|
+
py: 0.75,
|
|
146
|
+
fontFamily: "monospace",
|
|
147
|
+
fontSize: "0.78rem",
|
|
148
|
+
wordBreak: "break-all",
|
|
149
|
+
mb: 1.25
|
|
150
|
+
},
|
|
151
|
+
children: installPath
|
|
152
|
+
}
|
|
153
|
+
),
|
|
154
|
+
/* @__PURE__ */ jsxs(Box, { sx: { display: "flex", flexDirection: "column", gap: 0.75 }, children: [
|
|
155
|
+
showVscodeButton && tool === "github-copilot" && /* @__PURE__ */ jsx(
|
|
156
|
+
Button,
|
|
142
157
|
{
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
py: 0.75,
|
|
150
|
-
fontFamily: "monospace",
|
|
151
|
-
fontSize: "0.78rem",
|
|
152
|
-
color: "text.primary",
|
|
153
|
-
wordBreak: "break-all",
|
|
154
|
-
mb: 1.25
|
|
155
|
-
},
|
|
156
|
-
children: installPath
|
|
158
|
+
size: "small",
|
|
159
|
+
variant: "contained",
|
|
160
|
+
startIcon: /* @__PURE__ */ jsx(OpenInBrowserIcon, {}),
|
|
161
|
+
onClick: handleInstallInVscode,
|
|
162
|
+
fullWidth: true,
|
|
163
|
+
children: t("assetInstallDialog.installInVscode")
|
|
157
164
|
}
|
|
158
165
|
),
|
|
159
166
|
/* @__PURE__ */ jsxs(Box, { sx: { display: "flex", gap: 1 }, children: [
|
|
160
|
-
/* @__PURE__ */ jsx(Tooltip, { title: copiedTool === tool ? "
|
|
167
|
+
/* @__PURE__ */ jsx(Tooltip, { title: copiedTool === tool ? t("assetInstallDialog.copied") : t("assetInstallDialog.copyTooltip"), children: /* @__PURE__ */ jsx(
|
|
161
168
|
Button,
|
|
162
169
|
{
|
|
163
170
|
size: "small",
|
|
@@ -166,10 +173,10 @@ function AssetInstallDialog({ assetId, onClose }) {
|
|
|
166
173
|
onClick: () => handleCopy(tool),
|
|
167
174
|
color: copiedTool === tool ? "success" : "primary",
|
|
168
175
|
sx: { flex: 1 },
|
|
169
|
-
children: copiedTool === tool ? "
|
|
176
|
+
children: copiedTool === tool ? t("assetInstallDialog.copied") : t("assetInstallDialog.copyContent")
|
|
170
177
|
}
|
|
171
178
|
) }),
|
|
172
|
-
/* @__PURE__ */ jsx(Tooltip, { title: isZipSkill ? "
|
|
179
|
+
/* @__PURE__ */ jsx(Tooltip, { title: isZipSkill ? t("assetInstallDialog.downloadZipTooltip") : t("assetInstallDialog.downloadTooltip"), children: /* @__PURE__ */ jsx(
|
|
173
180
|
Button,
|
|
174
181
|
{
|
|
175
182
|
size: "small",
|
|
@@ -177,16 +184,229 @@ function AssetInstallDialog({ assetId, onClose }) {
|
|
|
177
184
|
startIcon: isZipSkill ? /* @__PURE__ */ jsx(FolderZipIcon, {}) : /* @__PURE__ */ jsx(DownloadIcon, {}),
|
|
178
185
|
onClick: () => handleDownload(tool, installPath),
|
|
179
186
|
sx: { flex: 1 },
|
|
180
|
-
children: isZipSkill ? "
|
|
187
|
+
children: isZipSkill ? t("assetInstallDialog.downloadZip") : t("assetInstallDialog.download")
|
|
181
188
|
}
|
|
182
189
|
) })
|
|
183
190
|
] })
|
|
184
|
-
]
|
|
191
|
+
] })
|
|
192
|
+
]
|
|
193
|
+
},
|
|
194
|
+
tool
|
|
195
|
+
))
|
|
196
|
+
] });
|
|
197
|
+
}
|
|
198
|
+
function BundleItemStep({ item, stepIndex, total }) {
|
|
199
|
+
const [copied, setCopied] = useState(false);
|
|
200
|
+
const api = useApi(devAiHubApiRef);
|
|
201
|
+
const discoveryApi = useApi(discoveryApiRef);
|
|
202
|
+
const { asset, loading } = useAssetDetail(item.assetId ?? null);
|
|
203
|
+
const { t } = useTranslationRef(devAiHubTranslationRef);
|
|
204
|
+
const installPaths = asset ? getInstallPathsForAsset(asset.type, asset.tools, asset.name, {
|
|
205
|
+
installPath: asset.installPath,
|
|
206
|
+
installPaths: asset.installPaths
|
|
207
|
+
}) : {};
|
|
208
|
+
const firstInstallPath = Object.values(installPaths)[0];
|
|
209
|
+
const handleCopy = () => {
|
|
210
|
+
if (!asset) return;
|
|
211
|
+
navigator.clipboard.writeText(asset.content).then(() => {
|
|
212
|
+
setCopied(true);
|
|
213
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
214
|
+
});
|
|
215
|
+
api.trackInstall(asset.id).catch(() => {
|
|
216
|
+
});
|
|
217
|
+
};
|
|
218
|
+
const handleDownload = async () => {
|
|
219
|
+
if (!asset) return;
|
|
220
|
+
const filename = firstInstallPath?.split("/").pop() ?? `${asset.name}.md`;
|
|
221
|
+
const blob = new Blob([asset.content], { type: "text/markdown" });
|
|
222
|
+
const url = URL.createObjectURL(blob);
|
|
223
|
+
const a = document.createElement("a");
|
|
224
|
+
a.href = url;
|
|
225
|
+
a.download = filename;
|
|
226
|
+
a.click();
|
|
227
|
+
URL.revokeObjectURL(url);
|
|
228
|
+
api.trackInstall(asset.id).catch(() => {
|
|
229
|
+
});
|
|
230
|
+
};
|
|
231
|
+
const handleInstallInVscode = async () => {
|
|
232
|
+
if (!asset) return;
|
|
233
|
+
const backendUrl = await discoveryApi.getBaseUrl("dev-ai-hub");
|
|
234
|
+
const a = document.createElement("a");
|
|
235
|
+
a.href = buildVscodeRedirectUrl(asset, backendUrl);
|
|
236
|
+
a.target = "_blank";
|
|
237
|
+
a.rel = "noopener noreferrer";
|
|
238
|
+
document.body.appendChild(a);
|
|
239
|
+
a.click();
|
|
240
|
+
document.body.removeChild(a);
|
|
241
|
+
api.trackInstall(asset.id).catch(() => {
|
|
242
|
+
});
|
|
243
|
+
};
|
|
244
|
+
const showVscodeButton = asset && canUseVscodeDeepLink(asset.type, asset.tools, installPaths["github-copilot"]);
|
|
245
|
+
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
246
|
+
/* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1, mb: 1.5 }, children: [
|
|
247
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "text.secondary", children: t("assetInstallDialog.stepProgress", { current: stepIndex + 1, total }) }),
|
|
248
|
+
item.type && /* @__PURE__ */ jsx(Chip, { label: item.type, size: "small", variant: "outlined", sx: { height: 20, fontSize: "0.65rem" } })
|
|
249
|
+
] }),
|
|
250
|
+
/* @__PURE__ */ jsx(Typography, { variant: "subtitle1", fontWeight: 700, sx: { mb: 0.25 }, children: item.label ?? item.name ?? item.ref }),
|
|
251
|
+
item.description && /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", sx: { mb: 1.5 }, children: item.description }),
|
|
252
|
+
loading && /* @__PURE__ */ jsx(Box, { sx: { display: "flex", justifyContent: "center", py: 2 }, children: /* @__PURE__ */ jsx(CircularProgress, { size: 24 }) }),
|
|
253
|
+
!loading && !item.assetId && /* @__PURE__ */ jsxs(
|
|
254
|
+
Box,
|
|
255
|
+
{
|
|
256
|
+
sx: {
|
|
257
|
+
border: "1px dashed",
|
|
258
|
+
borderColor: "warning.main",
|
|
259
|
+
borderRadius: 2,
|
|
260
|
+
p: 1.5,
|
|
261
|
+
bgcolor: (theme) => `${theme.palette.warning.main}10`
|
|
185
262
|
},
|
|
186
|
-
|
|
187
|
-
|
|
263
|
+
children: [
|
|
264
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", color: "warning.main", fontWeight: 600, children: t("assetInstallDialog.notSyncedTitle") }),
|
|
265
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "text.secondary", children: t("assetInstallDialog.notSyncedRef", { ref: item.ref }) })
|
|
266
|
+
]
|
|
267
|
+
}
|
|
268
|
+
),
|
|
269
|
+
!loading && asset && /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", flexDirection: "column", gap: 1 }, children: [
|
|
270
|
+
firstInstallPath && /* @__PURE__ */ jsx(
|
|
271
|
+
Box,
|
|
272
|
+
{
|
|
273
|
+
sx: {
|
|
274
|
+
bgcolor: "action.hover",
|
|
275
|
+
border: "1px solid",
|
|
276
|
+
borderColor: "divider",
|
|
277
|
+
borderRadius: 1,
|
|
278
|
+
px: 1.5,
|
|
279
|
+
py: 0.75,
|
|
280
|
+
fontFamily: "monospace",
|
|
281
|
+
fontSize: "0.78rem",
|
|
282
|
+
wordBreak: "break-all"
|
|
283
|
+
},
|
|
284
|
+
children: firstInstallPath
|
|
285
|
+
}
|
|
286
|
+
),
|
|
287
|
+
showVscodeButton && /* @__PURE__ */ jsx(
|
|
288
|
+
Button,
|
|
289
|
+
{
|
|
290
|
+
size: "small",
|
|
291
|
+
variant: "contained",
|
|
292
|
+
startIcon: /* @__PURE__ */ jsx(OpenInBrowserIcon, {}),
|
|
293
|
+
onClick: handleInstallInVscode,
|
|
294
|
+
fullWidth: true,
|
|
295
|
+
children: t("assetInstallDialog.installInVscode")
|
|
296
|
+
}
|
|
297
|
+
),
|
|
298
|
+
/* @__PURE__ */ jsxs(Box, { sx: { display: "flex", gap: 1 }, children: [
|
|
299
|
+
/* @__PURE__ */ jsx(
|
|
300
|
+
Button,
|
|
301
|
+
{
|
|
302
|
+
size: "small",
|
|
303
|
+
variant: "outlined",
|
|
304
|
+
startIcon: copied ? /* @__PURE__ */ jsx(CheckIcon, {}) : /* @__PURE__ */ jsx(ContentCopyIcon, {}),
|
|
305
|
+
onClick: handleCopy,
|
|
306
|
+
color: copied ? "success" : "primary",
|
|
307
|
+
sx: { flex: 1 },
|
|
308
|
+
children: copied ? t("assetInstallDialog.copied") : t("assetInstallDialog.copyContent")
|
|
309
|
+
}
|
|
310
|
+
),
|
|
311
|
+
/* @__PURE__ */ jsx(
|
|
312
|
+
Button,
|
|
313
|
+
{
|
|
314
|
+
size: "small",
|
|
315
|
+
variant: "outlined",
|
|
316
|
+
startIcon: /* @__PURE__ */ jsx(DownloadIcon, {}),
|
|
317
|
+
onClick: handleDownload,
|
|
318
|
+
sx: { flex: 1 },
|
|
319
|
+
children: t("assetInstallDialog.download")
|
|
320
|
+
}
|
|
321
|
+
)
|
|
322
|
+
] })
|
|
323
|
+
] })
|
|
324
|
+
] });
|
|
325
|
+
}
|
|
326
|
+
function AssetInstallDialog({ assetId, onClose }) {
|
|
327
|
+
const [step, setStep] = useState(0);
|
|
328
|
+
const api = useApi(devAiHubApiRef);
|
|
329
|
+
const { asset, loading } = useAssetDetail(assetId);
|
|
330
|
+
const { t } = useTranslationRef(devAiHubTranslationRef);
|
|
331
|
+
const handleClose = () => {
|
|
332
|
+
setStep(0);
|
|
333
|
+
onClose();
|
|
334
|
+
};
|
|
335
|
+
const handleDownloadBundle = async () => {
|
|
336
|
+
if (!asset) return;
|
|
337
|
+
const url = await api.getDownloadUrl(asset.id);
|
|
338
|
+
const a = document.createElement("a");
|
|
339
|
+
a.href = url;
|
|
340
|
+
a.download = `${asset.name.replace(/\s+/g, "-").toLowerCase()}-bundle.zip`;
|
|
341
|
+
a.click();
|
|
342
|
+
api.trackInstall(asset.id).catch(() => {
|
|
343
|
+
});
|
|
344
|
+
};
|
|
345
|
+
const isBundle = asset?.type === "bundle";
|
|
346
|
+
const bundleItems = isBundle ? asset.items ?? [] : [];
|
|
347
|
+
const totalSteps = bundleItems.length;
|
|
348
|
+
const progress = totalSteps > 0 ? (step + 1) / totalSteps * 100 : 0;
|
|
349
|
+
return /* @__PURE__ */ jsxs(Dialog, { open: !!assetId, onClose: handleClose, maxWidth: "sm", fullWidth: true, children: [
|
|
350
|
+
/* @__PURE__ */ jsx(DialogTitle, { sx: { pb: 1 }, children: isBundle ? /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
|
|
351
|
+
/* @__PURE__ */ jsx(Inventory2Icon, { sx: { color: "#8B5CF6", fontSize: "1.4rem" } }),
|
|
352
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
353
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h6", fontWeight: 700, children: t("assetInstallDialog.dialogTitleBundle", { name: asset?.name ?? "" }) }),
|
|
354
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", sx: { fontWeight: 400 }, children: t("assetInstallDialog.dialogSubtitleBundle") })
|
|
355
|
+
] })
|
|
356
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
357
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h6", fontWeight: 700, children: asset ? t("assetInstallDialog.dialogTitle", { name: asset.name }) : t("assetInstallDialog.dialogTitle", { name: "" }) }),
|
|
358
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", sx: { mt: 0.5, fontWeight: 400 }, children: t("assetInstallDialog.dialogSubtitle") })
|
|
359
|
+
] }) }),
|
|
360
|
+
isBundle && totalSteps > 0 && /* @__PURE__ */ jsxs(Box, { sx: { px: 3, pb: 1 }, children: [
|
|
361
|
+
/* @__PURE__ */ jsx(LinearProgress, { variant: "determinate", value: progress, sx: { borderRadius: 1, height: 6 } }),
|
|
362
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "text.secondary", sx: { display: "block", mt: 0.5, textAlign: "right" }, children: t("assetInstallDialog.bundleProgress", { current: step + 1, total: totalSteps }) })
|
|
363
|
+
] }),
|
|
364
|
+
/* @__PURE__ */ jsxs(DialogContent, { sx: { display: "flex", flexDirection: "column", gap: 1.5, pt: "8px !important" }, children: [
|
|
365
|
+
loading && /* @__PURE__ */ jsx(Box, { sx: { display: "flex", justifyContent: "center", py: 3 }, children: /* @__PURE__ */ jsx(CircularProgress, {}) }),
|
|
366
|
+
!loading && asset && !isBundle && /* @__PURE__ */ jsx(SingleAssetView, { asset }),
|
|
367
|
+
!loading && isBundle && bundleItems.length === 0 && /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", sx: { textAlign: "center", py: 2 }, children: t("assetInstallDialog.bundleEmpty") }),
|
|
368
|
+
!loading && isBundle && bundleItems.length > 0 && /* @__PURE__ */ jsx(
|
|
369
|
+
BundleItemStep,
|
|
370
|
+
{
|
|
371
|
+
item: bundleItems[step],
|
|
372
|
+
stepIndex: step,
|
|
373
|
+
total: totalSteps
|
|
374
|
+
}
|
|
375
|
+
)
|
|
188
376
|
] }),
|
|
189
|
-
/* @__PURE__ */ jsx(DialogActions, { children: /* @__PURE__ */
|
|
377
|
+
/* @__PURE__ */ jsx(DialogActions, { sx: { justifyContent: "space-between", px: 2, py: 1.5 }, children: isBundle ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
378
|
+
/* @__PURE__ */ jsx(
|
|
379
|
+
Button,
|
|
380
|
+
{
|
|
381
|
+
startIcon: /* @__PURE__ */ jsx(FolderZipIcon, {}),
|
|
382
|
+
variant: "outlined",
|
|
383
|
+
size: "small",
|
|
384
|
+
onClick: handleDownloadBundle,
|
|
385
|
+
disabled: !asset,
|
|
386
|
+
children: t("assetInstallDialog.downloadBundle")
|
|
387
|
+
}
|
|
388
|
+
),
|
|
389
|
+
/* @__PURE__ */ jsxs(Box, { sx: { display: "flex", gap: 1 }, children: [
|
|
390
|
+
/* @__PURE__ */ jsx(
|
|
391
|
+
Button,
|
|
392
|
+
{
|
|
393
|
+
startIcon: /* @__PURE__ */ jsx(ArrowBackIcon, {}),
|
|
394
|
+
onClick: () => setStep((s) => Math.max(0, s - 1)),
|
|
395
|
+
disabled: step === 0,
|
|
396
|
+
children: t("assetInstallDialog.back")
|
|
397
|
+
}
|
|
398
|
+
),
|
|
399
|
+
step < totalSteps - 1 ? /* @__PURE__ */ jsx(
|
|
400
|
+
Button,
|
|
401
|
+
{
|
|
402
|
+
endIcon: /* @__PURE__ */ jsx(ArrowForwardIcon, {}),
|
|
403
|
+
variant: "contained",
|
|
404
|
+
onClick: () => setStep((s) => Math.min(totalSteps - 1, s + 1)),
|
|
405
|
+
children: t("assetInstallDialog.next")
|
|
406
|
+
}
|
|
407
|
+
) : /* @__PURE__ */ jsx(Button, { variant: "contained", color: "success", onClick: handleClose, children: t("assetInstallDialog.finish") })
|
|
408
|
+
] })
|
|
409
|
+
] }) : /* @__PURE__ */ jsx(Button, { onClick: handleClose, sx: { ml: "auto" }, children: t("assetInstallDialog.close") }) })
|
|
190
410
|
] });
|
|
191
411
|
}
|
|
192
412
|
|