@terasky/backstage-plugin-ai-rules 1.2.0 → 1.4.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/alpha.esm.js +1 -1
- package/dist/alpha.esm.js.map +1 -1
- package/dist/api/AiRulesClient.esm.js.map +1 -1
- package/dist/api/types.esm.js.map +1 -1
- package/dist/components/AiInstructionsComponent/AiInstructionsComponent.esm.js.map +1 -1
- package/dist/components/AiRulesComponent/AiRulesComponent.esm.js.map +1 -1
- package/dist/components/MCPServersComponent/MCPServersComponent.esm.js.map +1 -1
- package/dist/hooks/useAiRules.esm.js.map +1 -1
- package/dist/hooks/useMCPServers.esm.js.map +1 -1
- package/dist/index.d.ts +18 -17
- package/dist/plugin.esm.js.map +1 -1
- package/dist/routes.esm.js.map +1 -1
- package/dist/types.esm.js.map +1 -1
- package/package.json +10 -10
package/dist/alpha.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { createFrontendPlugin, ApiBlueprint,
|
|
2
|
+
import { createFrontendPlugin, ApiBlueprint, identityApiRef, discoveryApiRef } from '@backstage/frontend-plugin-api';
|
|
3
3
|
import { EntityContentBlueprint } from '@backstage/plugin-catalog-react/alpha';
|
|
4
4
|
import { isAIRulesAvailable } from './components/AiRulesComponent/AiRulesComponent.esm.js';
|
|
5
5
|
import { aiRulesApiRef } from './api/types.esm.js';
|
package/dist/alpha.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alpha.esm.js","sources":["../src/alpha.tsx"],"sourcesContent":["import {\n ApiBlueprint,\n createFrontendPlugin,\n discoveryApiRef,\n identityApiRef,\n} from '@backstage/frontend-plugin-api';\nimport { EntityContentBlueprint } from '@backstage/plugin-catalog-react/alpha';\nimport { isAIRulesAvailable } from './components/AiRulesComponent';\nimport { aiRulesApiRef, AiRulesClient } from './api';\n\n/** @alpha */\nexport const aiRulesPlugin = createFrontendPlugin({\n pluginId: 'ai-rules',\n extensions: [\n EntityContentBlueprint.make({\n name: 'aiRules',\n params: {\n path: '/ai-rules',\n filter: isAIRulesAvailable,\n title: 'AI Rules',\n loader: () => import('./components/AiRulesComponent/AiRulesComponent').then(m => <m.AIRulesComponent />),\n },\n disabled: true,\n }),\n EntityContentBlueprint.make({\n name: 'aiInstructions',\n params: {\n path: '/ai-instructions',\n filter: isAIRulesAvailable,\n title: 'AI Instructions',\n loader: () => import('./components/AiInstructionsComponent/AiInstructionsComponent').then(m => <m.AiInstructionsComponent />),\n },\n disabled: false,\n }),\n EntityContentBlueprint.make({\n name: 'mcpServers',\n params: {\n path: '/mcp-servers',\n filter: isAIRulesAvailable,\n title: 'MCP Servers',\n loader: () => import('./components/MCPServersComponent/MCPServersComponent').then(m => <m.MCPServersComponent />),\n },\n disabled: true,\n }),\n ApiBlueprint.make({\n name: 'aiRulesApi',\n params: defineParams => defineParams({\n api: aiRulesApiRef,\n deps: {\n discoveryApi: discoveryApiRef,\n identityApi: identityApiRef,\n },\n factory: ({ discoveryApi, identityApi }) => new AiRulesClient({ discoveryApi, identityApi }),\n }),\n disabled: false,\n }),\n ],\n});\nexport default aiRulesPlugin;"],"names":[],"mappings":";;;;;;;AAWO,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"alpha.esm.js","sources":["../src/alpha.tsx"],"sourcesContent":["import {\n ApiBlueprint,\n createFrontendPlugin,\n discoveryApiRef,\n identityApiRef,\n} from '@backstage/frontend-plugin-api';\nimport { EntityContentBlueprint } from '@backstage/plugin-catalog-react/alpha';\nimport { isAIRulesAvailable } from './components/AiRulesComponent';\nimport { aiRulesApiRef, AiRulesClient } from './api';\n\n/** @alpha */\nexport const aiRulesPlugin = createFrontendPlugin({\n pluginId: 'ai-rules',\n extensions: [\n EntityContentBlueprint.make({\n name: 'aiRules',\n params: {\n path: '/ai-rules',\n filter: isAIRulesAvailable,\n title: 'AI Rules',\n loader: () => import('./components/AiRulesComponent/AiRulesComponent').then(m => <m.AIRulesComponent />),\n },\n disabled: true,\n }),\n EntityContentBlueprint.make({\n name: 'aiInstructions',\n params: {\n path: '/ai-instructions',\n filter: isAIRulesAvailable,\n title: 'AI Instructions',\n loader: () => import('./components/AiInstructionsComponent/AiInstructionsComponent').then(m => <m.AiInstructionsComponent />),\n },\n disabled: false,\n }),\n EntityContentBlueprint.make({\n name: 'mcpServers',\n params: {\n path: '/mcp-servers',\n filter: isAIRulesAvailable,\n title: 'MCP Servers',\n loader: () => import('./components/MCPServersComponent/MCPServersComponent').then(m => <m.MCPServersComponent />),\n },\n disabled: true,\n }),\n ApiBlueprint.make({\n name: 'aiRulesApi',\n params: defineParams => defineParams({\n api: aiRulesApiRef,\n deps: {\n discoveryApi: discoveryApiRef,\n identityApi: identityApiRef,\n },\n factory: ({ discoveryApi, identityApi }) => new AiRulesClient({ discoveryApi, identityApi }),\n }),\n disabled: false,\n }),\n ],\n});\nexport default aiRulesPlugin;"],"names":[],"mappings":";;;;;;;AAWO,MAAM,gBAAgB,oBAAA,CAAqB;AAAA,EAChD,QAAA,EAAU,UAAA;AAAA,EACV,UAAA,EAAY;AAAA,IACV,uBAAuB,IAAA,CAAK;AAAA,MAC1B,IAAA,EAAM,SAAA;AAAA,MACN,MAAA,EAAQ;AAAA,QACN,IAAA,EAAM,WAAA;AAAA,QACN,MAAA,EAAQ,kBAAA;AAAA,QACR,KAAA,EAAO,UAAA;AAAA,QACP,MAAA,EAAQ,MAAM,OAAO,uDAAgD,CAAA,CAAE,IAAA,CAAK,CAAA,CAAA,qBAAK,GAAA,CAAC,CAAA,CAAE,gBAAA,EAAF,EAAmB,CAAE;AAAA,OACzG;AAAA,MACA,QAAA,EAAU;AAAA,KACX,CAAA;AAAA,IACD,uBAAuB,IAAA,CAAK;AAAA,MAC1B,IAAA,EAAM,gBAAA;AAAA,MACN,MAAA,EAAQ;AAAA,QACN,IAAA,EAAM,kBAAA;AAAA,QACN,MAAA,EAAQ,kBAAA;AAAA,QACR,KAAA,EAAO,iBAAA;AAAA,QACP,MAAA,EAAQ,MAAM,OAAO,qEAA8D,CAAA,CAAE,IAAA,CAAK,CAAA,CAAA,qBAAK,GAAA,CAAC,CAAA,CAAE,uBAAA,EAAF,EAA0B,CAAE;AAAA,OAC9H;AAAA,MACA,QAAA,EAAU;AAAA,KACX,CAAA;AAAA,IACD,uBAAuB,IAAA,CAAK;AAAA,MAC1B,IAAA,EAAM,YAAA;AAAA,MACN,MAAA,EAAQ;AAAA,QACN,IAAA,EAAM,cAAA;AAAA,QACN,MAAA,EAAQ,kBAAA;AAAA,QACR,KAAA,EAAO,aAAA;AAAA,QACP,MAAA,EAAQ,MAAM,OAAO,6DAAsD,CAAA,CAAE,IAAA,CAAK,CAAA,CAAA,qBAAK,GAAA,CAAC,CAAA,CAAE,mBAAA,EAAF,EAAsB,CAAE;AAAA,OAClH;AAAA,MACA,QAAA,EAAU;AAAA,KACX,CAAA;AAAA,IACD,aAAa,IAAA,CAAK;AAAA,MAChB,IAAA,EAAM,YAAA;AAAA,MACN,MAAA,EAAQ,kBAAgB,YAAA,CAAa;AAAA,QACnC,GAAA,EAAK,aAAA;AAAA,QACL,IAAA,EAAM;AAAA,UACJ,YAAA,EAAc,eAAA;AAAA,UACd,WAAA,EAAa;AAAA,SACf;AAAA,QACA,OAAA,EAAS,CAAC,EAAE,YAAA,EAAc,WAAA,EAAY,KAAM,IAAI,aAAA,CAAc,EAAE,YAAA,EAAc,WAAA,EAAa;AAAA,OAC5F,CAAA;AAAA,MACD,QAAA,EAAU;AAAA,KACX;AAAA;AAEL,CAAC;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiRulesClient.esm.js","sources":["../../src/api/AiRulesClient.ts"],"sourcesContent":["import { AiRulesApi } from './types';\nimport { AIRulesResponse } from '../types';\nimport { MCPServersResponse } from '../types/mcp';\n\n\nexport class AiRulesClient implements AiRulesApi {\n private readonly discoveryApi: { getBaseUrl: (pluginId: string) => Promise<string> };\n private readonly identityApi: { getCredentials(): Promise<{ token?: string }> };\n\n constructor(options: {\n discoveryApi: { getBaseUrl: (pluginId: string) => Promise<string> };\n identityApi: { getCredentials(): Promise<{ token?: string }> };\n }) {\n this.discoveryApi = options.discoveryApi;\n this.identityApi = options.identityApi;\n }\n\n private async getAuthHeaders(): Promise<HeadersInit> {\n const { token } = await this.identityApi.getCredentials();\n return {\n 'Authorization': `Bearer ${token}`,\n };\n }\n\n private cleanGitUrl(url: string): string {\n return url\n .replace('url:', '')\n .replace(/\\/tree\\/(?:main|master)\\/.*$/, '');\n }\n\n async getAiRules(ruleTypes: string[]): Promise<AIRulesResponse> {\n const baseUrl = await this.discoveryApi.getBaseUrl('ai-rules');\n const sourceLocation = window.location.pathname.split('/').includes('catalog')\n ? new URLSearchParams(window.location.search).get('sourceLocation') || ''\n : '';\n const gitUrl = this.cleanGitUrl(sourceLocation);\n \n const queryParams = new URLSearchParams({\n gitUrl,\n ruleTypes: ruleTypes.join(','),\n });\n\n const response = await fetch(`${baseUrl}/rules?${queryParams}`, {\n headers: await this.getAuthHeaders(),\n });\n if (!response.ok) {\n throw new Error('Failed to fetch AI rules');\n }\n return await response.json();\n }\n\n async getMCPServers(gitUrl: string): Promise<MCPServersResponse> {\n const baseUrl = await this.discoveryApi.getBaseUrl('ai-rules');\n const queryParams = new URLSearchParams({ gitUrl });\n\n const response = await fetch(`${baseUrl}/mcp-servers?${queryParams}`, {\n headers: await this.getAuthHeaders(),\n });\n if (!response.ok) {\n throw new Error('Failed to fetch MCP servers');\n }\n return await response.json();\n }\n}\n"],"names":[],"mappings":"AAKO,MAAM,
|
|
1
|
+
{"version":3,"file":"AiRulesClient.esm.js","sources":["../../src/api/AiRulesClient.ts"],"sourcesContent":["import { AiRulesApi } from './types';\nimport { AIRulesResponse } from '../types';\nimport { MCPServersResponse } from '../types/mcp';\n\n\nexport class AiRulesClient implements AiRulesApi {\n private readonly discoveryApi: { getBaseUrl: (pluginId: string) => Promise<string> };\n private readonly identityApi: { getCredentials(): Promise<{ token?: string }> };\n\n constructor(options: {\n discoveryApi: { getBaseUrl: (pluginId: string) => Promise<string> };\n identityApi: { getCredentials(): Promise<{ token?: string }> };\n }) {\n this.discoveryApi = options.discoveryApi;\n this.identityApi = options.identityApi;\n }\n\n private async getAuthHeaders(): Promise<HeadersInit> {\n const { token } = await this.identityApi.getCredentials();\n return {\n 'Authorization': `Bearer ${token}`,\n };\n }\n\n private cleanGitUrl(url: string): string {\n return url\n .replace('url:', '')\n .replace(/\\/tree\\/(?:main|master)\\/.*$/, '');\n }\n\n async getAiRules(ruleTypes: string[]): Promise<AIRulesResponse> {\n const baseUrl = await this.discoveryApi.getBaseUrl('ai-rules');\n const sourceLocation = window.location.pathname.split('/').includes('catalog')\n ? new URLSearchParams(window.location.search).get('sourceLocation') || ''\n : '';\n const gitUrl = this.cleanGitUrl(sourceLocation);\n \n const queryParams = new URLSearchParams({\n gitUrl,\n ruleTypes: ruleTypes.join(','),\n });\n\n const response = await fetch(`${baseUrl}/rules?${queryParams}`, {\n headers: await this.getAuthHeaders(),\n });\n if (!response.ok) {\n throw new Error('Failed to fetch AI rules');\n }\n return await response.json();\n }\n\n async getMCPServers(gitUrl: string): Promise<MCPServersResponse> {\n const baseUrl = await this.discoveryApi.getBaseUrl('ai-rules');\n const queryParams = new URLSearchParams({ gitUrl });\n\n const response = await fetch(`${baseUrl}/mcp-servers?${queryParams}`, {\n headers: await this.getAuthHeaders(),\n });\n if (!response.ok) {\n throw new Error('Failed to fetch MCP servers');\n }\n return await response.json();\n }\n}\n"],"names":[],"mappings":"AAKO,MAAM,aAAA,CAAoC;AAAA,EAC9B,YAAA;AAAA,EACA,WAAA;AAAA,EAEjB,YAAY,OAAA,EAGT;AACD,IAAA,IAAA,CAAK,eAAe,OAAA,CAAQ,YAAA;AAC5B,IAAA,IAAA,CAAK,cAAc,OAAA,CAAQ,WAAA;AAAA,EAC7B;AAAA,EAEA,MAAc,cAAA,GAAuC;AACnD,IAAA,MAAM,EAAE,KAAA,EAAM,GAAI,MAAM,IAAA,CAAK,YAAY,cAAA,EAAe;AACxD,IAAA,OAAO;AAAA,MACL,eAAA,EAAiB,UAAU,KAAK,CAAA;AAAA,KAClC;AAAA,EACF;AAAA,EAEQ,YAAY,GAAA,EAAqB;AACvC,IAAA,OAAO,IACJ,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA,CAClB,OAAA,CAAQ,gCAAgC,EAAE,CAAA;AAAA,EAC/C;AAAA,EAEA,MAAM,WAAW,SAAA,EAA+C;AAC9D,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,YAAA,CAAa,WAAW,UAAU,CAAA;AAC7D,IAAA,MAAM,iBAAiB,MAAA,CAAO,QAAA,CAAS,SAAS,KAAA,CAAM,GAAG,EAAE,QAAA,CAAS,SAAS,IACzE,IAAI,eAAA,CAAgB,OAAO,QAAA,CAAS,MAAM,EAAE,GAAA,CAAI,gBAAgB,KAAK,EAAA,GACrE,EAAA;AACJ,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,WAAA,CAAY,cAAc,CAAA;AAE9C,IAAA,MAAM,WAAA,GAAc,IAAI,eAAA,CAAgB;AAAA,MACtC,MAAA;AAAA,MACA,SAAA,EAAW,SAAA,CAAU,IAAA,CAAK,GAAG;AAAA,KAC9B,CAAA;AAED,IAAA,MAAM,WAAW,MAAM,KAAA,CAAM,GAAG,OAAO,CAAA,OAAA,EAAU,WAAW,CAAA,CAAA,EAAI;AAAA,MAC9D,OAAA,EAAS,MAAM,IAAA,CAAK,cAAA;AAAe,KACpC,CAAA;AACD,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAI,MAAM,0BAA0B,CAAA;AAAA,IAC5C;AACA,IAAA,OAAO,MAAM,SAAS,IAAA,EAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,cAAc,MAAA,EAA6C;AAC/D,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,YAAA,CAAa,WAAW,UAAU,CAAA;AAC7D,IAAA,MAAM,WAAA,GAAc,IAAI,eAAA,CAAgB,EAAE,QAAQ,CAAA;AAElD,IAAA,MAAM,WAAW,MAAM,KAAA,CAAM,GAAG,OAAO,CAAA,aAAA,EAAgB,WAAW,CAAA,CAAA,EAAI;AAAA,MACpE,OAAA,EAAS,MAAM,IAAA,CAAK,cAAA;AAAe,KACpC,CAAA;AACD,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAI,MAAM,6BAA6B,CAAA;AAAA,IAC/C;AACA,IAAA,OAAO,MAAM,SAAS,IAAA,EAAK;AAAA,EAC7B;AACF;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.esm.js","sources":["../../src/api/types.ts"],"sourcesContent":["import { AIRulesResponse } from '../types';\nimport { MCPServersResponse } from '../types/mcp';\n\nimport { createApiRef } from '@backstage/core-plugin-api';\n\nexport const aiRulesApiRef = createApiRef<AiRulesApi>({\n id: 'plugin.ai-rules.service',\n});\n\nexport interface AiRulesApi {\n getAiRules(ruleTypes: string[]): Promise<AIRulesResponse>;\n getMCPServers(gitUrl: string): Promise<MCPServersResponse>;\n}\n"],"names":[],"mappings":";;AAKO,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"types.esm.js","sources":["../../src/api/types.ts"],"sourcesContent":["import { AIRulesResponse } from '../types';\nimport { MCPServersResponse } from '../types/mcp';\n\nimport { createApiRef } from '@backstage/core-plugin-api';\n\nexport const aiRulesApiRef = createApiRef<AiRulesApi>({\n id: 'plugin.ai-rules.service',\n});\n\nexport interface AiRulesApi {\n getAiRules(ruleTypes: string[]): Promise<AIRulesResponse>;\n getMCPServers(gitUrl: string): Promise<MCPServersResponse>;\n}\n"],"names":[],"mappings":";;AAKO,MAAM,gBAAgB,YAAA,CAAyB;AAAA,EACpD,EAAA,EAAI;AACN,CAAC;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiInstructionsComponent.esm.js","sources":["../../../src/components/AiInstructionsComponent/AiInstructionsComponent.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport { makeStyles } from '@material-ui/core/styles';\nimport {\n Tabs,\n Tab,\n Box,\n} from '@material-ui/core';\nimport { AIRulesComponent } from '../AiRulesComponent';\nimport { MCPServersComponent } from '../MCPServersComponent';\n\ninterface TabPanelProps {\n children?: React.ReactNode;\n index: number;\n value: number;\n}\n\nfunction TabPanel(props: TabPanelProps) {\n const { children, value, index, ...other } = props;\n\n return (\n <div\n role=\"tabpanel\"\n hidden={value !== index}\n id={`ai-instructions-tabpanel-${index}`}\n aria-labelledby={`ai-instructions-tab-${index}`}\n {...other}\n >\n {value === index && (\n <Box>\n {children}\n </Box>\n )}\n </div>\n );\n}\n\nfunction a11yProps(index: number) {\n return {\n id: `ai-instructions-tab-${index}`,\n 'aria-controls': `ai-instructions-tabpanel-${index}`,\n };\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n width: '100%',\n backgroundColor: theme.palette.background.paper,\n },\n tabPanel: {\n padding: 0,\n marginTop: theme.spacing(2),\n },\n}));\n\nexport interface AiInstructionsComponentProps {\n title?: string;\n}\n\nexport const AiInstructionsComponent = ({ title = \"AI Instructions\" }: AiInstructionsComponentProps) => {\n const styles = useStyles();\n const [value, setValue] = useState(0);\n\n const handleChange = (_event: React.ChangeEvent<{}>, newValue: number) => {\n setValue(newValue);\n };\n\n return (\n <div className={styles.root}>\n <Tabs\n value={value}\n onChange={handleChange}\n indicatorColor=\"primary\"\n textColor=\"primary\"\n variant=\"fullWidth\"\n >\n <Tab label=\"Agent Rules\" {...a11yProps(0)} />\n <Tab label=\"MCP Servers\" {...a11yProps(1)} />\n </Tabs>\n <TabPanel value={value} index={0}>\n <Box className={styles.tabPanel}>\n <AIRulesComponent title={title} />\n </Box>\n </TabPanel>\n <TabPanel value={value} index={1}>\n <Box className={styles.tabPanel}>\n <MCPServersComponent />\n </Box>\n </TabPanel>\n </div>\n );\n};\n\n\n"],"names":[],"mappings":";;;;;;;AAgBA,SAAS,SAAS,
|
|
1
|
+
{"version":3,"file":"AiInstructionsComponent.esm.js","sources":["../../../src/components/AiInstructionsComponent/AiInstructionsComponent.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport { makeStyles } from '@material-ui/core/styles';\nimport {\n Tabs,\n Tab,\n Box,\n} from '@material-ui/core';\nimport { AIRulesComponent } from '../AiRulesComponent';\nimport { MCPServersComponent } from '../MCPServersComponent';\n\ninterface TabPanelProps {\n children?: React.ReactNode;\n index: number;\n value: number;\n}\n\nfunction TabPanel(props: TabPanelProps) {\n const { children, value, index, ...other } = props;\n\n return (\n <div\n role=\"tabpanel\"\n hidden={value !== index}\n id={`ai-instructions-tabpanel-${index}`}\n aria-labelledby={`ai-instructions-tab-${index}`}\n {...other}\n >\n {value === index && (\n <Box>\n {children}\n </Box>\n )}\n </div>\n );\n}\n\nfunction a11yProps(index: number) {\n return {\n id: `ai-instructions-tab-${index}`,\n 'aria-controls': `ai-instructions-tabpanel-${index}`,\n };\n}\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n width: '100%',\n backgroundColor: theme.palette.background.paper,\n },\n tabPanel: {\n padding: 0,\n marginTop: theme.spacing(2),\n },\n}));\n\nexport interface AiInstructionsComponentProps {\n title?: string;\n}\n\nexport const AiInstructionsComponent = ({ title = \"AI Instructions\" }: AiInstructionsComponentProps) => {\n const styles = useStyles();\n const [value, setValue] = useState(0);\n\n const handleChange = (_event: React.ChangeEvent<{}>, newValue: number) => {\n setValue(newValue);\n };\n\n return (\n <div className={styles.root}>\n <Tabs\n value={value}\n onChange={handleChange}\n indicatorColor=\"primary\"\n textColor=\"primary\"\n variant=\"fullWidth\"\n >\n <Tab label=\"Agent Rules\" {...a11yProps(0)} />\n <Tab label=\"MCP Servers\" {...a11yProps(1)} />\n </Tabs>\n <TabPanel value={value} index={0}>\n <Box className={styles.tabPanel}>\n <AIRulesComponent title={title} />\n </Box>\n </TabPanel>\n <TabPanel value={value} index={1}>\n <Box className={styles.tabPanel}>\n <MCPServersComponent />\n </Box>\n </TabPanel>\n </div>\n );\n};\n\n\n"],"names":[],"mappings":";;;;;;;AAgBA,SAAS,SAAS,KAAA,EAAsB;AACtC,EAAA,MAAM,EAAE,QAAA,EAAU,KAAA,EAAO,KAAA,EAAO,GAAG,OAAM,GAAI,KAAA;AAE7C,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,UAAA;AAAA,MACL,QAAQ,KAAA,KAAU,KAAA;AAAA,MAClB,EAAA,EAAI,4BAA4B,KAAK,CAAA,CAAA;AAAA,MACrC,iBAAA,EAAiB,uBAAuB,KAAK,CAAA,CAAA;AAAA,MAC5C,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA,KAAA,KAAU,KAAA,oBACT,GAAA,CAAC,GAAA,EAAA,EACE,QAAA,EACH;AAAA;AAAA,GAEJ;AAEJ;AAEA,SAAS,UAAU,KAAA,EAAe;AAChC,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,uBAAuB,KAAK,CAAA,CAAA;AAAA,IAChC,eAAA,EAAiB,4BAA4B,KAAK,CAAA;AAAA,GACpD;AACF;AAEA,MAAM,SAAA,GAAY,UAAA,CAAW,CAAC,KAAA,MAAW;AAAA,EACvC,IAAA,EAAM;AAAA,IACJ,KAAA,EAAO,MAAA;AAAA,IACP,eAAA,EAAiB,KAAA,CAAM,OAAA,CAAQ,UAAA,CAAW;AAAA,GAC5C;AAAA,EACA,QAAA,EAAU;AAAA,IACR,OAAA,EAAS,CAAA;AAAA,IACT,SAAA,EAAW,KAAA,CAAM,OAAA,CAAQ,CAAC;AAAA;AAE9B,CAAA,CAAE,CAAA;AAMK,MAAM,uBAAA,GAA0B,CAAC,EAAE,KAAA,GAAQ,mBAAkB,KAAoC;AACtG,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAS,CAAC,CAAA;AAEpC,EAAA,MAAM,YAAA,GAAe,CAAC,MAAA,EAA+B,QAAA,KAAqB;AACxE,IAAA,QAAA,CAAS,QAAQ,CAAA;AAAA,EACnB,CAAA;AAEA,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,IAAA,EACrB,QAAA,EAAA;AAAA,oBAAA,IAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACC,KAAA;AAAA,QACA,QAAA,EAAU,YAAA;AAAA,QACV,cAAA,EAAe,SAAA;AAAA,QACf,SAAA,EAAU,SAAA;AAAA,QACV,OAAA,EAAQ,WAAA;AAAA,QAER,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,OAAI,KAAA,EAAM,aAAA,EAAe,GAAG,SAAA,CAAU,CAAC,CAAA,EAAG,CAAA;AAAA,8BAC1C,GAAA,EAAA,EAAI,KAAA,EAAM,eAAe,GAAG,SAAA,CAAU,CAAC,CAAA,EAAG;AAAA;AAAA;AAAA,KAC7C;AAAA,oBACA,GAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAc,KAAA,EAAO,GAC7B,QAAA,kBAAA,GAAA,CAAC,GAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,QAAA,EACrB,QAAA,kBAAA,GAAA,CAAC,gBAAA,EAAA,EAAiB,KAAA,EAAc,GAClC,CAAA,EACF,CAAA;AAAA,oBACA,GAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAc,KAAA,EAAO,CAAA,EAC7B,QAAA,kBAAA,GAAA,CAAC,GAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,QAAA,EACrB,QAAA,kBAAA,GAAA,CAAC,mBAAA,EAAA,EAAoB,GACvB,CAAA,EACF;AAAA,GAAA,EACF,CAAA;AAEJ;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiRulesComponent.esm.js","sources":["../../../src/components/AiRulesComponent/AiRulesComponent.tsx"],"sourcesContent":["import React from 'react';\nimport { useAiRules } from '../../hooks/useAiRules';\nimport { InfoCard, Progress, EmptyState, MarkdownContent } from '@backstage/core-components';\nimport { Button, makeStyles, useTheme, Typography, Chip, Card, CardContent, Accordion, AccordionSummary, AccordionDetails, FormControlLabel, Checkbox, IconButton, Tooltip } from '@material-ui/core';\nimport { Entity } from '@backstage/catalog-model';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport CodeIcon from '@material-ui/icons/Code';\nimport LaunchIcon from '@material-ui/icons/Launch';\nimport { AIRuleType, AIRule, CursorRule, CopilotRule, ClineRule, ClaudeCodeRule } from '../../types';\nexport interface AIRulesComponentProps {\n title?: string;\n}\n\nexport const isAIRulesAvailable = (entity: Entity): boolean => {\n const sourceAnnotation = entity.metadata?.annotations?.['backstage.io/source-location'] || '';\n return sourceAnnotation.startsWith('url:');\n};\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n '& .MuiAccordion-root': {\n marginBottom: theme.spacing(1),\n '&:before': {\n display: 'none',\n },\n },\n },\n filterSection: {\n marginBottom: theme.spacing(2),\n padding: theme.spacing(2),\n backgroundColor: theme.palette.background.default,\n borderRadius: theme.shape.borderRadius,\n },\n ruleCard: {\n marginBottom: theme.spacing(1),\n border: `1px solid ${theme.palette.divider}`,\n },\n ruleHeader: {\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n width: '100%',\n },\n ruleHeaderContent: {\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n flex: 1,\n },\n ruleType: {\n textTransform: 'uppercase',\n fontWeight: 'bold',\n fontSize: '0.75rem',\n },\n ruleContent: {\n padding: theme.spacing(1),\n borderRadius: theme.shape.borderRadius,\n overflow: 'auto',\n maxHeight: '300px',\n '& > *': {\n backgroundColor: 'transparent !important',\n },\n },\n ruleMetadata: {\n display: 'flex',\n flexWrap: 'wrap',\n gap: theme.spacing(0.5),\n marginBottom: theme.spacing(1),\n },\n statsContainer: {\n display: 'flex',\n gap: theme.spacing(2),\n marginBottom: theme.spacing(2),\n },\n statCard: {\n minWidth: '120px',\n textAlign: 'center',\n },\n emptyStateIcon: {\n fontSize: '4rem',\n color: theme.palette.grey[400],\n },\n filterContainer: {\n display: 'flex',\n flexWrap: 'wrap',\n '& > *': {\n marginRight: theme.spacing(1),\n },\n },\n applyFilterButton: {\n marginTop: theme.spacing(1),\n },\n}));\n\nconst RuleTypeIcon = ({ type }: { type: AIRuleType }) => {\n const colors = {\n [AIRuleType.CURSOR]: '#0066CC',\n [AIRuleType.COPILOT]: '#6F42C1', \n [AIRuleType.CLINE]: '#28A745',\n [AIRuleType.CLAUDE_CODE]: '#FF6B35',\n };\n \n return <CodeIcon style={{ color: colors[type] }} />;\n};\n\nconst renderFrontmatter = (theme: any, frontmatter?: Record<string, any>) => {\n if (!frontmatter || Object.keys(frontmatter).length === 0) {\n return null;\n }\n\n // Filter out fields that are already displayed elsewhere (description, globs)\n const filteredEntries = Object.entries(frontmatter).filter(([key]) => \n !['description', 'globs'].includes(key)\n );\n\n if (filteredEntries.length === 0) {\n return null;\n }\n\n return (\n <div style={{ \n marginBottom: '16px', \n padding: '16px', \n backgroundColor: theme.palette.type === 'dark' ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.05)', \n borderRadius: '8px',\n border: `1px solid ${theme.palette.type === 'dark' ? 'rgba(255,255,255,0.12)' : 'rgba(0,0,0,0.12)'}`\n }}>\n <Typography variant=\"subtitle2\" style={{ \n marginBottom: '12px', \n fontWeight: 'bold',\n color: theme.palette.text.secondary,\n textTransform: 'uppercase',\n letterSpacing: '0.5px'\n }}>\n Metadata\n </Typography>\n {filteredEntries.map(([key, value], index) => (\n <div key={key} style={{ marginBottom: index < filteredEntries.length - 1 ? '12px' : '0' }}>\n <Typography variant=\"body2\" style={{ \n fontWeight: 'bold',\n textTransform: 'capitalize',\n color: theme.palette.primary.main,\n marginBottom: '4px'\n }}>\n {key}:\n </Typography>\n <Typography variant=\"body2\" style={{ \n lineHeight: '1.5',\n marginLeft: '8px',\n color: theme.palette.text.primary\n }}>\n {Array.isArray(value) ? value.join(', ') : String(value)}\n </Typography>\n </div>\n ))}\n </div>\n );\n};\n\n// Helper function to parse cursor rule content manually\nconst parseCursorContent = (content: string) => {\n return manualParseFrontmatter(content);\n};\n\n// Manual frontmatter parsing as fallback\nconst manualParseFrontmatter = (content: string) => {\n // Check if content starts with ---\n if (!content.trim().startsWith('---')) {\n return {\n frontmatter: undefined,\n content: content\n };\n }\n\n try {\n // Split by lines\n const lines = content.split('\\n');\n let frontmatterEndIndex = -1;\n \n // Find the closing ---\n for (let i = 1; i < lines.length; i++) {\n if (lines[i].trim() === '---') {\n frontmatterEndIndex = i;\n break;\n }\n }\n \n if (frontmatterEndIndex === -1) {\n return {\n frontmatter: undefined,\n content: content\n };\n }\n \n // Extract frontmatter lines (between the --- markers)\n const frontmatterLines = lines.slice(1, frontmatterEndIndex);\n const contentLines = lines.slice(frontmatterEndIndex + 1);\n \n // Parse the YAML manually (simple key: value pairs)\n const frontmatter: Record<string, any> = {};\n for (const line of frontmatterLines) {\n const trimmedLine = line.trim();\n if (trimmedLine && trimmedLine.includes(':')) {\n const colonIndex = trimmedLine.indexOf(':');\n const key = trimmedLine.substring(0, colonIndex).trim();\n const value = trimmedLine.substring(colonIndex + 1).trim();\n frontmatter[key] = value;\n }\n }\n \n return {\n frontmatter: Object.keys(frontmatter).length > 0 ? frontmatter : undefined,\n content: contentLines.join('\\n').trim()\n };\n } catch (error) {\n return {\n frontmatter: undefined,\n content: content\n };\n }\n};\n\nconst constructFileUrl = (gitUrl: string, filePath: string): string => {\n // Remove trailing slashes from gitUrl\n const cleanGitUrl = gitUrl.replace(/\\/+$/, '');\n \n // For GitHub URLs, convert to blob view\n if (cleanGitUrl.includes('github.com')) {\n return `${cleanGitUrl}/blob/main/${filePath}`;\n }\n \n // For GitLab URLs, convert to blob view\n if (cleanGitUrl.includes('gitlab.com')) {\n return `${cleanGitUrl}/-/blob/main/${filePath}`;\n }\n \n // For other git providers, try generic blob URL\n return `${cleanGitUrl}/blob/main/${filePath}`;\n};\n\nconst RuleComponent = ({ rule }: { rule: AIRule }) => {\n const styles = useStyles();\n const theme = useTheme();\n \n const renderCursorRule = (rule: CursorRule) => {\n // Parse the raw content to extract frontmatter and clean content\n const { frontmatter, content } = parseCursorContent(rule.content);\n \n return (\n <Accordion className={styles.ruleCard}>\n <AccordionSummary expandIcon={<ExpandMoreIcon />}>\n <div className={styles.ruleHeader}>\n <div className={styles.ruleHeaderContent}>\n <RuleTypeIcon type={rule.type} />\n <Typography variant=\"h6\">{rule.fileName}</Typography>\n <Chip label={rule.type} size=\"small\" className={styles.ruleType} />\n {frontmatter?.description && (\n <Typography variant=\"body2\" style={{ marginLeft: 8, color: theme.palette.text.secondary }}>\n {frontmatter.description}\n </Typography>\n )}\n </div>\n {rule.gitUrl && (\n <Tooltip title=\"Open file in repository\">\n <IconButton\n size=\"small\"\n onClick={(e) => {\n e.stopPropagation();\n window.open(constructFileUrl(rule.gitUrl!, rule.filePath), '_blank');\n }}\n >\n <LaunchIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n )}\n </div>\n </AccordionSummary>\n <AccordionDetails>\n <div>\n <div className={styles.ruleMetadata}>\n <Chip label={`Path: ${rule.filePath}`} size=\"small\" variant=\"outlined\" />\n {frontmatter?.globs && (\n <Chip label={`Globs: ${Array.isArray(frontmatter.globs) ? frontmatter.globs.join(', ') : frontmatter.globs}`} size=\"small\" variant=\"outlined\" />\n )}\n </div>\n {renderFrontmatter(theme, frontmatter)}\n <div className={styles.ruleContent}>\n <MarkdownContent content={content} />\n </div>\n </div>\n </AccordionDetails>\n </Accordion>\n );\n };\n\n const renderCopilotRule = (rule: CopilotRule) => {\n // Get rule number from either order (legacy) or extract from filename\n const ruleNumber = rule.order || (rule.fileName.match(/Rule (\\d+)/) || [])[1] || rule.id.split('-').pop();\n \n return (\n <Accordion className={styles.ruleCard}>\n <AccordionSummary expandIcon={<ExpandMoreIcon />}>\n <div className={styles.ruleHeader}>\n <div className={styles.ruleHeaderContent}>\n <RuleTypeIcon type={rule.type} />\n <Typography variant=\"h6\">\n {rule.title || `Copilot Rule #${ruleNumber}`}\n </Typography>\n <Chip label={rule.type} size=\"small\" className={styles.ruleType} />\n {rule.applyTo && (\n <Chip \n label={`Applies to: ${rule.applyTo}`} \n size=\"small\" \n variant=\"outlined\" \n style={{ marginLeft: 8 }}\n />\n )}\n </div>\n {rule.gitUrl && (\n <Tooltip title=\"Open file in repository\">\n <IconButton\n size=\"small\"\n onClick={(e) => {\n e.stopPropagation();\n window.open(constructFileUrl(rule.gitUrl!, rule.filePath), '_blank');\n }}\n >\n <LaunchIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n )}\n </div>\n </AccordionSummary>\n <AccordionDetails>\n <div>\n <div className={styles.ruleMetadata}>\n <Chip label={`Path: ${rule.filePath}`} size=\"small\" variant=\"outlined\" />\n {rule.frontmatter && renderFrontmatter(theme, rule.frontmatter)}\n </div>\n <div className={styles.ruleContent}>\n <MarkdownContent content={rule.content} />\n </div>\n </div>\n </AccordionDetails>\n </Accordion>\n );\n };\n\n const renderClineRule = (rule: ClineRule) => (\n <Accordion className={styles.ruleCard}>\n <AccordionSummary expandIcon={<ExpandMoreIcon />}>\n <div className={styles.ruleHeader}>\n <div className={styles.ruleHeaderContent}>\n <RuleTypeIcon type={rule.type} />\n <Typography variant=\"h6\">{rule.title || rule.fileName}</Typography>\n <Chip label={rule.type} size=\"small\" className={styles.ruleType} />\n </div>\n {rule.gitUrl && (\n <Tooltip title=\"Open file in repository\">\n <IconButton\n size=\"small\"\n onClick={(e) => {\n e.stopPropagation();\n window.open(constructFileUrl(rule.gitUrl!, rule.filePath), '_blank');\n }}\n >\n <LaunchIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n )}\n </div>\n </AccordionSummary>\n <AccordionDetails>\n <div>\n <div className={styles.ruleMetadata}>\n <Chip label={`Path: ${rule.filePath}`} size=\"small\" variant=\"outlined\" />\n </div>\n <div className={styles.ruleContent}>\n <MarkdownContent content={rule.content} />\n </div>\n </div>\n </AccordionDetails>\n </Accordion>\n );\n\n const renderClaudeCodeRule = (rule: ClaudeCodeRule) => (\n <Accordion className={styles.ruleCard}>\n <AccordionSummary expandIcon={<ExpandMoreIcon />}>\n <div className={styles.ruleHeader}>\n <div className={styles.ruleHeaderContent}>\n <RuleTypeIcon type={rule.type} />\n <Typography variant=\"h6\">{rule.title || rule.fileName}</Typography>\n <Chip label={rule.type} size=\"small\" className={styles.ruleType} />\n </div>\n {rule.gitUrl && (\n <Tooltip title=\"Open file in repository\">\n <IconButton\n size=\"small\"\n onClick={(e) => {\n e.stopPropagation();\n window.open(constructFileUrl(rule.gitUrl!, rule.filePath), '_blank');\n }}\n >\n <LaunchIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n )}\n </div>\n </AccordionSummary>\n <AccordionDetails>\n <div>\n <div className={styles.ruleMetadata}>\n <Chip label={`Path: ${rule.filePath}`} size=\"small\" variant=\"outlined\" />\n </div>\n <div className={styles.ruleContent}>\n <MarkdownContent content={rule.content} />\n </div>\n </div>\n </AccordionDetails>\n </Accordion>\n );\n\n switch (rule.type) {\n case AIRuleType.CURSOR:\n return renderCursorRule(rule as CursorRule);\n case AIRuleType.CLAUDE_CODE:\n return renderClaudeCodeRule(rule as ClaudeCodeRule);\n case AIRuleType.COPILOT:\n return renderCopilotRule(rule as CopilotRule);\n case AIRuleType.CLINE:\n return renderClineRule(rule as ClineRule);\n default:\n return null;\n }\n};\n\nexport const AIRulesComponent: React.FC<AIRulesComponentProps> = ({ title = \"AI Coding Rules\" } = {}) => {\n const { rulesByType, loading, error, hasGitUrl, totalRules, allowedRuleTypes, selectedRuleTypes, setSelectedRuleTypes, applyFilters, resetFilters, hasUnappliedChanges, hasSearched } = useAiRules();\n const styles = useStyles();\n \n // Define the desired rendering order\n const ruleTypeDisplayOrder = [AIRuleType.CURSOR, AIRuleType.CLAUDE_CODE, AIRuleType.COPILOT, AIRuleType.CLINE];\n \n // Helper function to format rule type names for display\n const formatRuleTypeName = (type: AIRuleType): string => {\n switch (type) {\n case AIRuleType.CURSOR:\n return 'Cursor';\n case AIRuleType.CLAUDE_CODE:\n return 'Claude Code';\n case AIRuleType.COPILOT:\n return 'Copilot';\n case AIRuleType.CLINE:\n return 'Cline';\n }\n };\n const handleTypeToggle = (type: AIRuleType, checked: boolean) => {\n const newTypes = checked \n ? [...selectedRuleTypes, type]\n : selectedRuleTypes.filter(t => t !== type);\n setSelectedRuleTypes(newTypes);\n };\n\n if (loading) {\n return (\n <InfoCard title={title}>\n <Progress />\n </InfoCard>\n );\n }\n\n if (!hasGitUrl) {\n return (\n <InfoCard title={title}>\n <EmptyState\n missing=\"content\"\n title=\"No Git Repository\"\n description=\"This component doesn't have a Git source URL configured.\"\n />\n </InfoCard>\n );\n }\n\n if (error) {\n return (\n <InfoCard title={title}>\n <EmptyState\n missing=\"content\"\n title=\"Error Loading Rules\"\n description={error}\n />\n </InfoCard>\n );\n }\n\n return (\n <InfoCard title={title} className={styles.root}>\n <div className={styles.filterSection}>\n <Typography variant=\"h6\" gutterBottom>\n Filter Rule Types\n </Typography>\n <div className={styles.filterContainer}>\n {allowedRuleTypes.map(type => (\n <FormControlLabel\n key={type}\n control={\n <Checkbox\n checked={selectedRuleTypes.includes(type)}\n onChange={(e) => handleTypeToggle(type, e.target.checked)}\n />\n }\n label={formatRuleTypeName(type)}\n />\n ))}\n </div>\n <div className={styles.applyFilterButton}>\n <Button\n variant=\"contained\"\n color=\"primary\"\n onClick={applyFilters}\n disabled={!hasUnappliedChanges}\n >\n Apply Filter\n </Button>\n {hasUnappliedChanges && (\n <Typography variant=\"body2\" color=\"textSecondary\" style={{ marginTop: 8 }}>\n You have unsaved filter changes. Click \"Apply Filter\" to update the results.\n </Typography>\n )}\n {!hasUnappliedChanges && selectedRuleTypes.length === 0 && (\n <Typography variant=\"body2\" color=\"textSecondary\" style={{ marginTop: 8 }}>\n Select at least one rule type to search for AI rules.\n </Typography>\n )}\n </div>\n </div>\n\n {hasSearched && totalRules === 0 ? (\n <EmptyState\n missing=\"content\"\n title=\"No AI Rules Found\"\n description=\"No AI rules were found in this repository for the selected rule types.\"\n action={\n <Button\n variant=\"outlined\"\n onClick={resetFilters}\n >\n Reset Filters\n </Button>\n }\n />\n ) : totalRules > 0 ? (\n <>\n <div className={styles.statsContainer}>\n <Card className={styles.statCard}>\n <CardContent>\n <Typography variant=\"h4\">{totalRules}</Typography>\n <Typography color=\"textSecondary\">Total Rules</Typography>\n </CardContent>\n </Card>\n {ruleTypeDisplayOrder.map(type => {\n const typeRules = rulesByType[type] || [];\n if (typeRules.length === 0) return null;\n return (\n <Card key={type} className={styles.statCard}>\n <CardContent>\n <Typography variant=\"h4\">{typeRules.length}</Typography>\n <Typography color=\"textSecondary\">{formatRuleTypeName(type)}</Typography>\n </CardContent>\n </Card>\n );\n })}\n </div>\n\n {ruleTypeDisplayOrder.map(type => {\n const typeRules = rulesByType[type] || [];\n if (typeRules.length === 0) return null;\n return (\n <div key={type}>\n <Typography variant=\"h5\" gutterBottom style={{ marginTop: 16 }}>\n {formatRuleTypeName(type)} Rules ({typeRules.length})\n </Typography>\n {typeRules.map(rule => (\n <RuleComponent key={rule.id} rule={rule} />\n ))}\n </div>\n );\n })}\n </>\n ) : (\n <div style={{ marginTop: 16 }}>\n <Typography variant=\"body1\" color=\"textSecondary\">\n Select rule types above and click \"Apply Filter\" to search for AI coding rules in this repository.\n </Typography>\n </div>\n )}\n </InfoCard>\n );\n};"],"names":["rule"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AiRulesComponent.esm.js","sources":["../../../src/components/AiRulesComponent/AiRulesComponent.tsx"],"sourcesContent":["import React from 'react';\nimport { useAiRules } from '../../hooks/useAiRules';\nimport { InfoCard, Progress, EmptyState, MarkdownContent } from '@backstage/core-components';\nimport { Button, makeStyles, useTheme, Typography, Chip, Card, CardContent, Accordion, AccordionSummary, AccordionDetails, FormControlLabel, Checkbox, IconButton, Tooltip } from '@material-ui/core';\nimport { Entity } from '@backstage/catalog-model';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport CodeIcon from '@material-ui/icons/Code';\nimport LaunchIcon from '@material-ui/icons/Launch';\nimport { AIRuleType, AIRule, CursorRule, CopilotRule, ClineRule, ClaudeCodeRule } from '../../types';\nexport interface AIRulesComponentProps {\n title?: string;\n}\n\nexport const isAIRulesAvailable = (entity: Entity): boolean => {\n const sourceAnnotation = entity.metadata?.annotations?.['backstage.io/source-location'] || '';\n return sourceAnnotation.startsWith('url:');\n};\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n '& .MuiAccordion-root': {\n marginBottom: theme.spacing(1),\n '&:before': {\n display: 'none',\n },\n },\n },\n filterSection: {\n marginBottom: theme.spacing(2),\n padding: theme.spacing(2),\n backgroundColor: theme.palette.background.default,\n borderRadius: theme.shape.borderRadius,\n },\n ruleCard: {\n marginBottom: theme.spacing(1),\n border: `1px solid ${theme.palette.divider}`,\n },\n ruleHeader: {\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n width: '100%',\n },\n ruleHeaderContent: {\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n flex: 1,\n },\n ruleType: {\n textTransform: 'uppercase',\n fontWeight: 'bold',\n fontSize: '0.75rem',\n },\n ruleContent: {\n padding: theme.spacing(1),\n borderRadius: theme.shape.borderRadius,\n overflow: 'auto',\n maxHeight: '300px',\n '& > *': {\n backgroundColor: 'transparent !important',\n },\n },\n ruleMetadata: {\n display: 'flex',\n flexWrap: 'wrap',\n gap: theme.spacing(0.5),\n marginBottom: theme.spacing(1),\n },\n statsContainer: {\n display: 'flex',\n gap: theme.spacing(2),\n marginBottom: theme.spacing(2),\n },\n statCard: {\n minWidth: '120px',\n textAlign: 'center',\n },\n emptyStateIcon: {\n fontSize: '4rem',\n color: theme.palette.grey[400],\n },\n filterContainer: {\n display: 'flex',\n flexWrap: 'wrap',\n '& > *': {\n marginRight: theme.spacing(1),\n },\n },\n applyFilterButton: {\n marginTop: theme.spacing(1),\n },\n}));\n\nconst RuleTypeIcon = ({ type }: { type: AIRuleType }) => {\n const colors = {\n [AIRuleType.CURSOR]: '#0066CC',\n [AIRuleType.COPILOT]: '#6F42C1', \n [AIRuleType.CLINE]: '#28A745',\n [AIRuleType.CLAUDE_CODE]: '#FF6B35',\n };\n \n return <CodeIcon style={{ color: colors[type] }} />;\n};\n\nconst renderFrontmatter = (theme: any, frontmatter?: Record<string, any>) => {\n if (!frontmatter || Object.keys(frontmatter).length === 0) {\n return null;\n }\n\n // Filter out fields that are already displayed elsewhere (description, globs)\n const filteredEntries = Object.entries(frontmatter).filter(([key]) => \n !['description', 'globs'].includes(key)\n );\n\n if (filteredEntries.length === 0) {\n return null;\n }\n\n return (\n <div style={{ \n marginBottom: '16px', \n padding: '16px', \n backgroundColor: theme.palette.type === 'dark' ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.05)', \n borderRadius: '8px',\n border: `1px solid ${theme.palette.type === 'dark' ? 'rgba(255,255,255,0.12)' : 'rgba(0,0,0,0.12)'}`\n }}>\n <Typography variant=\"subtitle2\" style={{ \n marginBottom: '12px', \n fontWeight: 'bold',\n color: theme.palette.text.secondary,\n textTransform: 'uppercase',\n letterSpacing: '0.5px'\n }}>\n Metadata\n </Typography>\n {filteredEntries.map(([key, value], index) => (\n <div key={key} style={{ marginBottom: index < filteredEntries.length - 1 ? '12px' : '0' }}>\n <Typography variant=\"body2\" style={{ \n fontWeight: 'bold',\n textTransform: 'capitalize',\n color: theme.palette.primary.main,\n marginBottom: '4px'\n }}>\n {key}:\n </Typography>\n <Typography variant=\"body2\" style={{ \n lineHeight: '1.5',\n marginLeft: '8px',\n color: theme.palette.text.primary\n }}>\n {Array.isArray(value) ? value.join(', ') : String(value)}\n </Typography>\n </div>\n ))}\n </div>\n );\n};\n\n// Helper function to parse cursor rule content manually\nconst parseCursorContent = (content: string) => {\n return manualParseFrontmatter(content);\n};\n\n// Manual frontmatter parsing as fallback\nconst manualParseFrontmatter = (content: string) => {\n // Check if content starts with ---\n if (!content.trim().startsWith('---')) {\n return {\n frontmatter: undefined,\n content: content\n };\n }\n\n try {\n // Split by lines\n const lines = content.split('\\n');\n let frontmatterEndIndex = -1;\n \n // Find the closing ---\n for (let i = 1; i < lines.length; i++) {\n if (lines[i].trim() === '---') {\n frontmatterEndIndex = i;\n break;\n }\n }\n \n if (frontmatterEndIndex === -1) {\n return {\n frontmatter: undefined,\n content: content\n };\n }\n \n // Extract frontmatter lines (between the --- markers)\n const frontmatterLines = lines.slice(1, frontmatterEndIndex);\n const contentLines = lines.slice(frontmatterEndIndex + 1);\n \n // Parse the YAML manually (simple key: value pairs)\n const frontmatter: Record<string, any> = {};\n for (const line of frontmatterLines) {\n const trimmedLine = line.trim();\n if (trimmedLine && trimmedLine.includes(':')) {\n const colonIndex = trimmedLine.indexOf(':');\n const key = trimmedLine.substring(0, colonIndex).trim();\n const value = trimmedLine.substring(colonIndex + 1).trim();\n frontmatter[key] = value;\n }\n }\n \n return {\n frontmatter: Object.keys(frontmatter).length > 0 ? frontmatter : undefined,\n content: contentLines.join('\\n').trim()\n };\n } catch (error) {\n return {\n frontmatter: undefined,\n content: content\n };\n }\n};\n\nconst constructFileUrl = (gitUrl: string, filePath: string): string => {\n // Remove trailing slashes from gitUrl\n const cleanGitUrl = gitUrl.replace(/\\/+$/, '');\n \n // For GitHub URLs, convert to blob view\n if (cleanGitUrl.includes('github.com')) {\n return `${cleanGitUrl}/blob/main/${filePath}`;\n }\n \n // For GitLab URLs, convert to blob view\n if (cleanGitUrl.includes('gitlab.com')) {\n return `${cleanGitUrl}/-/blob/main/${filePath}`;\n }\n \n // For other git providers, try generic blob URL\n return `${cleanGitUrl}/blob/main/${filePath}`;\n};\n\nconst RuleComponent = ({ rule }: { rule: AIRule }) => {\n const styles = useStyles();\n const theme = useTheme();\n \n const renderCursorRule = (rule: CursorRule) => {\n // Parse the raw content to extract frontmatter and clean content\n const { frontmatter, content } = parseCursorContent(rule.content);\n \n return (\n <Accordion className={styles.ruleCard}>\n <AccordionSummary expandIcon={<ExpandMoreIcon />}>\n <div className={styles.ruleHeader}>\n <div className={styles.ruleHeaderContent}>\n <RuleTypeIcon type={rule.type} />\n <Typography variant=\"h6\">{rule.fileName}</Typography>\n <Chip label={rule.type} size=\"small\" className={styles.ruleType} />\n {frontmatter?.description && (\n <Typography variant=\"body2\" style={{ marginLeft: 8, color: theme.palette.text.secondary }}>\n {frontmatter.description}\n </Typography>\n )}\n </div>\n {rule.gitUrl && (\n <Tooltip title=\"Open file in repository\">\n <IconButton\n size=\"small\"\n onClick={(e) => {\n e.stopPropagation();\n window.open(constructFileUrl(rule.gitUrl!, rule.filePath), '_blank');\n }}\n >\n <LaunchIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n )}\n </div>\n </AccordionSummary>\n <AccordionDetails>\n <div>\n <div className={styles.ruleMetadata}>\n <Chip label={`Path: ${rule.filePath}`} size=\"small\" variant=\"outlined\" />\n {frontmatter?.globs && (\n <Chip label={`Globs: ${Array.isArray(frontmatter.globs) ? frontmatter.globs.join(', ') : frontmatter.globs}`} size=\"small\" variant=\"outlined\" />\n )}\n </div>\n {renderFrontmatter(theme, frontmatter)}\n <div className={styles.ruleContent}>\n <MarkdownContent content={content} />\n </div>\n </div>\n </AccordionDetails>\n </Accordion>\n );\n };\n\n const renderCopilotRule = (rule: CopilotRule) => {\n // Get rule number from either order (legacy) or extract from filename\n const ruleNumber = rule.order || (rule.fileName.match(/Rule (\\d+)/) || [])[1] || rule.id.split('-').pop();\n \n return (\n <Accordion className={styles.ruleCard}>\n <AccordionSummary expandIcon={<ExpandMoreIcon />}>\n <div className={styles.ruleHeader}>\n <div className={styles.ruleHeaderContent}>\n <RuleTypeIcon type={rule.type} />\n <Typography variant=\"h6\">\n {rule.title || `Copilot Rule #${ruleNumber}`}\n </Typography>\n <Chip label={rule.type} size=\"small\" className={styles.ruleType} />\n {rule.applyTo && (\n <Chip \n label={`Applies to: ${rule.applyTo}`} \n size=\"small\" \n variant=\"outlined\" \n style={{ marginLeft: 8 }}\n />\n )}\n </div>\n {rule.gitUrl && (\n <Tooltip title=\"Open file in repository\">\n <IconButton\n size=\"small\"\n onClick={(e) => {\n e.stopPropagation();\n window.open(constructFileUrl(rule.gitUrl!, rule.filePath), '_blank');\n }}\n >\n <LaunchIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n )}\n </div>\n </AccordionSummary>\n <AccordionDetails>\n <div>\n <div className={styles.ruleMetadata}>\n <Chip label={`Path: ${rule.filePath}`} size=\"small\" variant=\"outlined\" />\n {rule.frontmatter && renderFrontmatter(theme, rule.frontmatter)}\n </div>\n <div className={styles.ruleContent}>\n <MarkdownContent content={rule.content} />\n </div>\n </div>\n </AccordionDetails>\n </Accordion>\n );\n };\n\n const renderClineRule = (rule: ClineRule) => (\n <Accordion className={styles.ruleCard}>\n <AccordionSummary expandIcon={<ExpandMoreIcon />}>\n <div className={styles.ruleHeader}>\n <div className={styles.ruleHeaderContent}>\n <RuleTypeIcon type={rule.type} />\n <Typography variant=\"h6\">{rule.title || rule.fileName}</Typography>\n <Chip label={rule.type} size=\"small\" className={styles.ruleType} />\n </div>\n {rule.gitUrl && (\n <Tooltip title=\"Open file in repository\">\n <IconButton\n size=\"small\"\n onClick={(e) => {\n e.stopPropagation();\n window.open(constructFileUrl(rule.gitUrl!, rule.filePath), '_blank');\n }}\n >\n <LaunchIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n )}\n </div>\n </AccordionSummary>\n <AccordionDetails>\n <div>\n <div className={styles.ruleMetadata}>\n <Chip label={`Path: ${rule.filePath}`} size=\"small\" variant=\"outlined\" />\n </div>\n <div className={styles.ruleContent}>\n <MarkdownContent content={rule.content} />\n </div>\n </div>\n </AccordionDetails>\n </Accordion>\n );\n\n const renderClaudeCodeRule = (rule: ClaudeCodeRule) => (\n <Accordion className={styles.ruleCard}>\n <AccordionSummary expandIcon={<ExpandMoreIcon />}>\n <div className={styles.ruleHeader}>\n <div className={styles.ruleHeaderContent}>\n <RuleTypeIcon type={rule.type} />\n <Typography variant=\"h6\">{rule.title || rule.fileName}</Typography>\n <Chip label={rule.type} size=\"small\" className={styles.ruleType} />\n </div>\n {rule.gitUrl && (\n <Tooltip title=\"Open file in repository\">\n <IconButton\n size=\"small\"\n onClick={(e) => {\n e.stopPropagation();\n window.open(constructFileUrl(rule.gitUrl!, rule.filePath), '_blank');\n }}\n >\n <LaunchIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n )}\n </div>\n </AccordionSummary>\n <AccordionDetails>\n <div>\n <div className={styles.ruleMetadata}>\n <Chip label={`Path: ${rule.filePath}`} size=\"small\" variant=\"outlined\" />\n </div>\n <div className={styles.ruleContent}>\n <MarkdownContent content={rule.content} />\n </div>\n </div>\n </AccordionDetails>\n </Accordion>\n );\n\n switch (rule.type) {\n case AIRuleType.CURSOR:\n return renderCursorRule(rule as CursorRule);\n case AIRuleType.CLAUDE_CODE:\n return renderClaudeCodeRule(rule as ClaudeCodeRule);\n case AIRuleType.COPILOT:\n return renderCopilotRule(rule as CopilotRule);\n case AIRuleType.CLINE:\n return renderClineRule(rule as ClineRule);\n default:\n return null;\n }\n};\n\nexport const AIRulesComponent: React.FC<AIRulesComponentProps> = ({ title = \"AI Coding Rules\" } = {}) => {\n const { rulesByType, loading, error, hasGitUrl, totalRules, allowedRuleTypes, selectedRuleTypes, setSelectedRuleTypes, applyFilters, resetFilters, hasUnappliedChanges, hasSearched } = useAiRules();\n const styles = useStyles();\n \n // Define the desired rendering order\n const ruleTypeDisplayOrder = [AIRuleType.CURSOR, AIRuleType.CLAUDE_CODE, AIRuleType.COPILOT, AIRuleType.CLINE];\n \n // Helper function to format rule type names for display\n const formatRuleTypeName = (type: AIRuleType): string => {\n switch (type) {\n case AIRuleType.CURSOR:\n return 'Cursor';\n case AIRuleType.CLAUDE_CODE:\n return 'Claude Code';\n case AIRuleType.COPILOT:\n return 'Copilot';\n case AIRuleType.CLINE:\n return 'Cline';\n }\n };\n const handleTypeToggle = (type: AIRuleType, checked: boolean) => {\n const newTypes = checked \n ? [...selectedRuleTypes, type]\n : selectedRuleTypes.filter(t => t !== type);\n setSelectedRuleTypes(newTypes);\n };\n\n if (loading) {\n return (\n <InfoCard title={title}>\n <Progress />\n </InfoCard>\n );\n }\n\n if (!hasGitUrl) {\n return (\n <InfoCard title={title}>\n <EmptyState\n missing=\"content\"\n title=\"No Git Repository\"\n description=\"This component doesn't have a Git source URL configured.\"\n />\n </InfoCard>\n );\n }\n\n if (error) {\n return (\n <InfoCard title={title}>\n <EmptyState\n missing=\"content\"\n title=\"Error Loading Rules\"\n description={error}\n />\n </InfoCard>\n );\n }\n\n return (\n <InfoCard title={title} className={styles.root}>\n <div className={styles.filterSection}>\n <Typography variant=\"h6\" gutterBottom>\n Filter Rule Types\n </Typography>\n <div className={styles.filterContainer}>\n {allowedRuleTypes.map(type => (\n <FormControlLabel\n key={type}\n control={\n <Checkbox\n checked={selectedRuleTypes.includes(type)}\n onChange={(e) => handleTypeToggle(type, e.target.checked)}\n />\n }\n label={formatRuleTypeName(type)}\n />\n ))}\n </div>\n <div className={styles.applyFilterButton}>\n <Button\n variant=\"contained\"\n color=\"primary\"\n onClick={applyFilters}\n disabled={!hasUnappliedChanges}\n >\n Apply Filter\n </Button>\n {hasUnappliedChanges && (\n <Typography variant=\"body2\" color=\"textSecondary\" style={{ marginTop: 8 }}>\n You have unsaved filter changes. Click \"Apply Filter\" to update the results.\n </Typography>\n )}\n {!hasUnappliedChanges && selectedRuleTypes.length === 0 && (\n <Typography variant=\"body2\" color=\"textSecondary\" style={{ marginTop: 8 }}>\n Select at least one rule type to search for AI rules.\n </Typography>\n )}\n </div>\n </div>\n\n {hasSearched && totalRules === 0 ? (\n <EmptyState\n missing=\"content\"\n title=\"No AI Rules Found\"\n description=\"No AI rules were found in this repository for the selected rule types.\"\n action={\n <Button\n variant=\"outlined\"\n onClick={resetFilters}\n >\n Reset Filters\n </Button>\n }\n />\n ) : totalRules > 0 ? (\n <>\n <div className={styles.statsContainer}>\n <Card className={styles.statCard}>\n <CardContent>\n <Typography variant=\"h4\">{totalRules}</Typography>\n <Typography color=\"textSecondary\">Total Rules</Typography>\n </CardContent>\n </Card>\n {ruleTypeDisplayOrder.map(type => {\n const typeRules = rulesByType[type] || [];\n if (typeRules.length === 0) return null;\n return (\n <Card key={type} className={styles.statCard}>\n <CardContent>\n <Typography variant=\"h4\">{typeRules.length}</Typography>\n <Typography color=\"textSecondary\">{formatRuleTypeName(type)}</Typography>\n </CardContent>\n </Card>\n );\n })}\n </div>\n\n {ruleTypeDisplayOrder.map(type => {\n const typeRules = rulesByType[type] || [];\n if (typeRules.length === 0) return null;\n return (\n <div key={type}>\n <Typography variant=\"h5\" gutterBottom style={{ marginTop: 16 }}>\n {formatRuleTypeName(type)} Rules ({typeRules.length})\n </Typography>\n {typeRules.map(rule => (\n <RuleComponent key={rule.id} rule={rule} />\n ))}\n </div>\n );\n })}\n </>\n ) : (\n <div style={{ marginTop: 16 }}>\n <Typography variant=\"body1\" color=\"textSecondary\">\n Select rule types above and click \"Apply Filter\" to search for AI coding rules in this repository.\n </Typography>\n </div>\n )}\n </InfoCard>\n );\n};"],"names":["rule"],"mappings":";;;;;;;;;AAaO,MAAM,kBAAA,GAAqB,CAAC,MAAA,KAA4B;AAC7D,EAAA,MAAM,gBAAA,GAAmB,MAAA,CAAO,QAAA,EAAU,WAAA,GAAc,8BAA8B,CAAA,IAAK,EAAA;AAC3F,EAAA,OAAO,gBAAA,CAAiB,WAAW,MAAM,CAAA;AAC3C;AAEA,MAAM,SAAA,GAAY,UAAA,CAAW,CAAC,KAAA,MAAW;AAAA,EACvC,IAAA,EAAM;AAAA,IACJ,sBAAA,EAAwB;AAAA,MACtB,YAAA,EAAc,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA;AAAA,MAC7B,UAAA,EAAY;AAAA,QACV,OAAA,EAAS;AAAA;AACX;AACF,GACF;AAAA,EACA,aAAA,EAAe;AAAA,IACb,YAAA,EAAc,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA;AAAA,IAC7B,OAAA,EAAS,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA;AAAA,IACxB,eAAA,EAAiB,KAAA,CAAM,OAAA,CAAQ,UAAA,CAAW,OAAA;AAAA,IAC1C,YAAA,EAAc,MAAM,KAAA,CAAM;AAAA,GAC5B;AAAA,EACA,QAAA,EAAU;AAAA,IACR,YAAA,EAAc,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA;AAAA,IAC7B,MAAA,EAAQ,CAAA,UAAA,EAAa,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA;AAAA,GAC5C;AAAA,EACA,UAAA,EAAY;AAAA,IACV,OAAA,EAAS,MAAA;AAAA,IACT,UAAA,EAAY,QAAA;AAAA,IACZ,GAAA,EAAK,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA;AAAA,IACpB,KAAA,EAAO;AAAA,GACT;AAAA,EACA,iBAAA,EAAmB;AAAA,IACjB,OAAA,EAAS,MAAA;AAAA,IACT,UAAA,EAAY,QAAA;AAAA,IACZ,GAAA,EAAK,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA;AAAA,IACpB,IAAA,EAAM;AAAA,GACR;AAAA,EACA,QAAA,EAAU;AAAA,IACR,aAAA,EAAe,WAAA;AAAA,IACf,UAAA,EAAY,MAAA;AAAA,IACZ,QAAA,EAAU;AAAA,GACZ;AAAA,EACA,WAAA,EAAa;AAAA,IACX,OAAA,EAAS,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA;AAAA,IACxB,YAAA,EAAc,MAAM,KAAA,CAAM,YAAA;AAAA,IAC1B,QAAA,EAAU,MAAA;AAAA,IACV,SAAA,EAAW,OAAA;AAAA,IACX,OAAA,EAAS;AAAA,MACP,eAAA,EAAiB;AAAA;AACnB,GACF;AAAA,EACA,YAAA,EAAc;AAAA,IACZ,OAAA,EAAS,MAAA;AAAA,IACT,QAAA,EAAU,MAAA;AAAA,IACV,GAAA,EAAK,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA;AAAA,IACtB,YAAA,EAAc,KAAA,CAAM,OAAA,CAAQ,CAAC;AAAA,GAC/B;AAAA,EACA,cAAA,EAAgB;AAAA,IACd,OAAA,EAAS,MAAA;AAAA,IACT,GAAA,EAAK,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA;AAAA,IACpB,YAAA,EAAc,KAAA,CAAM,OAAA,CAAQ,CAAC;AAAA,GAC/B;AAAA,EACA,QAAA,EAAU;AAAA,IACR,QAAA,EAAU,OAAA;AAAA,IACV,SAAA,EAAW;AAAA,GACb;AAAA,EACA,cAAA,EAAgB;AAAA,IACd,QAAA,EAAU,MAAA;AAAA,IACV,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,GAAG;AAAA,GAC/B;AAAA,EACA,eAAA,EAAiB;AAAA,IACf,OAAA,EAAS,MAAA;AAAA,IACT,QAAA,EAAU,MAAA;AAAA,IACV,OAAA,EAAS;AAAA,MACP,WAAA,EAAa,KAAA,CAAM,OAAA,CAAQ,CAAC;AAAA;AAC9B,GACF;AAAA,EACA,iBAAA,EAAmB;AAAA,IACjB,SAAA,EAAW,KAAA,CAAM,OAAA,CAAQ,CAAC;AAAA;AAE9B,CAAA,CAAE,CAAA;AAEF,MAAM,YAAA,GAAe,CAAC,EAAE,IAAA,EAAK,KAA4B;AACvD,EAAA,MAAM,MAAA,GAAS;AAAA,IACb,CAAC,UAAA,CAAW,MAAM,GAAG,SAAA;AAAA,IACrB,CAAC,UAAA,CAAW,OAAO,GAAG,SAAA;AAAA,IACtB,CAAC,UAAA,CAAW,KAAK,GAAG,SAAA;AAAA,IACpB,CAAC,UAAA,CAAW,WAAW,GAAG;AAAA,GAC5B;AAEA,EAAA,uBAAO,GAAA,CAAC,YAAS,KAAA,EAAO,EAAE,OAAO,MAAA,CAAO,IAAI,GAAE,EAAG,CAAA;AACnD,CAAA;AAEA,MAAM,iBAAA,GAAoB,CAAC,KAAA,EAAY,WAAA,KAAsC;AAC3E,EAAA,IAAI,CAAC,WAAA,IAAe,MAAA,CAAO,KAAK,WAAW,CAAA,CAAE,WAAW,CAAA,EAAG;AACzD,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,MAAM,eAAA,GAAkB,MAAA,CAAO,OAAA,CAAQ,WAAW,CAAA,CAAE,MAAA;AAAA,IAAO,CAAC,CAAC,GAAG,CAAA,KAC9D,CAAC,CAAC,aAAA,EAAe,OAAO,CAAA,CAAE,QAAA,CAAS,GAAG;AAAA,GACxC;AAEA,EAAA,IAAI,eAAA,CAAgB,WAAW,CAAA,EAAG;AAChC,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,uBACE,IAAA,CAAC,SAAI,KAAA,EAAO;AAAA,IACV,YAAA,EAAc,MAAA;AAAA,IACd,OAAA,EAAS,MAAA;AAAA,IACT,eAAA,EAAiB,KAAA,CAAM,OAAA,CAAQ,IAAA,KAAS,SAAS,wBAAA,GAA2B,kBAAA;AAAA,IAC5E,YAAA,EAAc,KAAA;AAAA,IACd,QAAQ,CAAA,UAAA,EAAa,KAAA,CAAM,QAAQ,IAAA,KAAS,MAAA,GAAS,2BAA2B,kBAAkB,CAAA;AAAA,GACpG,EACE,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,WAAA,EAAY,KAAA,EAAO;AAAA,MACrC,YAAA,EAAc,MAAA;AAAA,MACd,UAAA,EAAY,MAAA;AAAA,MACZ,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,SAAA;AAAA,MAC1B,aAAA,EAAe,WAAA;AAAA,MACf,aAAA,EAAe;AAAA,OACd,QAAA,EAAA,UAAA,EAEH,CAAA;AAAA,IACC,gBAAgB,GAAA,CAAI,CAAC,CAAC,GAAA,EAAK,KAAK,GAAG,KAAA,qBAClC,IAAA,CAAC,SAAc,KAAA,EAAO,EAAE,cAAc,KAAA,GAAQ,eAAA,CAAgB,SAAS,CAAA,GAAI,MAAA,GAAS,KAAI,EACtF,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,OAAA,EAAQ,KAAA,EAAO;AAAA,QACjC,UAAA,EAAY,MAAA;AAAA,QACZ,aAAA,EAAe,YAAA;AAAA,QACf,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,OAAA,CAAQ,IAAA;AAAA,QAC7B,YAAA,EAAc;AAAA,OAChB,EACG,QAAA,EAAA;AAAA,QAAA,GAAA;AAAA,QAAI;AAAA,OAAA,EACP,CAAA;AAAA,sBACA,GAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,OAAA,EAAQ,KAAA,EAAO;AAAA,QACjC,UAAA,EAAY,KAAA;AAAA,QACZ,UAAA,EAAY,KAAA;AAAA,QACZ,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK;AAAA,OAC5B,EACG,QAAA,EAAA,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,GAAI,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA,GAAI,MAAA,CAAO,KAAK,CAAA,EACzD;AAAA,KAAA,EAAA,EAfQ,GAgBV,CACD;AAAA,GAAA,EACH,CAAA;AAEJ,CAAA;AAGA,MAAM,kBAAA,GAAqB,CAAC,OAAA,KAAoB;AAC9C,EAAA,OAAO,uBAAuB,OAAO,CAAA;AACvC,CAAA;AAGA,MAAM,sBAAA,GAAyB,CAAC,OAAA,KAAoB;AAElD,EAAA,IAAI,CAAC,OAAA,CAAQ,IAAA,EAAK,CAAE,UAAA,CAAW,KAAK,CAAA,EAAG;AACrC,IAAA,OAAO;AAAA,MACL,WAAA,EAAa,MAAA;AAAA,MACb;AAAA,KACF;AAAA,EACF;AAEA,EAAA,IAAI;AAEF,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAA;AAChC,IAAA,IAAI,mBAAA,GAAsB,CAAA,CAAA;AAG1B,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,MAAA,IAAI,KAAA,CAAM,CAAC,CAAA,CAAE,IAAA,OAAW,KAAA,EAAO;AAC7B,QAAA,mBAAA,GAAsB,CAAA;AACtB,QAAA;AAAA,MACF;AAAA,IACF;AAEA,IAAA,IAAI,wBAAwB,CAAA,CAAA,EAAI;AAC9B,MAAA,OAAO;AAAA,QACL,WAAA,EAAa,KAAA,CAAA;AAAA,QACb;AAAA,OACF;AAAA,IACF;AAGA,IAAA,MAAM,gBAAA,GAAmB,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,mBAAmB,CAAA;AAC3D,IAAA,MAAM,YAAA,GAAe,KAAA,CAAM,KAAA,CAAM,mBAAA,GAAsB,CAAC,CAAA;AAGxD,IAAA,MAAM,cAAmC,EAAC;AAC1C,IAAA,KAAA,MAAW,QAAQ,gBAAA,EAAkB;AACnC,MAAA,MAAM,WAAA,GAAc,KAAK,IAAA,EAAK;AAC9B,MAAA,IAAI,WAAA,IAAe,WAAA,CAAY,QAAA,CAAS,GAAG,CAAA,EAAG;AAC5C,QAAA,MAAM,UAAA,GAAa,WAAA,CAAY,OAAA,CAAQ,GAAG,CAAA;AAC1C,QAAA,MAAM,MAAM,WAAA,CAAY,SAAA,CAAU,CAAA,EAAG,UAAU,EAAE,IAAA,EAAK;AACtD,QAAA,MAAM,QAAQ,WAAA,CAAY,SAAA,CAAU,UAAA,GAAa,CAAC,EAAE,IAAA,EAAK;AACzD,QAAA,WAAA,CAAY,GAAG,CAAA,GAAI,KAAA;AAAA,MACrB;AAAA,IACF;AAEA,IAAA,OAAO;AAAA,MACL,aAAa,MAAA,CAAO,IAAA,CAAK,WAAW,CAAA,CAAE,MAAA,GAAS,IAAI,WAAA,GAAc,KAAA,CAAA;AAAA,MACjE,OAAA,EAAS,YAAA,CAAa,IAAA,CAAK,IAAI,EAAE,IAAA;AAAK,KACxC;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,OAAO;AAAA,MACL,WAAA,EAAa,MAAA;AAAA,MACb;AAAA,KACF;AAAA,EACF;AACF,CAAA;AAEA,MAAM,gBAAA,GAAmB,CAAC,MAAA,EAAgB,QAAA,KAA6B;AAErE,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA;AAG7C,EAAA,IAAI,WAAA,CAAY,QAAA,CAAS,YAAY,CAAA,EAAG;AACtC,IAAA,OAAO,CAAA,EAAG,WAAW,CAAA,WAAA,EAAc,QAAQ,CAAA,CAAA;AAAA,EAC7C;AAGA,EAAA,IAAI,WAAA,CAAY,QAAA,CAAS,YAAY,CAAA,EAAG;AACtC,IAAA,OAAO,CAAA,EAAG,WAAW,CAAA,aAAA,EAAgB,QAAQ,CAAA,CAAA;AAAA,EAC/C;AAGA,EAAA,OAAO,CAAA,EAAG,WAAW,CAAA,WAAA,EAAc,QAAQ,CAAA,CAAA;AAC7C,CAAA;AAEA,MAAM,aAAA,GAAgB,CAAC,EAAE,IAAA,EAAK,KAAwB;AACpD,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,MAAM,QAAQ,QAAA,EAAS;AAEvB,EAAA,MAAM,gBAAA,GAAmB,CAACA,KAAAA,KAAqB;AAE7C,IAAA,MAAM,EAAE,WAAA,EAAa,OAAA,EAAQ,GAAI,kBAAA,CAAmBA,MAAK,OAAO,CAAA;AAEhE,IAAA,uBACE,IAAA,CAAC,SAAA,EAAA,EAAU,SAAA,EAAW,MAAA,CAAO,QAAA,EAC3B,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,gBAAA,EAAA,EAAiB,4BAAY,GAAA,CAAC,cAAA,EAAA,EAAe,GAC5C,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,UAAA,EACrB,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,iBAAA,EACrB,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,YAAA,EAAA,EAAa,IAAA,EAAMA,KAAAA,CAAK,IAAA,EAAM,CAAA;AAAA,8BAC9B,UAAA,EAAA,EAAW,OAAA,EAAQ,IAAA,EAAM,QAAA,EAAAA,MAAK,QAAA,EAAS,CAAA;AAAA,0BACxC,GAAA,CAAC,QAAK,KAAA,EAAOA,KAAAA,CAAK,MAAM,IAAA,EAAK,OAAA,EAAQ,SAAA,EAAW,MAAA,CAAO,QAAA,EAAU,CAAA;AAAA,UAChE,aAAa,WAAA,oBACZ,GAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,SAAQ,KAAA,EAAO,EAAE,UAAA,EAAY,CAAA,EAAG,OAAO,KAAA,CAAM,OAAA,CAAQ,KAAK,SAAA,EAAU,EACrF,sBAAY,WAAA,EACf;AAAA,SAAA,EAEJ,CAAA;AAAA,QACCA,KAAAA,CAAK,MAAA,oBACJ,GAAA,CAAC,OAAA,EAAA,EAAQ,OAAM,yBAAA,EACb,QAAA,kBAAA,GAAA;AAAA,UAAC,UAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,OAAA;AAAA,YACL,OAAA,EAAS,CAAC,CAAA,KAAM;AACd,cAAA,CAAA,CAAE,eAAA,EAAgB;AAClB,cAAA,MAAA,CAAO,KAAK,gBAAA,CAAiBA,KAAAA,CAAK,QAASA,KAAAA,CAAK,QAAQ,GAAG,QAAQ,CAAA;AAAA,YACrE,CAAA;AAAA,YAEA,QAAA,kBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,QAAA,EAAS,OAAA,EAAQ;AAAA;AAAA,SAC/B,EACF;AAAA,OAAA,EAEJ,CAAA,EACF,CAAA;AAAA,sBACA,GAAA,CAAC,gBAAA,EAAA,EACC,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,YAAA,EACrB,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,IAAA,EAAA,EAAK,OAAO,CAAA,MAAA,EAASA,KAAAA,CAAK,QAAQ,CAAA,CAAA,EAAI,IAAA,EAAK,OAAA,EAAQ,OAAA,EAAQ,UAAA,EAAW,CAAA;AAAA,UACtE,WAAA,EAAa,yBACZ,GAAA,CAAC,IAAA,EAAA,EAAK,OAAO,CAAA,OAAA,EAAU,KAAA,CAAM,OAAA,CAAQ,WAAA,CAAY,KAAK,CAAA,GAAI,YAAY,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA,GAAI,WAAA,CAAY,KAAK,CAAA,CAAA,EAAI,IAAA,EAAK,OAAA,EAAQ,OAAA,EAAQ,UAAA,EAAW;AAAA,SAAA,EAElJ,CAAA;AAAA,QACC,iBAAA,CAAkB,OAAO,WAAW,CAAA;AAAA,wBACrC,GAAA,CAAC,SAAI,SAAA,EAAW,MAAA,CAAO,aACrB,QAAA,kBAAA,GAAA,CAAC,eAAA,EAAA,EAAgB,SAAkB,CAAA,EACrC;AAAA,OAAA,EACF,CAAA,EACF;AAAA,KAAA,EACF,CAAA;AAAA,EAEJ,CAAA;AAEA,EAAA,MAAM,iBAAA,GAAoB,CAACA,KAAAA,KAAsB;AAE/C,IAAA,MAAM,aAAaA,KAAAA,CAAK,KAAA,IAAA,CAAUA,KAAAA,CAAK,QAAA,CAAS,MAAM,YAAY,CAAA,IAAK,EAAC,EAAG,CAAC,CAAA,IAAKA,KAAAA,CAAK,GAAG,KAAA,CAAM,GAAG,EAAE,GAAA,EAAI;AAExG,IAAA,uBACE,IAAA,CAAC,SAAA,EAAA,EAAU,SAAA,EAAW,MAAA,CAAO,QAAA,EAC3B,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,gBAAA,EAAA,EAAiB,4BAAY,GAAA,CAAC,cAAA,EAAA,EAAe,GAC5C,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,UAAA,EACrB,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,iBAAA,EACrB,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,YAAA,EAAA,EAAa,IAAA,EAAMA,KAAAA,CAAK,IAAA,EAAM,CAAA;AAAA,0BAC/B,GAAA,CAAC,cAAW,OAAA,EAAQ,IAAA,EACjB,UAAAA,KAAAA,CAAK,KAAA,IAAS,CAAA,cAAA,EAAiB,UAAU,CAAA,CAAA,EAC5C,CAAA;AAAA,0BACA,GAAA,CAAC,QAAK,KAAA,EAAOA,KAAAA,CAAK,MAAM,IAAA,EAAK,OAAA,EAAQ,SAAA,EAAW,MAAA,CAAO,QAAA,EAAU,CAAA;AAAA,UAChEA,MAAK,OAAA,oBACJ,GAAA;AAAA,YAAC,IAAA;AAAA,YAAA;AAAA,cACC,KAAA,EAAO,CAAA,YAAA,EAAeA,KAAAA,CAAK,OAAO,CAAA,CAAA;AAAA,cAClC,IAAA,EAAK,OAAA;AAAA,cACL,OAAA,EAAQ,UAAA;AAAA,cACR,KAAA,EAAO,EAAE,UAAA,EAAY,CAAA;AAAE;AAAA;AACzB,SAAA,EAEJ,CAAA;AAAA,QACCA,KAAAA,CAAK,MAAA,oBACJ,GAAA,CAAC,OAAA,EAAA,EAAQ,OAAM,yBAAA,EACb,QAAA,kBAAA,GAAA;AAAA,UAAC,UAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,OAAA;AAAA,YACL,OAAA,EAAS,CAAC,CAAA,KAAM;AACd,cAAA,CAAA,CAAE,eAAA,EAAgB;AAClB,cAAA,MAAA,CAAO,KAAK,gBAAA,CAAiBA,KAAAA,CAAK,QAASA,KAAAA,CAAK,QAAQ,GAAG,QAAQ,CAAA;AAAA,YACrE,CAAA;AAAA,YAEA,QAAA,kBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,QAAA,EAAS,OAAA,EAAQ;AAAA;AAAA,SAC/B,EACF;AAAA,OAAA,EAEJ,CAAA,EACF,CAAA;AAAA,sBACA,GAAA,CAAC,gBAAA,EAAA,EACC,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,YAAA,EACrB,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,IAAA,EAAA,EAAK,OAAO,CAAA,MAAA,EAASA,KAAAA,CAAK,QAAQ,CAAA,CAAA,EAAI,IAAA,EAAK,OAAA,EAAQ,OAAA,EAAQ,UAAA,EAAW,CAAA;AAAA,UACtEA,KAAAA,CAAK,WAAA,IAAe,iBAAA,CAAkB,KAAA,EAAOA,MAAK,WAAW;AAAA,SAAA,EAChE,CAAA;AAAA,wBACA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,WAAA,EACrB,8BAAC,eAAA,EAAA,EAAgB,OAAA,EAASA,KAAAA,CAAK,OAAA,EAAS,CAAA,EAC1C;AAAA,OAAA,EACF,CAAA,EACF;AAAA,KAAA,EACF,CAAA;AAAA,EAEJ,CAAA;AAEA,EAAA,MAAM,kBAAkB,CAACA,KAAAA,0BACtB,SAAA,EAAA,EAAU,SAAA,EAAW,OAAO,QAAA,EAC3B,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,gBAAA,EAAA,EAAiB,4BAAY,GAAA,CAAC,cAAA,EAAA,EAAe,GAC5C,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,UAAA,EACrB,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,iBAAA,EACrB,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,YAAA,EAAA,EAAa,IAAA,EAAMA,KAAAA,CAAK,IAAA,EAAM,CAAA;AAAA,wBAC/B,GAAA,CAAC,cAAW,OAAA,EAAQ,IAAA,EAAM,UAAAA,KAAAA,CAAK,KAAA,IAASA,MAAK,QAAA,EAAS,CAAA;AAAA,wBACtD,GAAA,CAAC,QAAK,KAAA,EAAOA,KAAAA,CAAK,MAAM,IAAA,EAAK,OAAA,EAAQ,SAAA,EAAW,MAAA,CAAO,QAAA,EAAU;AAAA,OAAA,EACnE,CAAA;AAAA,MACCA,KAAAA,CAAK,MAAA,oBACJ,GAAA,CAAC,OAAA,EAAA,EAAQ,OAAM,yBAAA,EACb,QAAA,kBAAA,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,OAAA;AAAA,UACL,OAAA,EAAS,CAAC,CAAA,KAAM;AACd,YAAA,CAAA,CAAE,eAAA,EAAgB;AAClB,YAAA,MAAA,CAAO,KAAK,gBAAA,CAAiBA,KAAAA,CAAK,QAASA,KAAAA,CAAK,QAAQ,GAAG,QAAQ,CAAA;AAAA,UACrE,CAAA;AAAA,UAEA,QAAA,kBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,QAAA,EAAS,OAAA,EAAQ;AAAA;AAAA,OAC/B,EACF;AAAA,KAAA,EAEJ,CAAA,EACF,CAAA;AAAA,oBACA,GAAA,CAAC,gBAAA,EAAA,EACC,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,YAAA,EACrB,8BAAC,IAAA,EAAA,EAAK,KAAA,EAAO,CAAA,MAAA,EAASA,KAAAA,CAAK,QAAQ,CAAA,CAAA,EAAI,IAAA,EAAK,OAAA,EAAQ,OAAA,EAAQ,YAAW,CAAA,EACzE,CAAA;AAAA,sBACA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,WAAA,EACrB,8BAAC,eAAA,EAAA,EAAgB,OAAA,EAASA,KAAAA,CAAK,OAAA,EAAS,CAAA,EAC1C;AAAA,KAAA,EACF,CAAA,EACF;AAAA,GAAA,EACF,CAAA;AAGF,EAAA,MAAM,uBAAuB,CAACA,KAAAA,0BAC3B,SAAA,EAAA,EAAU,SAAA,EAAW,OAAO,QAAA,EAC3B,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,gBAAA,EAAA,EAAiB,4BAAY,GAAA,CAAC,cAAA,EAAA,EAAe,GAC5C,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,UAAA,EACrB,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,iBAAA,EACrB,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,YAAA,EAAA,EAAa,IAAA,EAAMA,KAAAA,CAAK,IAAA,EAAM,CAAA;AAAA,wBAC/B,GAAA,CAAC,cAAW,OAAA,EAAQ,IAAA,EAAM,UAAAA,KAAAA,CAAK,KAAA,IAASA,MAAK,QAAA,EAAS,CAAA;AAAA,wBACtD,GAAA,CAAC,QAAK,KAAA,EAAOA,KAAAA,CAAK,MAAM,IAAA,EAAK,OAAA,EAAQ,SAAA,EAAW,MAAA,CAAO,QAAA,EAAU;AAAA,OAAA,EACnE,CAAA;AAAA,MACCA,KAAAA,CAAK,MAAA,oBACJ,GAAA,CAAC,OAAA,EAAA,EAAQ,OAAM,yBAAA,EACb,QAAA,kBAAA,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,OAAA;AAAA,UACL,OAAA,EAAS,CAAC,CAAA,KAAM;AACd,YAAA,CAAA,CAAE,eAAA,EAAgB;AAClB,YAAA,MAAA,CAAO,KAAK,gBAAA,CAAiBA,KAAAA,CAAK,QAASA,KAAAA,CAAK,QAAQ,GAAG,QAAQ,CAAA;AAAA,UACrE,CAAA;AAAA,UAEA,QAAA,kBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,QAAA,EAAS,OAAA,EAAQ;AAAA;AAAA,OAC/B,EACF;AAAA,KAAA,EAEJ,CAAA,EACF,CAAA;AAAA,oBACA,GAAA,CAAC,gBAAA,EAAA,EACC,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,YAAA,EACrB,8BAAC,IAAA,EAAA,EAAK,KAAA,EAAO,CAAA,MAAA,EAASA,KAAAA,CAAK,QAAQ,CAAA,CAAA,EAAI,IAAA,EAAK,OAAA,EAAQ,OAAA,EAAQ,YAAW,CAAA,EACzE,CAAA;AAAA,sBACA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,WAAA,EACrB,8BAAC,eAAA,EAAA,EAAgB,OAAA,EAASA,KAAAA,CAAK,OAAA,EAAS,CAAA,EAC1C;AAAA,KAAA,EACF,CAAA,EACF;AAAA,GAAA,EACF,CAAA;AAGF,EAAA,QAAQ,KAAK,IAAA;AAAM,IACjB,KAAK,UAAA,CAAW,MAAA;AACd,MAAA,OAAO,iBAAiB,IAAkB,CAAA;AAAA,IAC5C,KAAK,UAAA,CAAW,WAAA;AACZ,MAAA,OAAO,qBAAqB,IAAsB,CAAA;AAAA,IACtD,KAAK,UAAA,CAAW,OAAA;AACd,MAAA,OAAO,kBAAkB,IAAmB,CAAA;AAAA,IAC9C,KAAK,UAAA,CAAW,KAAA;AACd,MAAA,OAAO,gBAAgB,IAAiB,CAAA;AAAA,IAC1C;AACE,MAAA,OAAO,IAAA;AAAA;AAEb,CAAA;AAEO,MAAM,mBAAoD,CAAC,EAAE,QAAQ,iBAAA,EAAkB,GAAI,EAAC,KAAM;AACvG,EAAA,MAAM,EAAE,WAAA,EAAa,OAAA,EAAS,KAAA,EAAO,WAAW,UAAA,EAAY,gBAAA,EAAkB,iBAAA,EAAmB,oBAAA,EAAsB,YAAA,EAAc,YAAA,EAAc,mBAAA,EAAqB,WAAA,KAAgB,UAAA,EAAW;AACnM,EAAA,MAAM,SAAS,SAAA,EAAU;AAGzB,EAAA,MAAM,oBAAA,GAAuB,CAAC,UAAA,CAAW,MAAA,EAAQ,WAAW,WAAA,EAAa,UAAA,CAAW,OAAA,EAAS,UAAA,CAAW,KAAK,CAAA;AAG7G,EAAA,MAAM,kBAAA,GAAqB,CAAC,IAAA,KAA6B;AACvD,IAAA,QAAQ,IAAA;AAAM,MACZ,KAAK,UAAA,CAAW,MAAA;AACd,QAAA,OAAO,QAAA;AAAA,MACT,KAAK,UAAA,CAAW,WAAA;AACd,QAAA,OAAO,aAAA;AAAA,MACT,KAAK,UAAA,CAAW,OAAA;AACd,QAAA,OAAO,SAAA;AAAA,MACT,KAAK,UAAA,CAAW,KAAA;AACd,QAAA,OAAO,OAAA;AAAA;AACX,EACF,CAAA;AACA,EAAA,MAAM,gBAAA,GAAmB,CAAC,IAAA,EAAkB,OAAA,KAAqB;AAC/D,IAAA,MAAM,QAAA,GAAW,OAAA,GACb,CAAC,GAAG,iBAAA,EAAmB,IAAI,CAAA,GAC3B,iBAAA,CAAkB,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,KAAM,IAAI,CAAA;AAC5C,IAAA,oBAAA,CAAqB,QAAQ,CAAA;AAAA,EAC/B,CAAA;AAEA,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,uBACE,GAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EACR,QAAA,kBAAA,GAAA,CAAC,YAAS,CAAA,EACZ,CAAA;AAAA,EAEJ;AAEA,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,uBACE,GAAA,CAAC,YAAS,KAAA,EACR,QAAA,kBAAA,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAQ,SAAA;AAAA,QACR,KAAA,EAAM,mBAAA;AAAA,QACN,WAAA,EAAY;AAAA;AAAA,KACd,EACF,CAAA;AAAA,EAEJ;AAEA,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,uBACE,GAAA,CAAC,YAAS,KAAA,EACR,QAAA,kBAAA,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAQ,SAAA;AAAA,QACR,KAAA,EAAM,qBAAA;AAAA,QACN,WAAA,EAAa;AAAA;AAAA,KACf,EACF,CAAA;AAAA,EAEJ;AAEA,EAAA,uBACE,IAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAc,SAAA,EAAW,OAAO,IAAA,EACxC,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,aAAA,EACrB,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,IAAA,EAAK,YAAA,EAAY,MAAC,QAAA,EAAA,mBAAA,EAEtC,CAAA;AAAA,0BACC,KAAA,EAAA,EAAI,SAAA,EAAW,OAAO,eAAA,EACpB,QAAA,EAAA,gBAAA,CAAiB,IAAI,CAAA,IAAA,qBACpB,GAAA;AAAA,QAAC,gBAAA;AAAA,QAAA;AAAA,UAEC,OAAA,kBACE,GAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAS,iBAAA,CAAkB,QAAA,CAAS,IAAI,CAAA;AAAA,cACxC,UAAU,CAAC,CAAA,KAAM,iBAAiB,IAAA,EAAM,CAAA,CAAE,OAAO,OAAO;AAAA;AAAA,WAC1D;AAAA,UAEF,KAAA,EAAO,mBAAmB,IAAI;AAAA,SAAA;AAAA,QAPzB;AAAA,OASR,CAAA,EACH,CAAA;AAAA,sBACA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,iBAAA,EACrB,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAQ,WAAA;AAAA,YACR,KAAA,EAAM,SAAA;AAAA,YACN,OAAA,EAAS,YAAA;AAAA,YACT,UAAU,CAAC,mBAAA;AAAA,YACZ,QAAA,EAAA;AAAA;AAAA,SAED;AAAA,QACC,mBAAA,oBACC,GAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,OAAA,EAAQ,KAAA,EAAM,eAAA,EAAgB,KAAA,EAAO,EAAE,SAAA,EAAW,CAAA,EAAE,EAAG,QAAA,EAAA,8EAAA,EAE3E,CAAA;AAAA,QAED,CAAC,mBAAA,IAAuB,iBAAA,CAAkB,MAAA,KAAW,CAAA,wBACnD,UAAA,EAAA,EAAW,OAAA,EAAQ,OAAA,EAAQ,KAAA,EAAM,iBAAgB,KAAA,EAAO,EAAE,SAAA,EAAW,CAAA,IAAK,QAAA,EAAA,uDAAA,EAE3E;AAAA,OAAA,EAEJ;AAAA,KAAA,EACF,CAAA;AAAA,IAEC,WAAA,IAAe,eAAe,CAAA,mBAC7B,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAQ,SAAA;AAAA,QACR,KAAA,EAAM,mBAAA;AAAA,QACN,WAAA,EAAY,wEAAA;AAAA,QACZ,MAAA,kBACE,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAQ,UAAA;AAAA,YACR,OAAA,EAAS,YAAA;AAAA,YACV,QAAA,EAAA;AAAA;AAAA;AAED;AAAA,KAEJ,GACE,UAAA,GAAa,CAAA,mBACf,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,MAAA,CAAO,cAAA,EACrB,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAW,MAAA,CAAO,QAAA,EACtB,+BAAC,WAAA,EAAA,EACC,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,IAAA,EAAM,QAAA,EAAA,UAAA,EAAW,CAAA;AAAA,0BACrC,GAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EAAgB,QAAA,EAAA,aAAA,EAAW;AAAA,SAAA,EAC/C,CAAA,EACF,CAAA;AAAA,QACC,oBAAA,CAAqB,IAAI,CAAA,IAAA,KAAQ;AAChC,UAAA,MAAM,SAAA,GAAY,WAAA,CAAY,IAAI,CAAA,IAAK,EAAC;AACxC,UAAA,IAAI,SAAA,CAAU,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AACnC,UAAA,2BACG,IAAA,EAAA,EAAgB,SAAA,EAAW,MAAA,CAAO,QAAA,EACjC,+BAAC,WAAA,EAAA,EACC,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,IAAA,EAAM,QAAA,EAAA,SAAA,CAAU,MAAA,EAAO,CAAA;AAAA,gCAC1C,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EAAiB,QAAA,EAAA,kBAAA,CAAmB,IAAI,CAAA,EAAE;AAAA,WAAA,EAC9D,KAJS,IAKX,CAAA;AAAA,QAEJ,CAAC;AAAA,OAAA,EACH,CAAA;AAAA,MAEC,oBAAA,CAAqB,IAAI,CAAA,IAAA,KAAQ;AAChC,QAAA,MAAM,SAAA,GAAY,WAAA,CAAY,IAAI,CAAA,IAAK,EAAC;AACxC,QAAA,IAAI,SAAA,CAAU,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AACnC,QAAA,4BACG,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,0BAAA,IAAA,CAAC,UAAA,EAAA,EAAW,SAAQ,IAAA,EAAK,YAAA,EAAY,MAAC,KAAA,EAAO,EAAE,SAAA,EAAW,EAAA,EAAG,EAC1D,QAAA,EAAA;AAAA,YAAA,kBAAA,CAAmB,IAAI,CAAA;AAAA,YAAE,UAAA;AAAA,YAAS,SAAA,CAAU,MAAA;AAAA,YAAO;AAAA,WAAA,EACtD,CAAA;AAAA,UACC,SAAA,CAAU,IAAI,CAAA,IAAA,qBACb,GAAA,CAAC,iBAA4B,IAAA,EAAA,EAAT,IAAA,CAAK,EAAgB,CAC1C;AAAA,SAAA,EAAA,EANO,IAOV,CAAA;AAAA,MAEJ,CAAC;AAAA,KAAA,EACH,CAAA,mBAEA,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO,EAAE,SAAA,EAAW,EAAA,EAAG,EAC1B,QAAA,kBAAA,GAAA,CAAC,cAAW,OAAA,EAAQ,OAAA,EAAQ,KAAA,EAAM,eAAA,EAAgB,gHAElD,CAAA,EACF;AAAA,GAAA,EAEJ,CAAA;AAEJ;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MCPServersComponent.esm.js","sources":["../../../src/components/MCPServersComponent/MCPServersComponent.tsx"],"sourcesContent":["import React from 'react';\nimport {\n InfoCard,\n Progress,\n EmptyState,\n CodeSnippet,\n} from '@backstage/core-components';\nimport {\n makeStyles,\n Typography,\n Chip,\n Accordion,\n AccordionSummary,\n AccordionDetails,\n} from '@material-ui/core';\nimport { Theme } from '@material-ui/core/styles';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport { MCPServerInfo } from '../../types/mcp';\nimport { useMCPServers } from '../../hooks/useMCPServers';\n\nconst useStyles = makeStyles((theme: Theme) => ({\n root: {\n '& .MuiAccordion-root': {\n marginBottom: theme.spacing(1),\n '&:before': {\n display: 'none',\n },\n },\n },\n sourceAccordion: {\n backgroundColor: theme.palette.background.default,\n marginBottom: theme.spacing(2),\n width: '100%',\n '& .MuiAccordionSummary-root': {\n borderBottom: `1px solid ${theme.palette.divider}`,\n },\n '& .MuiAccordionDetails-root': {\n padding: theme.spacing(2),\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(2),\n },\n },\n serversList: {\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(2),\n width: '100%',\n },\n serverAccordion: {\n backgroundColor: theme.palette.background.paper,\n width: '100%',\n '& .MuiAccordionSummary-root': {\n minHeight: '48px',\n '&.Mui-expanded': {\n minHeight: '48px',\n },\n },\n '& .MuiAccordionSummary-content': {\n margin: '12px 0',\n '&.Mui-expanded': {\n margin: '12px 0',\n },\n },\n '& .MuiAccordionDetails-root': {\n padding: theme.spacing(3),\n },\n },\n envContainer: {\n backgroundColor: theme.palette.background.default,\n padding: theme.spacing(2),\n borderRadius: theme.shape.borderRadius,\n },\n envGrid: {\n display: 'grid',\n gridTemplateColumns: 'auto 1fr',\n gap: theme.spacing(1),\n alignItems: 'center',\n },\n envKey: {\n fontWeight: 'bold',\n color: theme.palette.text.secondary,\n padding: theme.spacing(0.5, 1),\n backgroundColor: theme.palette.background.paper,\n borderRadius: theme.shape.borderRadius,\n fontSize: '0.875rem',\n },\n envValue: {\n wordBreak: 'break-word',\n padding: theme.spacing(0.5, 1),\n backgroundColor: theme.palette.background.paper,\n borderRadius: theme.shape.borderRadius,\n fontSize: '0.875rem',\n },\n rawConfig: {\n backgroundColor: theme.palette.background.default,\n padding: theme.spacing(2),\n borderRadius: theme.shape.borderRadius,\n '& pre': {\n margin: 0,\n },\n },\n sectionTitle: {\n marginBottom: theme.spacing(1),\n color: theme.palette.text.secondary,\n fontWeight: 500,\n },\n serverContent: {\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(3),\n width: '100%',\n },\n commandContainer: {\n backgroundColor: theme.palette.background.default,\n padding: theme.spacing(2),\n borderRadius: theme.shape.borderRadius,\n fontFamily: 'monospace',\n fontSize: '0.9rem',\n overflowX: 'auto',\n whiteSpace: 'pre',\n },\n detailsContainer: {\n display: 'grid',\n gridTemplateColumns: '1fr 1fr',\n gap: theme.spacing(3),\n },\n}));\n\n\nexport interface MCPServersComponentProps {\n title?: string;\n}\n\nexport const MCPServersComponent = ({ title = \"MCP Servers\" }: MCPServersComponentProps) => {\n const styles = useStyles();\n const { servers, loading, error, hasGitUrl } = useMCPServers();\n\n if (loading) {\n return (\n <InfoCard title={title}>\n <Progress />\n </InfoCard>\n );\n }\n\n if (!hasGitUrl) {\n return (\n <InfoCard title={title}>\n <EmptyState\n missing=\"content\"\n title=\"No Git Repository\"\n description=\"This component doesn't have a Git source URL configured.\"\n />\n </InfoCard>\n );\n }\n\n if (error) {\n return (\n <InfoCard title={title}>\n <EmptyState\n missing=\"content\"\n title=\"Error Loading MCP Servers\"\n description={error}\n />\n </InfoCard>\n );\n }\n\n if (servers.length === 0) {\n return (\n <InfoCard title={title}>\n <EmptyState\n missing=\"content\"\n title=\"No MCP Servers Found\"\n description=\"No MCP server configurations were found in this repository.\"\n />\n </InfoCard>\n );\n }\n\n // Group servers by source\n const serversBySource = servers.reduce((acc, server) => {\n const source = server.source;\n if (!acc[source]) {\n acc[source] = [];\n }\n acc[source].push(server);\n return acc;\n }, {} as Record<string, MCPServerInfo[]>);\n\n const formatSourceName = (source: string) => {\n switch (source) {\n case 'vscode':\n return 'VSCode';\n case 'cursor':\n return 'Cursor';\n case 'claude':\n return 'Claude';\n default:\n return source;\n }\n };\n\n return (\n <InfoCard title={title} className={styles.root}>\n {Object.entries(serversBySource).map(([source, sourceServers]) => (\n <Accordion key={source} defaultExpanded={false} className={styles.sourceAccordion}>\n <AccordionSummary expandIcon={<ExpandMoreIcon />}>\n <div style={{ display: 'flex', alignItems: 'center', width: '100%', gap: '16px' }}>\n <Typography variant=\"h6\">\n {formatSourceName(source)} MCP Servers\n </Typography>\n <Chip\n label={`${sourceServers.length} server${sourceServers.length !== 1 ? 's' : ''}`}\n size=\"small\"\n color=\"primary\"\n />\n </div>\n </AccordionSummary>\n <AccordionDetails>\n <div className={styles.serversList}>\n {sourceServers.map((server) => (\n <Accordion key={server.name} className={styles.serverAccordion}>\n <AccordionSummary expandIcon={<ExpandMoreIcon />}>\n <div style={{ display: 'flex', alignItems: 'center', width: '100%', gap: '16px' }}>\n <Typography variant=\"subtitle1\">{server.name}</Typography>\n <Chip \n label={server.type} \n size=\"small\" \n color={server.type === 'local' ? 'default' : 'secondary'}\n variant=\"outlined\"\n />\n {server.config.command && (\n <Chip \n label={`${server.config.command}`}\n size=\"small\"\n variant=\"outlined\"\n />\n )}\n </div>\n </AccordionSummary>\n <AccordionDetails>\n <div className={styles.serverContent}>\n {server.config.command && (\n <div>\n <Typography variant=\"subtitle2\" className={styles.sectionTitle}>Command</Typography>\n <div className={styles.commandContainer}>\n {server.config.command} {server.config.args?.join(' ')}\n </div>\n </div>\n )}\n <div className={styles.detailsContainer}>\n <div>\n {server.config.env && Object.keys(server.config.env).length > 0 && (\n <>\n <Typography variant=\"subtitle2\" className={styles.sectionTitle}>Environment Variables</Typography>\n <div className={styles.envContainer}>\n <div className={styles.envGrid}>\n {Object.entries(server.config.env).map(([key, value]) => (\n <React.Fragment key={key}>\n <Typography className={styles.envKey}>{key}</Typography>\n <Typography className={styles.envValue}>{value}</Typography>\n </React.Fragment>\n ))}\n </div>\n </div>\n </>\n )}\n </div>\n <div>\n <Typography variant=\"subtitle2\" className={styles.sectionTitle}>Raw Configuration</Typography>\n <div className={styles.rawConfig}>\n <CodeSnippet text={server.rawConfig} language=\"json\" />\n </div>\n </div>\n </div>\n </div>\n </AccordionDetails>\n </Accordion>\n ))}\n </div>\n </AccordionDetails>\n </Accordion>\n ))}\n </InfoCard>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MCPServersComponent.esm.js","sources":["../../../src/components/MCPServersComponent/MCPServersComponent.tsx"],"sourcesContent":["import React from 'react';\nimport {\n InfoCard,\n Progress,\n EmptyState,\n CodeSnippet,\n} from '@backstage/core-components';\nimport {\n makeStyles,\n Typography,\n Chip,\n Accordion,\n AccordionSummary,\n AccordionDetails,\n} from '@material-ui/core';\nimport { Theme } from '@material-ui/core/styles';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport { MCPServerInfo } from '../../types/mcp';\nimport { useMCPServers } from '../../hooks/useMCPServers';\n\nconst useStyles = makeStyles((theme: Theme) => ({\n root: {\n '& .MuiAccordion-root': {\n marginBottom: theme.spacing(1),\n '&:before': {\n display: 'none',\n },\n },\n },\n sourceAccordion: {\n backgroundColor: theme.palette.background.default,\n marginBottom: theme.spacing(2),\n width: '100%',\n '& .MuiAccordionSummary-root': {\n borderBottom: `1px solid ${theme.palette.divider}`,\n },\n '& .MuiAccordionDetails-root': {\n padding: theme.spacing(2),\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(2),\n },\n },\n serversList: {\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(2),\n width: '100%',\n },\n serverAccordion: {\n backgroundColor: theme.palette.background.paper,\n width: '100%',\n '& .MuiAccordionSummary-root': {\n minHeight: '48px',\n '&.Mui-expanded': {\n minHeight: '48px',\n },\n },\n '& .MuiAccordionSummary-content': {\n margin: '12px 0',\n '&.Mui-expanded': {\n margin: '12px 0',\n },\n },\n '& .MuiAccordionDetails-root': {\n padding: theme.spacing(3),\n },\n },\n envContainer: {\n backgroundColor: theme.palette.background.default,\n padding: theme.spacing(2),\n borderRadius: theme.shape.borderRadius,\n },\n envGrid: {\n display: 'grid',\n gridTemplateColumns: 'auto 1fr',\n gap: theme.spacing(1),\n alignItems: 'center',\n },\n envKey: {\n fontWeight: 'bold',\n color: theme.palette.text.secondary,\n padding: theme.spacing(0.5, 1),\n backgroundColor: theme.palette.background.paper,\n borderRadius: theme.shape.borderRadius,\n fontSize: '0.875rem',\n },\n envValue: {\n wordBreak: 'break-word',\n padding: theme.spacing(0.5, 1),\n backgroundColor: theme.palette.background.paper,\n borderRadius: theme.shape.borderRadius,\n fontSize: '0.875rem',\n },\n rawConfig: {\n backgroundColor: theme.palette.background.default,\n padding: theme.spacing(2),\n borderRadius: theme.shape.borderRadius,\n '& pre': {\n margin: 0,\n },\n },\n sectionTitle: {\n marginBottom: theme.spacing(1),\n color: theme.palette.text.secondary,\n fontWeight: 500,\n },\n serverContent: {\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(3),\n width: '100%',\n },\n commandContainer: {\n backgroundColor: theme.palette.background.default,\n padding: theme.spacing(2),\n borderRadius: theme.shape.borderRadius,\n fontFamily: 'monospace',\n fontSize: '0.9rem',\n overflowX: 'auto',\n whiteSpace: 'pre',\n },\n detailsContainer: {\n display: 'grid',\n gridTemplateColumns: '1fr 1fr',\n gap: theme.spacing(3),\n },\n}));\n\n\nexport interface MCPServersComponentProps {\n title?: string;\n}\n\nexport const MCPServersComponent = ({ title = \"MCP Servers\" }: MCPServersComponentProps) => {\n const styles = useStyles();\n const { servers, loading, error, hasGitUrl } = useMCPServers();\n\n if (loading) {\n return (\n <InfoCard title={title}>\n <Progress />\n </InfoCard>\n );\n }\n\n if (!hasGitUrl) {\n return (\n <InfoCard title={title}>\n <EmptyState\n missing=\"content\"\n title=\"No Git Repository\"\n description=\"This component doesn't have a Git source URL configured.\"\n />\n </InfoCard>\n );\n }\n\n if (error) {\n return (\n <InfoCard title={title}>\n <EmptyState\n missing=\"content\"\n title=\"Error Loading MCP Servers\"\n description={error}\n />\n </InfoCard>\n );\n }\n\n if (servers.length === 0) {\n return (\n <InfoCard title={title}>\n <EmptyState\n missing=\"content\"\n title=\"No MCP Servers Found\"\n description=\"No MCP server configurations were found in this repository.\"\n />\n </InfoCard>\n );\n }\n\n // Group servers by source\n const serversBySource = servers.reduce((acc, server) => {\n const source = server.source;\n if (!acc[source]) {\n acc[source] = [];\n }\n acc[source].push(server);\n return acc;\n }, {} as Record<string, MCPServerInfo[]>);\n\n const formatSourceName = (source: string) => {\n switch (source) {\n case 'vscode':\n return 'VSCode';\n case 'cursor':\n return 'Cursor';\n case 'claude':\n return 'Claude';\n default:\n return source;\n }\n };\n\n return (\n <InfoCard title={title} className={styles.root}>\n {Object.entries(serversBySource).map(([source, sourceServers]) => (\n <Accordion key={source} defaultExpanded={false} className={styles.sourceAccordion}>\n <AccordionSummary expandIcon={<ExpandMoreIcon />}>\n <div style={{ display: 'flex', alignItems: 'center', width: '100%', gap: '16px' }}>\n <Typography variant=\"h6\">\n {formatSourceName(source)} MCP Servers\n </Typography>\n <Chip\n label={`${sourceServers.length} server${sourceServers.length !== 1 ? 's' : ''}`}\n size=\"small\"\n color=\"primary\"\n />\n </div>\n </AccordionSummary>\n <AccordionDetails>\n <div className={styles.serversList}>\n {sourceServers.map((server) => (\n <Accordion key={server.name} className={styles.serverAccordion}>\n <AccordionSummary expandIcon={<ExpandMoreIcon />}>\n <div style={{ display: 'flex', alignItems: 'center', width: '100%', gap: '16px' }}>\n <Typography variant=\"subtitle1\">{server.name}</Typography>\n <Chip \n label={server.type} \n size=\"small\" \n color={server.type === 'local' ? 'default' : 'secondary'}\n variant=\"outlined\"\n />\n {server.config.command && (\n <Chip \n label={`${server.config.command}`}\n size=\"small\"\n variant=\"outlined\"\n />\n )}\n </div>\n </AccordionSummary>\n <AccordionDetails>\n <div className={styles.serverContent}>\n {server.config.command && (\n <div>\n <Typography variant=\"subtitle2\" className={styles.sectionTitle}>Command</Typography>\n <div className={styles.commandContainer}>\n {server.config.command} {server.config.args?.join(' ')}\n </div>\n </div>\n )}\n <div className={styles.detailsContainer}>\n <div>\n {server.config.env && Object.keys(server.config.env).length > 0 && (\n <>\n <Typography variant=\"subtitle2\" className={styles.sectionTitle}>Environment Variables</Typography>\n <div className={styles.envContainer}>\n <div className={styles.envGrid}>\n {Object.entries(server.config.env).map(([key, value]) => (\n <React.Fragment key={key}>\n <Typography className={styles.envKey}>{key}</Typography>\n <Typography className={styles.envValue}>{value}</Typography>\n </React.Fragment>\n ))}\n </div>\n </div>\n </>\n )}\n </div>\n <div>\n <Typography variant=\"subtitle2\" className={styles.sectionTitle}>Raw Configuration</Typography>\n <div className={styles.rawConfig}>\n <CodeSnippet text={server.rawConfig} language=\"json\" />\n </div>\n </div>\n </div>\n </div>\n </AccordionDetails>\n </Accordion>\n ))}\n </div>\n </AccordionDetails>\n </Accordion>\n ))}\n </InfoCard>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAiRules.esm.js","sources":["../../src/hooks/useAiRules.ts"],"sourcesContent":["import { useEntity } from '@backstage/plugin-catalog-react';\nimport { AIRuleType, AIRulesResponse, AIRule } from '../types';\nimport { useState, useEffect, useMemo, useCallback } from 'react';\nimport { useApi, configApiRef, discoveryApiRef, fetchApiRef } from '@backstage/core-plugin-api';\n\nexport const useAiRules = () => {\n const { entity } = useEntity();\n const configApi = useApi(configApiRef);\n const discoveryApi = useApi(discoveryApiRef);\n const fetchApi = useApi(fetchApiRef);\n \n const [rules, setRules] = useState<AIRule[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [selectedRuleTypes, setSelectedRuleTypes] = useState<AIRuleType[]>([]);\n const [appliedRuleTypes, setAppliedRuleTypes] = useState<AIRuleType[]>([]);\n const [initialized, setInitialized] = useState(false);\n const [hasSearched, setHasSearched] = useState(false);\n\n // Stabilize allowed rule types\n const allowedRuleTypes = useMemo(() => {\n return configApi.getOptionalStringArray('aiRules.allowedRuleTypes') as AIRuleType[] || [AIRuleType.CURSOR, AIRuleType.COPILOT, AIRuleType.CLINE, AIRuleType.CLAUDE_CODE];\n }, [configApi]);\n\n // Stabilize default rule types\n const defaultRuleTypes = useMemo(() => {\n // Check if the config has the aiRules section at all\n const aiRulesConfig = configApi.getOptionalConfig('aiRules');\n if (!aiRulesConfig) {\n // Config not loaded yet or aiRules section doesn't exist, use empty array\n return [];\n }\n \n const configuredDefaults = configApi.getOptionalStringArray('aiRules.defaultRuleTypes') as AIRuleType[];\n \n // If defaultRuleTypes is explicitly configured (even as empty array), use that\n // If not configured at all, use empty array\n return configuredDefaults !== undefined ? configuredDefaults : [];\n }, [configApi]);\n\n // Extract stable entity properties\n const entityData = useMemo(() => {\n const sourceAnnotation = entity.metadata?.annotations?.['backstage.io/source-location'] || '';\n const hasGitUrl = sourceAnnotation.startsWith('url:');\n \n let gitUrl = hasGitUrl ? sourceAnnotation.substring(4) : undefined;\n if (gitUrl) {\n // Remove trailing slashes and normalize URL\n gitUrl = gitUrl.replace(/\\/+$/, '');\n // Handle GitHub tree/blob URLs - extract base repo URL\n const treeMatch = gitUrl.match(/^(.+)\\/tree\\/([^/]+)(?:\\/(.+))?$/);\n const blobMatch = gitUrl.match(/^(.+)\\/blob\\/([^/]+)(?:\\/(.+))?$/);\n if (treeMatch) {\n gitUrl = treeMatch[1]; // Just the base repo URL\n }\n if (blobMatch) {\n gitUrl = blobMatch[1]; // Just the base repo URL \n }\n }\n\n return {\n kind: entity.kind,\n namespace: entity.metadata.namespace || 'default',\n name: entity.metadata.name,\n sourceAnnotation,\n hasGitUrl,\n gitUrl,\n };\n }, [entity.kind, entity.metadata.namespace, entity.metadata.name, entity.metadata?.annotations?.['backstage.io/source-location']]);\n\n // Initialize selected and applied rule types when defaultRuleTypes is available\n useEffect(() => {\n // Check if config is loaded\n const aiRulesConfig = configApi.getOptionalConfig('aiRules');\n const configLoaded = aiRulesConfig !== undefined;\n \n if (!initialized && allowedRuleTypes.length > 0 && configLoaded) {\n setSelectedRuleTypes(defaultRuleTypes);\n setAppliedRuleTypes(defaultRuleTypes);\n setInitialized(true);\n }\n }, [defaultRuleTypes, allowedRuleTypes, initialized, configApi]);\n\n // Stable fetch function\n const fetchAiRules = useCallback(async (ruleTypes: AIRuleType[]) => {\n if (!entityData.hasGitUrl || !entityData.gitUrl) {\n setLoading(false);\n return;\n }\n\n try {\n setLoading(true);\n setError(null);\n setHasSearched(true);\n \n const baseUrl = await discoveryApi.getBaseUrl('ai-rules');\n const url = new URL(`${baseUrl}/rules`);\n \n // Send the Git URL directly to the backend\n url.searchParams.append('gitUrl', entityData.gitUrl);\n if (ruleTypes.length > 0) {\n url.searchParams.append('ruleTypes', ruleTypes.join(','));\n }\n\n const response = await fetchApi.fetch(url.toString());\n if (!response.ok) {\n throw new Error(`Failed to fetch AI rules: ${response.statusText}`);\n }\n\n const data: AIRulesResponse = await response.json();\n setRules(data.rules);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Unknown error occurred';\n console.error('Error fetching AI rules:', errorMessage);\n setError(errorMessage);\n setRules([]);\n } finally {\n setLoading(false);\n }\n }, [entityData.hasGitUrl, entityData.gitUrl, discoveryApi, fetchApi]);\n\n // Manual apply filter function\n const applyFilters = useCallback(() => {\n setAppliedRuleTypes([...selectedRuleTypes]);\n if (selectedRuleTypes.length > 0) {\n fetchAiRules(selectedRuleTypes);\n } else {\n // If no rule types selected, clear rules\n setRules([]);\n setError(null);\n setHasSearched(true);\n }\n }, [selectedRuleTypes, fetchAiRules]);\n\n // Reset filters to allowed rule types and apply immediately\n const resetFilters = useCallback(() => {\n setSelectedRuleTypes(allowedRuleTypes);\n setAppliedRuleTypes([...allowedRuleTypes]);\n if (allowedRuleTypes.length > 0) {\n fetchAiRules(allowedRuleTypes);\n }\n }, [allowedRuleTypes, fetchAiRules]);\n\n // Fetch rules when applied rule types change (triggered by applyFilters)\n useEffect(() => {\n if (appliedRuleTypes.length > 0) {\n fetchAiRules(appliedRuleTypes);\n }\n }, [fetchAiRules, appliedRuleTypes]);\n\n const rulesByType = useMemo(() => {\n return rules.reduce((acc, rule) => {\n if (!acc[rule.type]) {\n acc[rule.type] = [];\n }\n acc[rule.type].push(rule);\n return acc;\n }, {} as Record<AIRuleType, AIRule[]>);\n }, [rules]);\n\n return {\n rules,\n rulesByType,\n loading,\n error,\n hasGitUrl: entityData.hasGitUrl,\n componentName: entityData.name,\n allowedRuleTypes,\n defaultRuleTypes,\n selectedRuleTypes,\n setSelectedRuleTypes,\n appliedRuleTypes,\n applyFilters,\n resetFilters,\n totalRules: rules.length,\n hasSearched,\n hasUnappliedChanges: JSON.stringify(selectedRuleTypes.sort()) !== JSON.stringify(appliedRuleTypes.sort()),\n };\n};"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useAiRules.esm.js","sources":["../../src/hooks/useAiRules.ts"],"sourcesContent":["import { useEntity } from '@backstage/plugin-catalog-react';\nimport { AIRuleType, AIRulesResponse, AIRule } from '../types';\nimport { useState, useEffect, useMemo, useCallback } from 'react';\nimport { useApi, configApiRef, discoveryApiRef, fetchApiRef } from '@backstage/core-plugin-api';\n\nexport const useAiRules = () => {\n const { entity } = useEntity();\n const configApi = useApi(configApiRef);\n const discoveryApi = useApi(discoveryApiRef);\n const fetchApi = useApi(fetchApiRef);\n \n const [rules, setRules] = useState<AIRule[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [selectedRuleTypes, setSelectedRuleTypes] = useState<AIRuleType[]>([]);\n const [appliedRuleTypes, setAppliedRuleTypes] = useState<AIRuleType[]>([]);\n const [initialized, setInitialized] = useState(false);\n const [hasSearched, setHasSearched] = useState(false);\n\n // Stabilize allowed rule types\n const allowedRuleTypes = useMemo(() => {\n return configApi.getOptionalStringArray('aiRules.allowedRuleTypes') as AIRuleType[] || [AIRuleType.CURSOR, AIRuleType.COPILOT, AIRuleType.CLINE, AIRuleType.CLAUDE_CODE];\n }, [configApi]);\n\n // Stabilize default rule types\n const defaultRuleTypes = useMemo(() => {\n // Check if the config has the aiRules section at all\n const aiRulesConfig = configApi.getOptionalConfig('aiRules');\n if (!aiRulesConfig) {\n // Config not loaded yet or aiRules section doesn't exist, use empty array\n return [];\n }\n \n const configuredDefaults = configApi.getOptionalStringArray('aiRules.defaultRuleTypes') as AIRuleType[];\n \n // If defaultRuleTypes is explicitly configured (even as empty array), use that\n // If not configured at all, use empty array\n return configuredDefaults !== undefined ? configuredDefaults : [];\n }, [configApi]);\n\n // Extract stable entity properties\n const entityData = useMemo(() => {\n const sourceAnnotation = entity.metadata?.annotations?.['backstage.io/source-location'] || '';\n const hasGitUrl = sourceAnnotation.startsWith('url:');\n \n let gitUrl = hasGitUrl ? sourceAnnotation.substring(4) : undefined;\n if (gitUrl) {\n // Remove trailing slashes and normalize URL\n gitUrl = gitUrl.replace(/\\/+$/, '');\n // Handle GitHub tree/blob URLs - extract base repo URL\n const treeMatch = gitUrl.match(/^(.+)\\/tree\\/([^/]+)(?:\\/(.+))?$/);\n const blobMatch = gitUrl.match(/^(.+)\\/blob\\/([^/]+)(?:\\/(.+))?$/);\n if (treeMatch) {\n gitUrl = treeMatch[1]; // Just the base repo URL\n }\n if (blobMatch) {\n gitUrl = blobMatch[1]; // Just the base repo URL \n }\n }\n\n return {\n kind: entity.kind,\n namespace: entity.metadata.namespace || 'default',\n name: entity.metadata.name,\n sourceAnnotation,\n hasGitUrl,\n gitUrl,\n };\n }, [entity.kind, entity.metadata.namespace, entity.metadata.name, entity.metadata?.annotations?.['backstage.io/source-location']]);\n\n // Initialize selected and applied rule types when defaultRuleTypes is available\n useEffect(() => {\n // Check if config is loaded\n const aiRulesConfig = configApi.getOptionalConfig('aiRules');\n const configLoaded = aiRulesConfig !== undefined;\n \n if (!initialized && allowedRuleTypes.length > 0 && configLoaded) {\n setSelectedRuleTypes(defaultRuleTypes);\n setAppliedRuleTypes(defaultRuleTypes);\n setInitialized(true);\n }\n }, [defaultRuleTypes, allowedRuleTypes, initialized, configApi]);\n\n // Stable fetch function\n const fetchAiRules = useCallback(async (ruleTypes: AIRuleType[]) => {\n if (!entityData.hasGitUrl || !entityData.gitUrl) {\n setLoading(false);\n return;\n }\n\n try {\n setLoading(true);\n setError(null);\n setHasSearched(true);\n \n const baseUrl = await discoveryApi.getBaseUrl('ai-rules');\n const url = new URL(`${baseUrl}/rules`);\n \n // Send the Git URL directly to the backend\n url.searchParams.append('gitUrl', entityData.gitUrl);\n if (ruleTypes.length > 0) {\n url.searchParams.append('ruleTypes', ruleTypes.join(','));\n }\n\n const response = await fetchApi.fetch(url.toString());\n if (!response.ok) {\n throw new Error(`Failed to fetch AI rules: ${response.statusText}`);\n }\n\n const data: AIRulesResponse = await response.json();\n setRules(data.rules);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Unknown error occurred';\n console.error('Error fetching AI rules:', errorMessage);\n setError(errorMessage);\n setRules([]);\n } finally {\n setLoading(false);\n }\n }, [entityData.hasGitUrl, entityData.gitUrl, discoveryApi, fetchApi]);\n\n // Manual apply filter function\n const applyFilters = useCallback(() => {\n setAppliedRuleTypes([...selectedRuleTypes]);\n if (selectedRuleTypes.length > 0) {\n fetchAiRules(selectedRuleTypes);\n } else {\n // If no rule types selected, clear rules\n setRules([]);\n setError(null);\n setHasSearched(true);\n }\n }, [selectedRuleTypes, fetchAiRules]);\n\n // Reset filters to allowed rule types and apply immediately\n const resetFilters = useCallback(() => {\n setSelectedRuleTypes(allowedRuleTypes);\n setAppliedRuleTypes([...allowedRuleTypes]);\n if (allowedRuleTypes.length > 0) {\n fetchAiRules(allowedRuleTypes);\n }\n }, [allowedRuleTypes, fetchAiRules]);\n\n // Fetch rules when applied rule types change (triggered by applyFilters)\n useEffect(() => {\n if (appliedRuleTypes.length > 0) {\n fetchAiRules(appliedRuleTypes);\n }\n }, [fetchAiRules, appliedRuleTypes]);\n\n const rulesByType = useMemo(() => {\n return rules.reduce((acc, rule) => {\n if (!acc[rule.type]) {\n acc[rule.type] = [];\n }\n acc[rule.type].push(rule);\n return acc;\n }, {} as Record<AIRuleType, AIRule[]>);\n }, [rules]);\n\n return {\n rules,\n rulesByType,\n loading,\n error,\n hasGitUrl: entityData.hasGitUrl,\n componentName: entityData.name,\n allowedRuleTypes,\n defaultRuleTypes,\n selectedRuleTypes,\n setSelectedRuleTypes,\n appliedRuleTypes,\n applyFilters,\n resetFilters,\n totalRules: rules.length,\n hasSearched,\n hasUnappliedChanges: JSON.stringify(selectedRuleTypes.sort()) !== JSON.stringify(appliedRuleTypes.sort()),\n };\n};"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMCPServers.esm.js","sources":["../../src/hooks/useMCPServers.ts"],"sourcesContent":["import { useApi } from '@backstage/core-plugin-api';\nimport { useCallback, useEffect, useState } from 'react';\nimport { aiRulesApiRef } from '../api/types';\nimport type { AiRulesApi } from '../api/types';\nimport { MCPServerInfo } from '../types/mcp';\nimport { useEntity } from '@backstage/plugin-catalog-react';\n\nexport const useMCPServers = () => {\n const api = useApi(aiRulesApiRef) as AiRulesApi;\n const { entity } = useEntity();\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string>();\n const [servers, setServers] = useState<MCPServerInfo[]>([]);\n const [hasGitUrl, setHasGitUrl] = useState(true);\n\n const sourceLocation = entity.metadata?.annotations?.['backstage.io/source-location'];\n\n const fetchServers = useCallback(async () => {\n if (!sourceLocation) {\n setHasGitUrl(false);\n return;\n }\n\n try {\n setLoading(true);\n setError(undefined);\n // Clean up the Git URL - remove url: prefix and /tree/main/ or /tree/master/\n const gitUrl = sourceLocation\n .replace('url:', '')\n .replace(/\\/tree\\/(?:main|master)\\/.*$/, '');\n const response = await api.getMCPServers(gitUrl);\n setServers(response.servers);\n } catch (err) {\n setError((err as Error).message);\n } finally {\n setLoading(false);\n }\n }, [api, sourceLocation]);\n\n useEffect(() => {\n fetchServers();\n }, [fetchServers]);\n\n return {\n loading,\n error,\n servers,\n hasGitUrl,\n refetch: fetchServers,\n };\n};\n"],"names":[],"mappings":";;;;;AAOO,MAAM,gBAAgB,MAAM;AACjC,
|
|
1
|
+
{"version":3,"file":"useMCPServers.esm.js","sources":["../../src/hooks/useMCPServers.ts"],"sourcesContent":["import { useApi } from '@backstage/core-plugin-api';\nimport { useCallback, useEffect, useState } from 'react';\nimport { aiRulesApiRef } from '../api/types';\nimport type { AiRulesApi } from '../api/types';\nimport { MCPServerInfo } from '../types/mcp';\nimport { useEntity } from '@backstage/plugin-catalog-react';\n\nexport const useMCPServers = () => {\n const api = useApi(aiRulesApiRef) as AiRulesApi;\n const { entity } = useEntity();\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string>();\n const [servers, setServers] = useState<MCPServerInfo[]>([]);\n const [hasGitUrl, setHasGitUrl] = useState(true);\n\n const sourceLocation = entity.metadata?.annotations?.['backstage.io/source-location'];\n\n const fetchServers = useCallback(async () => {\n if (!sourceLocation) {\n setHasGitUrl(false);\n return;\n }\n\n try {\n setLoading(true);\n setError(undefined);\n // Clean up the Git URL - remove url: prefix and /tree/main/ or /tree/master/\n const gitUrl = sourceLocation\n .replace('url:', '')\n .replace(/\\/tree\\/(?:main|master)\\/.*$/, '');\n const response = await api.getMCPServers(gitUrl);\n setServers(response.servers);\n } catch (err) {\n setError((err as Error).message);\n } finally {\n setLoading(false);\n }\n }, [api, sourceLocation]);\n\n useEffect(() => {\n fetchServers();\n }, [fetchServers]);\n\n return {\n loading,\n error,\n servers,\n hasGitUrl,\n refetch: fetchServers,\n };\n};\n"],"names":[],"mappings":";;;;;AAOO,MAAM,gBAAgB,MAAM;AACjC,EAAA,MAAM,GAAA,GAAM,OAAO,aAAa,CAAA;AAChC,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,SAAA,EAAU;AAC7B,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,QAAA,EAAiB;AAC3C,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,QAAA,CAA0B,EAAE,CAAA;AAC1D,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,IAAI,CAAA;AAE/C,EAAA,MAAM,cAAA,GAAiB,MAAA,CAAO,QAAA,EAAU,WAAA,GAAc,8BAA8B,CAAA;AAEpF,EAAA,MAAM,YAAA,GAAe,YAAY,YAAY;AAC3C,IAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,MAAA,YAAA,CAAa,KAAK,CAAA;AAClB,MAAA;AAAA,IACF;AAEA,IAAA,IAAI;AACF,MAAA,UAAA,CAAW,IAAI,CAAA;AACf,MAAA,QAAA,CAAS,KAAA,CAAS,CAAA;AAElB,MAAA,MAAM,MAAA,GAAS,eACZ,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA,CAClB,OAAA,CAAQ,gCAAgC,EAAE,CAAA;AAC7C,MAAA,MAAM,QAAA,GAAW,MAAM,GAAA,CAAI,aAAA,CAAc,MAAM,CAAA;AAC/C,MAAA,UAAA,CAAW,SAAS,OAAO,CAAA;AAAA,IAC7B,SAAS,GAAA,EAAK;AACZ,MAAA,QAAA,CAAU,IAAc,OAAO,CAAA;AAAA,IACjC,CAAA,SAAE;AACA,MAAA,UAAA,CAAW,KAAK,CAAA;AAAA,IAClB;AAAA,EACF,CAAA,EAAG,CAAC,GAAA,EAAK,cAAc,CAAC,CAAA;AAExB,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,YAAA,EAAa;AAAA,EACf,CAAA,EAAG,CAAC,YAAY,CAAC,CAAA;AAEjB,EAAA,OAAO;AAAA,IACL,OAAA;AAAA,IACA,KAAA;AAAA,IACA,OAAA;AAAA,IACA,SAAA;AAAA,IACA,OAAA,EAAS;AAAA,GACX;AACF;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,23 +1,8 @@
|
|
|
1
|
-
import { Entity } from '@backstage/catalog-model';
|
|
2
1
|
import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
|
|
3
2
|
import React from 'react';
|
|
3
|
+
import { Entity } from '@backstage/catalog-model';
|
|
4
4
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
5
5
|
|
|
6
|
-
interface AiInstructionsComponentProps {
|
|
7
|
-
title?: string;
|
|
8
|
-
}
|
|
9
|
-
declare const AiInstructionsComponent: ({ title }: AiInstructionsComponentProps) => react_jsx_runtime.JSX.Element;
|
|
10
|
-
|
|
11
|
-
interface MCPServersComponentProps {
|
|
12
|
-
title?: string;
|
|
13
|
-
}
|
|
14
|
-
declare const MCPServersComponent: ({ title }: MCPServersComponentProps) => react_jsx_runtime.JSX.Element;
|
|
15
|
-
|
|
16
|
-
interface AIRulesComponentProps {
|
|
17
|
-
title?: string;
|
|
18
|
-
}
|
|
19
|
-
declare const isAIRulesAvailable: (entity: Entity) => boolean;
|
|
20
|
-
|
|
21
6
|
declare const aiRulesPlugin: _backstage_core_plugin_api.BackstagePlugin<{
|
|
22
7
|
root: _backstage_core_plugin_api.RouteRef<undefined>;
|
|
23
8
|
}, {}, {}>;
|
|
@@ -104,6 +89,21 @@ interface MCPServersResponse {
|
|
|
104
89
|
servers: MCPServerInfo[];
|
|
105
90
|
}
|
|
106
91
|
|
|
92
|
+
interface MCPServersComponentProps {
|
|
93
|
+
title?: string;
|
|
94
|
+
}
|
|
95
|
+
declare const MCPServersComponent: ({ title }: MCPServersComponentProps) => react_jsx_runtime.JSX.Element;
|
|
96
|
+
|
|
97
|
+
interface AiInstructionsComponentProps {
|
|
98
|
+
title?: string;
|
|
99
|
+
}
|
|
100
|
+
declare const AiInstructionsComponent: ({ title }: AiInstructionsComponentProps) => react_jsx_runtime.JSX.Element;
|
|
101
|
+
|
|
102
|
+
interface AIRulesComponentProps {
|
|
103
|
+
title?: string;
|
|
104
|
+
}
|
|
105
|
+
declare const isAIRulesAvailable: (entity: Entity) => boolean;
|
|
106
|
+
|
|
107
107
|
declare const aiRulesApiRef: _backstage_core_plugin_api.ApiRef<AiRulesApi>;
|
|
108
108
|
interface AiRulesApi {
|
|
109
109
|
getAiRules(ruleTypes: string[]): Promise<AIRulesResponse>;
|
|
@@ -129,4 +129,5 @@ declare class AiRulesClient implements AiRulesApi {
|
|
|
129
129
|
getMCPServers(gitUrl: string): Promise<MCPServersResponse>;
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
export {
|
|
132
|
+
export { AIRuleType, AIRulesComponent, AiInstructionsComponent, AiRulesClient, MCPServersComponent, aiRulesApiRef, aiRulesPlugin, isAIRulesAvailable };
|
|
133
|
+
export type { AIRule, AIRulesComponentProps, AIRulesConfig, AIRulesResponse, AiInstructionsComponentProps, AiRulesApi, ClaudeCodeRule, ClineRule, CopilotRule, CursorRule, MCPServerConfig, MCPServerInfo, MCPServersComponentProps, MCPServersResponse };
|
package/dist/plugin.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.esm.js","sources":["../src/plugin.ts"],"sourcesContent":["import { createPlugin, createComponentExtension } from '@backstage/core-plugin-api';\nimport { rootRouteRef } from './routes';\nimport React from 'react';\n\nexport const aiRulesPlugin = createPlugin({\n id: 'ai-rules',\n routes: {\n root: rootRouteRef,\n },\n});\n\nexport const AIRulesComponent = aiRulesPlugin.provide(\n createComponentExtension({\n name: 'AIRulesComponent',\n component: {\n lazy: () => import('./components/AiRulesComponent/AiRulesComponent').then(m => m.AIRulesComponent)\n .then(Component => (props: any) => React.createElement(Component, props)),\n },\n }),\n);\n\nexport const MCPServersComponent = aiRulesPlugin.provide(\n createComponentExtension({\n name: 'MCPServersComponent',\n component: {\n lazy: () => import('./components/MCPServersComponent/MCPServersComponent').then(m => m.MCPServersComponent)\n .then(Component => (props: any) => React.createElement(Component, props)),\n },\n }),\n);\n\nexport const AiInstructionsComponent = aiRulesPlugin.provide(\n createComponentExtension({\n name: 'AiInstructionsComponent',\n component: {\n lazy: () => import('./components/AiInstructionsComponent/AiInstructionsComponent').then(m => m.AiInstructionsComponent)\n .then(Component => (props: any) => React.createElement(Component, props)),\n },\n }),\n);"],"names":[],"mappings":";;;;AAIO,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"plugin.esm.js","sources":["../src/plugin.ts"],"sourcesContent":["import { createPlugin, createComponentExtension } from '@backstage/core-plugin-api';\nimport { rootRouteRef } from './routes';\nimport React from 'react';\n\nexport const aiRulesPlugin = createPlugin({\n id: 'ai-rules',\n routes: {\n root: rootRouteRef,\n },\n});\n\nexport const AIRulesComponent = aiRulesPlugin.provide(\n createComponentExtension({\n name: 'AIRulesComponent',\n component: {\n lazy: () => import('./components/AiRulesComponent/AiRulesComponent').then(m => m.AIRulesComponent)\n .then(Component => (props: any) => React.createElement(Component, props)),\n },\n }),\n);\n\nexport const MCPServersComponent = aiRulesPlugin.provide(\n createComponentExtension({\n name: 'MCPServersComponent',\n component: {\n lazy: () => import('./components/MCPServersComponent/MCPServersComponent').then(m => m.MCPServersComponent)\n .then(Component => (props: any) => React.createElement(Component, props)),\n },\n }),\n);\n\nexport const AiInstructionsComponent = aiRulesPlugin.provide(\n createComponentExtension({\n name: 'AiInstructionsComponent',\n component: {\n lazy: () => import('./components/AiInstructionsComponent/AiInstructionsComponent').then(m => m.AiInstructionsComponent)\n .then(Component => (props: any) => React.createElement(Component, props)),\n },\n }),\n);"],"names":[],"mappings":";;;;AAIO,MAAM,gBAAgB,YAAA,CAAa;AAAA,EACxC,EAAA,EAAI,UAAA;AAAA,EACJ,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM;AAAA;AAEV,CAAC;AAEM,MAAM,mBAAmB,aAAA,CAAc,OAAA;AAAA,EAC5C,wBAAA,CAAyB;AAAA,IACvB,IAAA,EAAM,kBAAA;AAAA,IACN,SAAA,EAAW;AAAA,MACT,MAAM,MAAM,OAAO,uDAAgD,CAAA,CAAE,IAAA,CAAK,OAAK,CAAA,CAAE,gBAAgB,CAAA,CAC9F,IAAA,CAAK,eAAa,CAAC,KAAA,KAAe,MAAM,aAAA,CAAc,SAAA,EAAW,KAAK,CAAC;AAAA;AAC5E,GACD;AACH;AAEmC,aAAA,CAAc,OAAA;AAAA,EAC/C,wBAAA,CAAyB;AAAA,IACvB,IAAA,EAAM,qBAAA;AAAA,IACN,SAAA,EAAW;AAAA,MACT,MAAM,MAAM,OAAO,6DAAsD,CAAA,CAAE,IAAA,CAAK,OAAK,CAAA,CAAE,mBAAmB,CAAA,CACvG,IAAA,CAAK,eAAa,CAAC,KAAA,KAAe,MAAM,aAAA,CAAc,SAAA,EAAW,KAAK,CAAC;AAAA;AAC5E,GACD;AACH;AAEuC,aAAA,CAAc,OAAA;AAAA,EACnD,wBAAA,CAAyB;AAAA,IACvB,IAAA,EAAM,yBAAA;AAAA,IACN,SAAA,EAAW;AAAA,MACT,MAAM,MAAM,OAAO,qEAA8D,CAAA,CAAE,IAAA,CAAK,OAAK,CAAA,CAAE,uBAAuB,CAAA,CACnH,IAAA,CAAK,eAAa,CAAC,KAAA,KAAe,MAAM,aAAA,CAAc,SAAA,EAAW,KAAK,CAAC;AAAA;AAC5E,GACD;AACH;;;;"}
|
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/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'ai-rules',\n});"],"names":[],"mappings":";;AAEO,MAAM,eAAe,
|
|
1
|
+
{"version":3,"file":"routes.esm.js","sources":["../src/routes.ts"],"sourcesContent":["import { createRouteRef } from '@backstage/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'ai-rules',\n});"],"names":[],"mappings":";;AAEO,MAAM,eAAe,cAAA,CAAe;AAAA,EACzC,EAAA,EAAI;AACN,CAAC;;;;"}
|
package/dist/types.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.esm.js","sources":["../src/types.ts"],"sourcesContent":["export enum AIRuleType {\n CURSOR = 'cursor',\n COPILOT = 'copilot', \n CLINE = 'cline',\n CLAUDE_CODE = 'claude-code',\n}\n\nexport interface CursorRule {\n type: AIRuleType.CURSOR;\n id: string;\n filePath: string;\n fileName: string;\n gitUrl?: string;\n description?: string;\n globs?: string[];\n alwaysApply?: boolean;\n frontmatter?: Record<string, any>;\n content: string;\n}\n\nexport interface CopilotRule {\n type: AIRuleType.COPILOT;\n id: string;\n filePath: string;\n fileName: string;\n gitUrl?: string;\n content: string;\n order?: number; // Position in the file (legacy)\n title?: string;\n applyTo?: string;\n frontmatter?: Record<string, any>;\n}\n\nexport interface ClineRule {\n type: AIRuleType.CLINE;\n id: string;\n filePath: string;\n fileName: string;\n gitUrl?: string;\n content: string;\n title?: string;\n sections?: Array<{\n title: string;\n content: string;\n }>;\n}\n\nexport interface ClaudeCodeRule {\n type: AIRuleType.CLAUDE_CODE;\n id: string;\n filePath: string;\n fileName: string;\n gitUrl?: string;\n content: string;\n title?: string;\n}\n\nexport type AIRule = CursorRule | CopilotRule | ClineRule | ClaudeCodeRule;\n\nexport interface AIRulesResponse {\n rules: AIRule[];\n totalCount: number;\n ruleTypes: AIRuleType[];\n}\n\nexport interface AIRulesConfig {\n allowedRuleTypes?: AIRuleType[];\n}"],"names":["AIRuleType"],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.esm.js","sources":["../src/types.ts"],"sourcesContent":["export enum AIRuleType {\n CURSOR = 'cursor',\n COPILOT = 'copilot', \n CLINE = 'cline',\n CLAUDE_CODE = 'claude-code',\n}\n\nexport interface CursorRule {\n type: AIRuleType.CURSOR;\n id: string;\n filePath: string;\n fileName: string;\n gitUrl?: string;\n description?: string;\n globs?: string[];\n alwaysApply?: boolean;\n frontmatter?: Record<string, any>;\n content: string;\n}\n\nexport interface CopilotRule {\n type: AIRuleType.COPILOT;\n id: string;\n filePath: string;\n fileName: string;\n gitUrl?: string;\n content: string;\n order?: number; // Position in the file (legacy)\n title?: string;\n applyTo?: string;\n frontmatter?: Record<string, any>;\n}\n\nexport interface ClineRule {\n type: AIRuleType.CLINE;\n id: string;\n filePath: string;\n fileName: string;\n gitUrl?: string;\n content: string;\n title?: string;\n sections?: Array<{\n title: string;\n content: string;\n }>;\n}\n\nexport interface ClaudeCodeRule {\n type: AIRuleType.CLAUDE_CODE;\n id: string;\n filePath: string;\n fileName: string;\n gitUrl?: string;\n content: string;\n title?: string;\n}\n\nexport type AIRule = CursorRule | CopilotRule | ClineRule | ClaudeCodeRule;\n\nexport interface AIRulesResponse {\n rules: AIRule[];\n totalCount: number;\n ruleTypes: AIRuleType[];\n}\n\nexport interface AIRulesConfig {\n allowedRuleTypes?: AIRuleType[];\n}"],"names":["AIRuleType"],"mappings":"AAAO,IAAK,UAAA,qBAAAA,WAAAA,KAAL;AACL,EAAAA,YAAA,QAAA,CAAA,GAAS,QAAA;AACT,EAAAA,YAAA,SAAA,CAAA,GAAU,SAAA;AACV,EAAAA,YAAA,OAAA,CAAA,GAAQ,OAAA;AACR,EAAAA,YAAA,aAAA,CAAA,GAAc,aAAA;AAJJ,EAAA,OAAAA,WAAAA;AAAA,CAAA,EAAA,UAAA,IAAA,EAAA;;;;"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@terasky/backstage-plugin-ai-rules",
|
|
3
3
|
"description": "AI Rules Visualizer Plugin for Backstage",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.4.0",
|
|
5
5
|
"main": "./dist/index.esm.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
7
|
"license": "Apache-2.0",
|
|
@@ -38,11 +38,11 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@backstage/catalog-model": "^1.7.6",
|
|
41
|
-
"@backstage/core-components": "^0.18.
|
|
42
|
-
"@backstage/core-plugin-api": "^1.12.
|
|
43
|
-
"@backstage/frontend-plugin-api": "^0.13.
|
|
44
|
-
"@backstage/plugin-catalog-react": "^1.21.
|
|
45
|
-
"@backstage/theme": "^0.7.
|
|
41
|
+
"@backstage/core-components": "^0.18.5",
|
|
42
|
+
"@backstage/core-plugin-api": "^1.12.1",
|
|
43
|
+
"@backstage/frontend-plugin-api": "^0.13.3",
|
|
44
|
+
"@backstage/plugin-catalog-react": "^1.21.5",
|
|
45
|
+
"@backstage/theme": "^0.7.1",
|
|
46
46
|
"@material-ui/core": "^4.12.4",
|
|
47
47
|
"@material-ui/icons": "^4.11.3",
|
|
48
48
|
"@material-ui/lab": "4.0.0-alpha.61"
|
|
@@ -51,10 +51,10 @@
|
|
|
51
51
|
"react": "^16.13.1 || ^17.0.0 || ^18.0.0"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
|
-
"@backstage/cli": "^0.
|
|
55
|
-
"@backstage/core-app-api": "^1.19.
|
|
56
|
-
"@backstage/dev-utils": "^1.1.
|
|
57
|
-
"@backstage/test-utils": "^1.7.
|
|
54
|
+
"@backstage/cli": "^0.35.2",
|
|
55
|
+
"@backstage/core-app-api": "^1.19.3",
|
|
56
|
+
"@backstage/dev-utils": "^1.1.19",
|
|
57
|
+
"@backstage/test-utils": "^1.7.14",
|
|
58
58
|
"@testing-library/jest-dom": "^6.0.0",
|
|
59
59
|
"@testing-library/react": "^14.0.0",
|
|
60
60
|
"@testing-library/user-event": "^14.0.0",
|