@nospt/plugin-dev-ai-hub 0.2.4 → 0.3.1

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 (126) hide show
  1. package/dist/api/DevAiHubResourceClient.esm.js +97 -0
  2. package/dist/api/DevAiHubResourceClient.esm.js.map +1 -0
  3. package/dist/components/AiResourcesPage/AiResourcesPage.esm.js +150 -0
  4. package/dist/components/AiResourcesPage/AiResourcesPage.esm.js.map +1 -0
  5. package/dist/components/AiResourcesPage/AiResourcesPage.module.css.esm.js +8 -0
  6. package/dist/components/AiResourcesPage/AiResourcesPage.module.css.esm.js.map +1 -0
  7. package/dist/components/AiResourcesPage/ResourceCard.esm.js +112 -0
  8. package/dist/components/AiResourcesPage/ResourceCard.esm.js.map +1 -0
  9. package/dist/components/AiResourcesPage/ResourceCard.module.css.esm.js +8 -0
  10. package/dist/components/AiResourcesPage/ResourceCard.module.css.esm.js.map +1 -0
  11. package/dist/components/AiResourcesPage/ResourceDetailPanel.esm.js +238 -0
  12. package/dist/components/AiResourcesPage/ResourceDetailPanel.esm.js.map +1 -0
  13. package/dist/components/AiResourcesPage/ResourceDetailPanel.module.css.esm.js +8 -0
  14. package/dist/components/AiResourcesPage/ResourceDetailPanel.module.css.esm.js.map +1 -0
  15. package/dist/components/AiResourcesPage/ResourceFilters.esm.js +242 -0
  16. package/dist/components/AiResourcesPage/ResourceFilters.esm.js.map +1 -0
  17. package/dist/components/AiResourcesPage/ResourceFilters.module.css.esm.js +8 -0
  18. package/dist/components/AiResourcesPage/ResourceFilters.module.css.esm.js.map +1 -0
  19. package/dist/components/AiResourcesPage/ResourceInstallDialog.esm.js +366 -0
  20. package/dist/components/AiResourcesPage/ResourceInstallDialog.esm.js.map +1 -0
  21. package/dist/components/AiResourcesPage/ResourceInstallDialog.module.css.esm.js +8 -0
  22. package/dist/components/AiResourcesPage/ResourceInstallDialog.module.css.esm.js.map +1 -0
  23. package/dist/components/AiResourcesPage/StatTiles.aurora.module.css.esm.js +8 -0
  24. package/dist/components/AiResourcesPage/StatTiles.aurora.module.css.esm.js.map +1 -0
  25. package/dist/components/AiResourcesPage/StatTiles.console.module.css.esm.js +8 -0
  26. package/dist/components/AiResourcesPage/StatTiles.console.module.css.esm.js.map +1 -0
  27. package/dist/components/AiResourcesPage/StatTiles.esm.js +82 -0
  28. package/dist/components/AiResourcesPage/StatTiles.esm.js.map +1 -0
  29. package/dist/components/AiResourcesPage/StatTiles.module.css.esm.js +8 -0
  30. package/dist/components/AiResourcesPage/StatTiles.module.css.esm.js.map +1 -0
  31. package/dist/components/AiResourcesPage/index.esm.js +6 -0
  32. package/dist/components/AiResourcesPage/typeMeta.esm.js +34 -0
  33. package/dist/components/AiResourcesPage/typeMeta.esm.js.map +1 -0
  34. package/dist/components/ToolIcon/ToolIcon.esm.js +28 -10
  35. package/dist/components/ToolIcon/ToolIcon.esm.js.map +1 -1
  36. package/dist/hooks/useResourceBody.esm.js +39 -0
  37. package/dist/hooks/useResourceBody.esm.js.map +1 -0
  38. package/dist/hooks/useResources.esm.js +26 -0
  39. package/dist/hooks/useResources.esm.js.map +1 -0
  40. package/dist/hooks/useTelemetryCounts.esm.js +24 -0
  41. package/dist/hooks/useTelemetryCounts.esm.js.map +1 -0
  42. package/dist/index.d.ts +1 -38
  43. package/dist/index.esm.js +1 -3
  44. package/dist/index.esm.js.map +1 -1
  45. package/dist/plugin.esm.js +15 -24
  46. package/dist/plugin.esm.js.map +1 -1
  47. package/dist/routes.esm.js +1 -2
  48. package/dist/routes.esm.js.map +1 -1
  49. package/package.json +17 -10
  50. package/.eslintrc.js +0 -1
  51. package/dev/index.tsx +0 -32
  52. package/dist/api/DevAiHubClient.esm.js +0 -78
  53. package/dist/api/DevAiHubClient.esm.js.map +0 -1
  54. package/dist/components/AssetCard/AssetCard.esm.js +0 -120
  55. package/dist/components/AssetCard/AssetCard.esm.js.map +0 -1
  56. package/dist/components/AssetCard/AssetCard.module.css.esm.js +0 -8
  57. package/dist/components/AssetCard/AssetCard.module.css.esm.js.map +0 -1
  58. package/dist/components/AssetDetailPanel/AssetDetailPanel.esm.js +0 -218
  59. package/dist/components/AssetDetailPanel/AssetDetailPanel.esm.js.map +0 -1
  60. package/dist/components/AssetDetailPanel/AssetDetailPanel.module.css.esm.js +0 -8
  61. package/dist/components/AssetDetailPanel/AssetDetailPanel.module.css.esm.js.map +0 -1
  62. package/dist/components/AssetFilters/AssetFilters.esm.js +0 -176
  63. package/dist/components/AssetFilters/AssetFilters.esm.js.map +0 -1
  64. package/dist/components/AssetFilters/AssetFilters.module.css.esm.js +0 -8
  65. package/dist/components/AssetFilters/AssetFilters.module.css.esm.js.map +0 -1
  66. package/dist/components/AssetInstallDialog/AssetInstallDialog.esm.js +0 -138
  67. package/dist/components/AssetInstallDialog/AssetInstallDialog.esm.js.map +0 -1
  68. package/dist/components/AssetInstallDialog/AssetInstallDialog.module.css.esm.js +0 -8
  69. package/dist/components/AssetInstallDialog/AssetInstallDialog.module.css.esm.js.map +0 -1
  70. package/dist/components/DevAiHubPage/DevAiHubPage.esm.js +0 -195
  71. package/dist/components/DevAiHubPage/DevAiHubPage.esm.js.map +0 -1
  72. package/dist/components/DevAiHubPage/DevAiHubPage.module.css.esm.js +0 -8
  73. package/dist/components/DevAiHubPage/DevAiHubPage.module.css.esm.js.map +0 -1
  74. package/dist/components/DevAiHubPage/index.esm.js +0 -6
  75. package/dist/components/McpConfigPage/McpConfigPage.esm.js +0 -200
  76. package/dist/components/McpConfigPage/McpConfigPage.esm.js.map +0 -1
  77. package/dist/components/McpConfigPage/McpConfigPage.module.css.esm.js +0 -8
  78. package/dist/components/McpConfigPage/McpConfigPage.module.css.esm.js.map +0 -1
  79. package/dist/components/McpConfigPage/index.esm.js +0 -6
  80. package/dist/components/McpConfigPage/index.esm.js.map +0 -1
  81. package/dist/hooks/index.esm.js +0 -114
  82. package/dist/hooks/index.esm.js.map +0 -1
  83. package/dist/pluginLegacy.esm.js +0 -27
  84. package/dist/pluginLegacy.esm.js.map +0 -1
  85. package/package.json-prepack +0 -85
  86. package/src/api/DevAiHubClient.ts +0 -110
  87. package/src/components/AssetCard/AssetCard.module.css +0 -153
  88. package/src/components/AssetCard/AssetCard.test.tsx +0 -182
  89. package/src/components/AssetCard/AssetCard.tsx +0 -152
  90. package/src/components/AssetCard/index.ts +0 -1
  91. package/src/components/AssetDetailPanel/AssetDetailPanel.module.css +0 -207
  92. package/src/components/AssetDetailPanel/AssetDetailPanel.tsx +0 -313
  93. package/src/components/AssetDetailPanel/index.ts +0 -1
  94. package/src/components/AssetFilters/AssetFilters.module.css +0 -67
  95. package/src/components/AssetFilters/AssetFilters.tsx +0 -219
  96. package/src/components/AssetFilters/index.ts +0 -2
  97. package/src/components/AssetInstallDialog/AssetInstallDialog.module.css +0 -72
  98. package/src/components/AssetInstallDialog/AssetInstallDialog.tsx +0 -176
  99. package/src/components/AssetInstallDialog/index.ts +0 -1
  100. package/src/components/DevAiHubPage/DevAiHubPage.module.css +0 -105
  101. package/src/components/DevAiHubPage/DevAiHubPage.tsx +0 -197
  102. package/src/components/DevAiHubPage/index.ts +0 -1
  103. package/src/components/McpConfigDialog/McpConfigDialog.module.css +0 -111
  104. package/src/components/McpConfigDialog/McpConfigDialog.tsx +0 -271
  105. package/src/components/McpConfigDialog/index.ts +0 -1
  106. package/src/components/McpConfigPage/McpConfigPage.module.css +0 -121
  107. package/src/components/McpConfigPage/McpConfigPage.tsx +0 -242
  108. package/src/components/McpConfigPage/index.ts +0 -1
  109. package/src/components/ToolIcon/ToolIcon.tsx +0 -65
  110. package/src/components/ToolIcon/index.ts +0 -1
  111. package/src/css-modules.d.ts +0 -4
  112. package/src/hooks/index.ts +0 -152
  113. package/src/index.ts +0 -10
  114. package/src/plugin.tsx +0 -60
  115. package/src/pluginLegacy.ts +0 -42
  116. package/src/routes.ts +0 -4
  117. package/tests/e2e/.auth.json +0 -14
  118. package/tests/e2e/asset-detail.spec.ts +0 -90
  119. package/tests/e2e/asset-filtering.spec.ts +0 -145
  120. package/tests/e2e/asset-installation.spec.ts +0 -74
  121. package/tests/e2e/dev-ai-hub-page.spec.ts +0 -89
  122. package/tests/e2e/fixtures/base.ts +0 -61
  123. package/tests/e2e/fixtures/mock-api.ts +0 -221
  124. package/tests/e2e/mcp-config.spec.ts +0 -88
  125. package/tsconfig.json +0 -10
  126. /package/dist/components/{DevAiHubPage → AiResourcesPage}/index.esm.js.map +0 -0
@@ -1,207 +0,0 @@
1
- @layer components {
2
- .drawer {
3
- position: fixed;
4
- top: 0;
5
- right: 0;
6
- bottom: 0;
7
- width: 640px;
8
- max-width: 100vw;
9
- background-color: var(--bui-bg-neutral-1);
10
- box-shadow: -4px 0 24px rgba(0, 0, 0, 0.15);
11
- z-index: 1300;
12
- display: flex;
13
- flex-direction: column;
14
- }
15
-
16
- .overlay {
17
- position: fixed;
18
- inset: 0;
19
- background-color: rgba(0, 0, 0, 0.9);
20
- z-index: 1299;
21
- }
22
-
23
- .panelContainer {
24
- display: flex;
25
- flex-direction: column;
26
- height: 100%;
27
- }
28
-
29
- .header {
30
- padding: var(--bui-space-4);
31
- display: flex;
32
- align-items: flex-start;
33
- gap: var(--bui-space-4);
34
- border-bottom: 1px solid var(--bui-border-1);
35
- }
36
-
37
- .headerContent {
38
- flex: 1;
39
- }
40
-
41
- .loadingRow {
42
- display: flex;
43
- align-items: center;
44
- gap: var(--bui-space-2);
45
- }
46
-
47
- .nameRow {
48
- display: flex;
49
- align-items: center;
50
- gap: var(--bui-space-2);
51
- margin-bottom: var(--bui-space-1);
52
- }
53
-
54
- .typeTag {
55
- font-weight: 600;
56
- }
57
-
58
- .tabBar {
59
- border-bottom: 1px solid var(--bui-border-1);
60
- padding: 0 var(--bui-space-4);
61
- }
62
-
63
- .contentArea {
64
- flex: 1;
65
- overflow: auto;
66
- padding: var(--bui-space-4);
67
- }
68
-
69
- .markdownContent {
70
- font-size: 0.9375rem;
71
- line-height: 1.7;
72
- }
73
-
74
- .markdownContent h1,
75
- .markdownContent h2,
76
- .markdownContent h3,
77
- .markdownContent h4,
78
- .markdownContent h5,
79
- .markdownContent h6 {
80
- margin-top: var(--bui-space-4);
81
- margin-bottom: var(--bui-space-2);
82
- font-weight: 700;
83
- }
84
-
85
- .markdownContent p {
86
- margin-bottom: var(--bui-space-2);
87
- line-height: 1.7;
88
- }
89
-
90
- .markdownContent ul,
91
- .markdownContent ol {
92
- padding-left: var(--bui-space-6);
93
- margin-bottom: var(--bui-space-2);
94
- }
95
-
96
- .markdownContent li {
97
- margin-bottom: var(--bui-space-1);
98
- }
99
-
100
- .markdownContent blockquote {
101
- border-left: 3px solid var(--bui-ring);
102
- padding-left: var(--bui-space-3);
103
- color: var(--bui-fg-secondary);
104
- margin: var(--bui-space-2) 0;
105
- margin-left: 0;
106
- }
107
-
108
- .markdownContent table {
109
- width: 100%;
110
- border-collapse: collapse;
111
- margin-bottom: var(--bui-space-2);
112
- }
113
-
114
- .markdownContent th,
115
- .markdownContent td {
116
- border: 1px solid var(--bui-border-1);
117
- padding: var(--bui-space-2) var(--bui-space-3);
118
- font-size: 0.875rem;
119
- }
120
-
121
- .markdownContent th {
122
- background-color: var(--bui-bg-neutral-1-hover);
123
- font-weight: 700;
124
- }
125
-
126
- .markdownContent code {
127
- background-color: var(--bui-bg-neutral-1-hover);
128
- padding: 1px var(--bui-space-1);
129
- border-radius: var(--bui-radius-2);
130
- font-family: monospace;
131
- font-size: 0.875em;
132
- }
133
-
134
- .markdownContent pre code {
135
- background-color: transparent;
136
- padding: 0;
137
- }
138
-
139
- .codeBlockWrapper {
140
- margin: var(--bui-space-2) 0;
141
- }
142
-
143
- .metaSection {
144
- display: flex;
145
- flex-direction: column;
146
- gap: var(--bui-space-3);
147
- }
148
-
149
- .metaRow {
150
- display: flex;
151
- align-items: baseline;
152
- gap: var(--bui-space-2);
153
- }
154
-
155
- .metaLabel {
156
- min-width: 90px;
157
- flex-shrink: 0;
158
- }
159
-
160
- .chipsRow {
161
- display: flex;
162
- gap: var(--bui-space-2);
163
- flex-wrap: wrap;
164
- margin-top: var(--bui-space-1);
165
- }
166
-
167
- .bundledHeader {
168
- display: flex;
169
- align-items: center;
170
- gap: 6px;
171
- margin-bottom: var(--bui-space-1);
172
- }
173
-
174
- .rawYaml {
175
- margin: 0;
176
- padding: var(--bui-space-4);
177
- border-radius: var(--bui-radius-2);
178
- border: 1px solid var(--bui-border-1);
179
- overflow: auto;
180
- font-size: 0.8rem;
181
- font-family: monospace;
182
- white-space: pre-wrap;
183
- word-break: break-word;
184
- background-color: var(--bui-bg-neutral-1-hover);
185
- }
186
-
187
- .actions {
188
- padding: var(--bui-space-4);
189
- border-top: 1px solid var(--bui-border-1);
190
- display: flex;
191
- gap: var(--bui-space-2);
192
- flex-wrap: wrap;
193
- }
194
-
195
- .repoLink {
196
- display: inline-flex;
197
- align-items: center;
198
- gap: var(--bui-space-1);
199
- }
200
-
201
- .divider {
202
- height: 1px;
203
- background-color: var(--bui-border-1);
204
- border: none;
205
- margin: 0;
206
- }
207
- }
@@ -1,313 +0,0 @@
1
- import { useState } from 'react';
2
- import ReactMarkdown from 'react-markdown';
3
- import remarkGfm from 'remark-gfm';
4
- import {
5
- Alert, Box, Flex, Text, Button, ButtonIcon, Tag, TagGroup, Skeleton, Link,
6
- Tabs, TabList, Tab, TabPanel,
7
- } from '@backstage/ui';
8
- import { RiCloseLine, RiFileCopyLine, RiFolderZipLine, RiExternalLinkLine } from '@remixicon/react';
9
- import type { AssetType } from '@nospt/plugin-dev-ai-hub-common';
10
- import { useAssetDetail } from '../../hooks';
11
- import styles from './AssetDetailPanel.module.css';
12
-
13
- // eslint-disable-next-line @typescript-eslint/no-require-imports
14
- const SyntaxHighlighter = require('react-syntax-highlighter/dist/esm/prism').default;
15
- // eslint-disable-next-line @typescript-eslint/no-require-imports
16
- const { oneLight } = require('react-syntax-highlighter/dist/esm/styles/prism');
17
-
18
- const TYPE_COLORS: Record<AssetType, string> = {
19
- instruction: '#1976d2',
20
- agent: '#7b1fa2',
21
- skill: '#388e3c',
22
- workflow: '#f57c00',
23
- };
24
-
25
- interface AssetDetailPanelProps {
26
- assetId: string | null;
27
- onClose: () => void;
28
- }
29
-
30
- export function AssetDetailPanel({ assetId, onClose }: AssetDetailPanelProps) {
31
- const [snackbar, setSnackbar] = useState<string | null>(null);
32
- const { asset, loading } = useAssetDetail(assetId);
33
-
34
- const handleCopy = () => {
35
- if (!asset) return;
36
- navigator.clipboard.writeText(asset.content).then(() =>
37
- setSnackbar('Markdown copied to clipboard!'),
38
- );
39
- };
40
-
41
- if (!assetId) return null;
42
-
43
- return (
44
- <>
45
- {/* Overlay */}
46
- <div className={styles.overlay} onClick={onClose} role="presentation" />
47
-
48
- {/* Drawer */}
49
- <div className={styles.drawer}>
50
- <Flex className={styles.panelContainer}>
51
- {/* Header */}
52
- <Flex className={styles.header}>
53
- <Box className={styles.headerContent}>
54
- {loading || !asset ? (
55
- <Flex className={styles.loadingRow}>
56
- <Skeleton style={{ width: 16, height: 16 }} />
57
- <Text variant="body-small" color="secondary">
58
- Loading...
59
- </Text>
60
- </Flex>
61
- ) : (
62
- <>
63
- <Flex className={styles.nameRow}>
64
- <Text variant="title-small" weight="bold">
65
- {asset.name}
66
- </Text>
67
- <TagGroup aria-label="Asset type">
68
- <Tag
69
- id={asset.type}
70
- size="small"
71
- className={styles.typeTag}
72
- style={{
73
- backgroundColor: `${TYPE_COLORS[asset.type]}20`,
74
- color: TYPE_COLORS[asset.type],
75
- }}
76
- >
77
- {asset.type}
78
- </Tag>
79
- </TagGroup>
80
- </Flex>
81
- <Text variant="body-medium" color="secondary">
82
- {asset.description}
83
- </Text>
84
- </>
85
- )}
86
- </Box>
87
- <ButtonIcon
88
- aria-label="Close"
89
- icon={<RiCloseLine size={20} />}
90
- variant="tertiary"
91
- onPress={onClose}
92
- />
93
- </Flex>
94
-
95
- {/* Tabs */}
96
- <Tabs defaultSelectedKey="preview">
97
- <TabList className={styles.tabBar}>
98
- <Tab id="preview">Preview</Tab>
99
- <Tab id="metadata">Metadata</Tab>
100
- <Tab id="raw">Raw YAML</Tab>
101
- </TabList>
102
-
103
- <Box className={styles.contentArea}>
104
- {loading && (
105
- <Flex style={{ justifyContent: 'center', paddingTop: 'var(--bui-space-8)' }}>
106
- <Skeleton style={{ width: '100%', height: 200 }} />
107
- </Flex>
108
- )}
109
-
110
- {!loading && asset && (
111
- <>
112
- <TabPanel id="preview">
113
- <div className={styles.markdownContent}>
114
- <ReactMarkdown
115
- remarkPlugins={[remarkGfm]}
116
- components={{
117
- pre: ({ children }) => <div className={styles.codeBlockWrapper}>{children}</div>,
118
- code({ className, children }) {
119
- const match = /language-(\w+)/.exec(className || '');
120
- const code = String(children).replace(/\n$/, '');
121
- const isBlock = code.includes('\n') || !!match;
122
- return isBlock ? (
123
- <SyntaxHighlighter
124
- style={oneLight}
125
- language={match?.[1] ?? 'text'}
126
- PreTag="div"
127
- customStyle={{
128
- borderRadius: 8,
129
- fontSize: '0.8rem',
130
- margin: 0,
131
- border: '1px solid rgba(0,0,0,0.08)',
132
- }}
133
- >
134
- {code}
135
- </SyntaxHighlighter>
136
- ) : (
137
- <code className={className}>{children}</code>
138
- );
139
- },
140
- }}
141
- >
142
- {asset.content}
143
- </ReactMarkdown>
144
- </div>
145
- </TabPanel>
146
-
147
- <TabPanel id="metadata">
148
- <Flex className={styles.metaSection}>
149
- <MetaRow label="Author" value={asset.author} />
150
- <MetaRow label="Version" value={asset.version} />
151
- <MetaRow label="Provider" value={asset.providerId} />
152
- {asset.commitSha && (
153
- <MetaRow label="Commit" value={asset.commitSha.slice(0, 8)} />
154
- )}
155
- <MetaRow label="Last synced" value={new Date(asset.syncedAt).toLocaleString()} />
156
- <MetaRow label="Branch" value={asset.branch} />
157
-
158
- <hr className={styles.divider} />
159
-
160
- <Box>
161
- <Text variant="body-small" color="secondary">
162
- Compatible tools
163
- </Text>
164
- <Flex className={styles.chipsRow}>
165
- <TagGroup aria-label="Compatible tools">
166
- {asset.tools.map(t => (
167
- <Tag key={t} id={t} size="small">{t}</Tag>
168
- ))}
169
- </TagGroup>
170
- </Flex>
171
- </Box>
172
-
173
- {asset.tags.length > 0 && (
174
- <Box>
175
- <Text variant="body-small" color="secondary">
176
- Tags
177
- </Text>
178
- <Flex className={styles.chipsRow}>
179
- <TagGroup aria-label="Tags">
180
- {asset.tags.map(t => (
181
- <Tag key={t} id={t} size="small">{t}</Tag>
182
- ))}
183
- </TagGroup>
184
- </Flex>
185
- </Box>
186
- )}
187
-
188
- {asset.type === 'skill' && (
189
- <>
190
- <hr className={styles.divider} />
191
- <Box>
192
- <Flex className={styles.bundledHeader}>
193
- <RiFolderZipLine size={14} style={{ color: 'var(--bui-fg-secondary)' }} />
194
- <Text variant="body-small" color="secondary">
195
- Bundled files
196
- </Text>
197
- </Flex>
198
- {asset.resourcesContent && Object.keys(asset.resourcesContent).length > 0 ? (
199
- <Flex direction="column" style={{ gap: 'var(--bui-space-1)', marginTop: 'var(--bui-space-1)' }}>
200
- <TagGroup aria-label="Bundled files">
201
- <Flex className={styles.chipsRow}>
202
- <Tag id="skill-md" size="small" style={{ fontFamily: 'monospace', fontSize: '0.7rem', height: 20 }}>
203
- SKILL.md
204
- </Tag>
205
- {Object.keys(asset.resourcesContent).map(p => (
206
- <Tag key={p} id={p} size="small" style={{ fontFamily: 'monospace', fontSize: '0.7rem', height: 20 }}>
207
- {p}
208
- </Tag>
209
- ))}
210
- </Flex>
211
- </TagGroup>
212
- <Text variant="body-small" color="secondary">
213
- Downloads as .zip containing all files above.
214
- </Text>
215
- </Flex>
216
- ) : (
217
- <TagGroup aria-label="Bundled files">
218
- <Flex className={styles.chipsRow}>
219
- <Tag id="skill-md-only" size="small" style={{ fontFamily: 'monospace', fontSize: '0.7rem', height: 20 }}>
220
- SKILL.md
221
- </Tag>
222
- </Flex>
223
- </TagGroup>
224
- )}
225
- </Box>
226
- </>
227
- )}
228
-
229
- <hr className={styles.divider} />
230
-
231
- <Box>
232
- <Text variant="body-small" color="secondary">
233
- Repository
234
- </Text>
235
- <Box>
236
- <Link
237
- href={asset.repoUrl}
238
- target="_blank"
239
- rel="noopener noreferrer"
240
- className={styles.repoLink}
241
- >
242
- {asset.repoUrl} <RiExternalLinkLine size={12} />
243
- </Link>
244
- </Box>
245
- </Box>
246
- </Flex>
247
- </TabPanel>
248
-
249
- <TabPanel id="raw">
250
- <pre className={styles.rawYaml}>
251
- {asset.yamlRaw}
252
- </pre>
253
- </TabPanel>
254
- </>
255
- )}
256
- </Box>
257
- </Tabs>
258
-
259
- {/* Actions */}
260
- <Flex className={styles.actions}>
261
- <Button
262
- variant="primary"
263
- onClick={handleCopy}
264
- isDisabled={!asset}
265
- >
266
- <RiFileCopyLine size={16} />
267
- Copy Markdown
268
- </Button>
269
-
270
- <Button
271
- variant="secondary"
272
- onClick={() => asset && window.open(asset.repoUrl, '_blank')}
273
- isDisabled={!asset}
274
- >
275
- <RiExternalLinkLine size={16} />
276
- Open in Repo
277
- </Button>
278
- </Flex>
279
- </Flex>
280
- </div>
281
-
282
- {/* Snackbar replacement — simple toast */}
283
- {snackbar && (
284
- <div
285
- style={{
286
- position: 'fixed',
287
- bottom: 24,
288
- left: '50%',
289
- transform: 'translateX(-50%)',
290
- zIndex: 1400,
291
- }}
292
- >
293
- <Alert
294
- status="success"
295
- icon
296
- description={snackbar}
297
- />
298
- </div>
299
- )}
300
- </>
301
- );
302
- }
303
-
304
- function MetaRow({ label, value }: { label: string; value: string }) {
305
- return (
306
- <Flex className={styles.metaRow}>
307
- <Text variant="body-medium" color="secondary" className={styles.metaLabel}>
308
- {label}:
309
- </Text>
310
- <Text variant="body-medium" weight="bold">{value}</Text>
311
- </Flex>
312
- );
313
- }
@@ -1 +0,0 @@
1
- export { AssetDetailPanel } from './AssetDetailPanel';
@@ -1,67 +0,0 @@
1
- @layer components {
2
- .container {
3
- display: flex;
4
- flex-direction: column;
5
- gap: var(--bui-space-4);
6
- margin-bottom: var(--bui-space-6);
7
- }
8
-
9
- .searchField {
10
- width: 100%;
11
- }
12
-
13
- .filtersRow {
14
- display: flex;
15
- gap: var(--bui-space-6);
16
- flex-wrap: wrap;
17
- align-items: flex-start;
18
- }
19
-
20
- .filterLabel {
21
- margin-bottom: var(--bui-space-2);
22
- display: block;
23
- text-transform: uppercase;
24
- letter-spacing: 0.5px;
25
- font-weight: 600;
26
- }
27
-
28
- .filterChips {
29
- display: flex;
30
- gap: 6px;
31
- flex-wrap: wrap;
32
- }
33
-
34
- .filterChip {
35
- font-weight: 600;
36
- font-size: 0.75rem;
37
- border-radius: var(--bui-radius-2);
38
- border: 1.5px solid;
39
- transition: all 0.15s ease;
40
- cursor: pointer;
41
- }
42
-
43
- .filterChip :global(.bui-ToggleButtonContent) {
44
- display: flex;
45
- align-items: center;
46
- }
47
-
48
- .filterChip svg {
49
- display: block;
50
- }
51
-
52
- .toolChipSelected {
53
- font-weight: 700;
54
- }
55
-
56
- .tagChip {
57
- font-size: 0.7rem;
58
- border-radius: var(--bui-radius-2);
59
- border: 1px solid;
60
- cursor: pointer;
61
- }
62
-
63
- .tagChip :global(.bui-ToggleButtonContent) {
64
- display: flex;
65
- align-items: center;
66
- }
67
- }