@showcall/backstage-plugin-agent-catalog 0.1.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.
@@ -0,0 +1,16 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { SidebarItem } from '@backstage/core-components';
3
+ import AndroidIcon from '@material-ui/icons/Android';
4
+ import { agentCatalogNavItem } from '../nav.esm.js';
5
+
6
+ const AgentCatalogSidebarItem = () => /* @__PURE__ */ jsx(
7
+ SidebarItem,
8
+ {
9
+ icon: AndroidIcon,
10
+ to: agentCatalogNavItem.path,
11
+ text: agentCatalogNavItem.title
12
+ }
13
+ );
14
+
15
+ export { AgentCatalogSidebarItem };
16
+ //# sourceMappingURL=AgentCatalogSidebarItem.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentCatalogSidebarItem.esm.js","sources":["../../src/components/AgentCatalogSidebarItem.tsx"],"sourcesContent":["import { SidebarItem } from '@backstage/core-components';\nimport AndroidIcon from '@material-ui/icons/Android';\nimport { agentCatalogNavItem } from '../nav';\n\nexport const AgentCatalogSidebarItem = () => (\n <SidebarItem\n icon={AndroidIcon}\n to={agentCatalogNavItem.path}\n text={agentCatalogNavItem.title}\n />\n);\n"],"names":[],"mappings":";;;;;AAIO,MAAM,0BAA0B,sBACrC,GAAA;AAAA,EAAC,WAAA;AAAA,EAAA;AAAA,IACC,IAAA,EAAM,WAAA;AAAA,IACN,IAAI,mBAAA,CAAoB,IAAA;AAAA,IACxB,MAAM,mBAAA,CAAoB;AAAA;AAC5B;;;;"}
@@ -0,0 +1,87 @@
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { InfoCard } from '@backstage/core-components';
3
+ import { useEntity } from '@backstage/plugin-catalog-react';
4
+ import { Grid, Chip, Typography } from '@material-ui/core';
5
+
6
+ const A = "agentcatalog.io";
7
+ const Stat = ({ label, value }) => /* @__PURE__ */ jsxs(Grid, { item: true, xs: 4, children: [
8
+ /* @__PURE__ */ jsx(Typography, { variant: "overline", color: "textSecondary", component: "div", children: label }),
9
+ /* @__PURE__ */ jsx(Typography, { variant: "h6", component: "div", children: value })
10
+ ] });
11
+ const AgentInfoCard = () => {
12
+ const { entity } = useEntity();
13
+ const ann = entity.metadata.annotations ?? {};
14
+ const agent = entity.spec?.agent ?? {};
15
+ const requests = ann[`${A}/usage-requests`];
16
+ const tokens = ann[`${A}/usage-tokens`];
17
+ const cost = ann[`${A}/usage-cost-usd`];
18
+ const window = ann[`${A}/usage-window`] ?? "";
19
+ const lastActive = ann[`${A}/last-active`];
20
+ const reachable = ann[`${A}/reachable`];
21
+ const cardSource = ann[`${A}/card-source`];
22
+ const discovery = ann[`${A}/discovery`];
23
+ const runtime = ann[`${A}/runtime`];
24
+ const modelConfig = ann[`${A}/model-config`];
25
+ const image = ann[`${A}/image`];
26
+ const signals = ann[`${A}/heuristic-signals`];
27
+ const isHeuristic = discovery === "heuristic";
28
+ return /* @__PURE__ */ jsx(
29
+ InfoCard,
30
+ {
31
+ title: isHeuristic ? "LLM workload (heuristic finding)" : "Agent",
32
+ subheader: isHeuristic ? void 0 : `runtime: ${runtime ?? "unknown"}`,
33
+ children: /* @__PURE__ */ jsxs(Grid, { container: true, spacing: 2, children: [
34
+ /* @__PURE__ */ jsxs(Grid, { item: true, xs: 12, children: [
35
+ discovery && /* @__PURE__ */ jsx(Chip, { size: "small", variant: "outlined", label: `discovery: ${discovery}` }),
36
+ reachable && /* @__PURE__ */ jsx(
37
+ Chip,
38
+ {
39
+ size: "small",
40
+ label: reachable === "true" ? "reachable" : "unreachable",
41
+ style: {
42
+ backgroundColor: reachable === "true" ? "#1db95433" : "#e5484d33"
43
+ }
44
+ }
45
+ ),
46
+ cardSource && /* @__PURE__ */ jsx(Chip, { size: "small", variant: "outlined", label: `card: ${cardSource}` })
47
+ ] }),
48
+ /* @__PURE__ */ jsx(Stat, { label: `Requests${window ? ` / ${window}` : ""}`, value: requests ?? "\u2014" }),
49
+ /* @__PURE__ */ jsx(Stat, { label: "Tokens", value: tokens ?? "\u2014" }),
50
+ /* @__PURE__ */ jsx(Stat, { label: "Last active", value: lastActive ?? "\u2014" }),
51
+ cost && /* @__PURE__ */ jsx(Stat, { label: `Cost / ${window}`, value: `$${cost}` }),
52
+ signals && /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, children: /* @__PURE__ */ jsxs(Typography, { variant: "body2", color: "textSecondary", children: [
53
+ "Flagged because: ",
54
+ /* @__PURE__ */ jsx("code", { children: signals }),
55
+ ". If this is a real agent, label its Service ",
56
+ /* @__PURE__ */ jsx("code", { children: 'agentcatalog.io/a2a: "true"' }),
57
+ "; if it's a false positive, label it ",
58
+ /* @__PURE__ */ jsx("code", { children: '"false"' }),
59
+ "."
60
+ ] }) }),
61
+ (modelConfig || image) && /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, children: /* @__PURE__ */ jsxs(Typography, { variant: "body2", color: "textSecondary", children: [
62
+ modelConfig && /* @__PURE__ */ jsxs(Fragment, { children: [
63
+ "model config: ",
64
+ /* @__PURE__ */ jsx("code", { children: modelConfig }),
65
+ " "
66
+ ] }),
67
+ image && /* @__PURE__ */ jsxs(Fragment, { children: [
68
+ "image: ",
69
+ /* @__PURE__ */ jsx("code", { children: image })
70
+ ] })
71
+ ] }) }),
72
+ requests === void 0 && /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, children: /* @__PURE__ */ jsxs(Typography, { variant: "body2", color: "textSecondary", children: [
73
+ "No per-agent usage: this agent has no gateway key alias. Issue it a key aliased ",
74
+ /* @__PURE__ */ jsxs("code", { children: [
75
+ String(agent.namespace ?? "ns"),
76
+ "/",
77
+ entity.metadata.title ?? entity.metadata.name
78
+ ] }),
79
+ " to light up traction."
80
+ ] }) })
81
+ ] })
82
+ }
83
+ );
84
+ };
85
+
86
+ export { AgentInfoCard };
87
+ //# sourceMappingURL=AgentInfoCard.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentInfoCard.esm.js","sources":["../../src/components/AgentInfoCard.tsx"],"sourcesContent":["/**\n * Per-agent card for entity overview pages: traction + status at a glance,\n * so nobody needs the entity inspector to answer \"is this agent alive and\n * does anyone use it\".\n */\n\nimport type { ReactNode } from 'react';\nimport { InfoCard } from '@backstage/core-components';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport { Chip, Grid, Typography } from '@material-ui/core';\n\nconst A = 'agentcatalog.io';\n\nconst Stat = ({ label, value }: { label: string; value: ReactNode }) => (\n <Grid item xs={4}>\n <Typography variant=\"overline\" color=\"textSecondary\" component=\"div\">\n {label}\n </Typography>\n <Typography variant=\"h6\" component=\"div\">\n {value}\n </Typography>\n </Grid>\n);\n\nexport const AgentInfoCard = () => {\n const { entity } = useEntity();\n const ann = entity.metadata.annotations ?? {};\n const agent = (entity.spec as { agent?: Record<string, unknown> })?.agent ?? {};\n\n const requests = ann[`${A}/usage-requests`];\n const tokens = ann[`${A}/usage-tokens`];\n const cost = ann[`${A}/usage-cost-usd`];\n const window = ann[`${A}/usage-window`] ?? '';\n const lastActive = ann[`${A}/last-active`];\n const reachable = ann[`${A}/reachable`];\n const cardSource = ann[`${A}/card-source`];\n const discovery = ann[`${A}/discovery`];\n const runtime = ann[`${A}/runtime`];\n const modelConfig = ann[`${A}/model-config`];\n const image = ann[`${A}/image`];\n const signals = ann[`${A}/heuristic-signals`];\n const isHeuristic = discovery === 'heuristic';\n\n return (\n <InfoCard\n title={isHeuristic ? 'LLM workload (heuristic finding)' : 'Agent'}\n subheader={isHeuristic ? undefined : `runtime: ${runtime ?? 'unknown'}`}\n >\n <Grid container spacing={2}>\n <Grid item xs={12}>\n {discovery && <Chip size=\"small\" variant=\"outlined\" label={`discovery: ${discovery}`} />}\n {reachable && (\n <Chip\n size=\"small\"\n label={reachable === 'true' ? 'reachable' : 'unreachable'}\n style={{\n backgroundColor: reachable === 'true' ? '#1db95433' : '#e5484d33',\n }}\n />\n )}\n {cardSource && <Chip size=\"small\" variant=\"outlined\" label={`card: ${cardSource}`} />}\n </Grid>\n\n <Stat label={`Requests${window ? ` / ${window}` : ''}`} value={requests ?? '—'} />\n <Stat label=\"Tokens\" value={tokens ?? '—'} />\n <Stat label=\"Last active\" value={lastActive ?? '—'} />\n {cost && <Stat label={`Cost / ${window}`} value={`$${cost}`} />}\n\n {signals && (\n <Grid item xs={12}>\n <Typography variant=\"body2\" color=\"textSecondary\">\n Flagged because: <code>{signals}</code>. If this is a real\n agent, label its Service <code>agentcatalog.io/a2a: \"true\"</code>;\n if it's a false positive, label it <code>\"false\"</code>.\n </Typography>\n </Grid>\n )}\n {(modelConfig || image) && (\n <Grid item xs={12}>\n <Typography variant=\"body2\" color=\"textSecondary\">\n {modelConfig && <>model config: <code>{modelConfig}</code> </>}\n {image && <>image: <code>{image}</code></>}\n </Typography>\n </Grid>\n )}\n {requests === undefined && (\n <Grid item xs={12}>\n <Typography variant=\"body2\" color=\"textSecondary\">\n No per-agent usage: this agent has no gateway key alias. Issue it\n a key aliased <code>{String(agent.namespace ?? 'ns')}/{entity.metadata.title ?? entity.metadata.name}</code> to\n light up traction.\n </Typography>\n </Grid>\n )}\n </Grid>\n </InfoCard>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,106 @@
1
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
+ import { useState, useEffect } from 'react';
3
+ import { Page, Header, Content, ResponseErrorPanel, Progress, Table } from '@backstage/core-components';
4
+ import { useApi } from '@backstage/core-plugin-api';
5
+ import { catalogApiRef, EntityRefLink } from '@backstage/plugin-catalog-react';
6
+ import { Chip } from '@material-ui/core';
7
+
8
+ const A = "agentcatalog.io";
9
+ function toRow(entity) {
10
+ const ann = entity.metadata.annotations ?? {};
11
+ const requests = ann[`${A}/usage-requests`];
12
+ return {
13
+ entity,
14
+ name: entity.metadata.title ?? entity.metadata.name,
15
+ owner: String(entity.spec?.owner ?? "\u2014"),
16
+ runtime: ann[`${A}/runtime`] ?? "unknown",
17
+ discovery: ann[`${A}/discovery`] ?? "\u2014",
18
+ lifecycle: String(entity.spec?.lifecycle ?? "\u2014"),
19
+ reachable: ann[`${A}/reachable`] ?? "\u2014",
20
+ lastActive: ann[`${A}/last-active`] ?? "\u2014",
21
+ requests: requests !== void 0 ? Number(requests) : void 0,
22
+ window: ann[`${A}/usage-window`] ?? ""
23
+ };
24
+ }
25
+ const columns = [
26
+ {
27
+ title: "Agent",
28
+ field: "name",
29
+ highlight: true,
30
+ render: (row) => /* @__PURE__ */ jsx(EntityRefLink, { entityRef: row.entity, title: row.name })
31
+ },
32
+ { title: "Owner", field: "owner" },
33
+ { title: "Runtime", field: "runtime" },
34
+ {
35
+ title: "Discovery",
36
+ field: "discovery",
37
+ render: (row) => /* @__PURE__ */ jsx(Chip, { label: row.discovery, size: "small", variant: "outlined" })
38
+ },
39
+ { title: "Lifecycle", field: "lifecycle" },
40
+ {
41
+ title: "Reachable",
42
+ field: "reachable",
43
+ render: (row) => row.reachable === "\u2014" ? /* @__PURE__ */ jsx(Fragment, { children: "\u2014" }) : /* @__PURE__ */ jsx(
44
+ Chip,
45
+ {
46
+ label: row.reachable === "true" ? "yes" : "no",
47
+ size: "small",
48
+ style: {
49
+ backgroundColor: row.reachable === "true" ? "#1db95433" : "#e5484d33"
50
+ }
51
+ }
52
+ )
53
+ },
54
+ { title: "Last active", field: "lastActive" },
55
+ {
56
+ title: "Requests",
57
+ field: "requests",
58
+ type: "numeric",
59
+ render: (row) => row.requests !== void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
60
+ row.requests,
61
+ /* @__PURE__ */ jsxs("span", { style: { opacity: 0.6 }, children: [
62
+ " /",
63
+ row.window
64
+ ] })
65
+ ] }) : /* @__PURE__ */ jsx("span", { style: { opacity: 0.6 }, children: "no key alias" })
66
+ }
67
+ ];
68
+ const FleetPage = () => {
69
+ const catalogApi = useApi(catalogApiRef);
70
+ const [rows, setRows] = useState();
71
+ const [error, setError] = useState();
72
+ useEffect(() => {
73
+ catalogApi.getEntities({
74
+ // agents + multi-agent teams + honest heuristic findings
75
+ filter: {
76
+ kind: "Component",
77
+ "spec.type": ["ai-agent", "ai-agent-team", "llm-workload"]
78
+ }
79
+ }).then((res) => setRows(res.items.map(toRow))).catch(setError);
80
+ }, [catalogApi]);
81
+ return /* @__PURE__ */ jsxs(Page, { themeId: "tool", children: [
82
+ /* @__PURE__ */ jsx(
83
+ Header,
84
+ {
85
+ title: "AI Agents",
86
+ subtitle: "It's 10 PM. Do you know where your agents are?"
87
+ }
88
+ ),
89
+ /* @__PURE__ */ jsxs(Content, { children: [
90
+ error && /* @__PURE__ */ jsx(ResponseErrorPanel, { error }),
91
+ !rows && !error && /* @__PURE__ */ jsx(Progress, {}),
92
+ rows && /* @__PURE__ */ jsx(
93
+ Table,
94
+ {
95
+ title: `Fleet (${rows.length})`,
96
+ options: { search: true, paging: false, padding: "dense" },
97
+ columns,
98
+ data: rows
99
+ }
100
+ )
101
+ ] })
102
+ ] });
103
+ };
104
+
105
+ export { FleetPage };
106
+ //# sourceMappingURL=FleetPage.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FleetPage.esm.js","sources":["../../src/components/FleetPage.tsx"],"sourcesContent":["/**\n * The fleet view: every AI agent across all sources, one table.\n * \"It's 10 PM. Do you know where your agents are?\"\n */\n\nimport { useEffect, useState } from 'react';\nimport {\n Content,\n Header,\n Page,\n Progress,\n ResponseErrorPanel,\n Table,\n TableColumn,\n} from '@backstage/core-components';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { catalogApiRef, EntityRefLink } from '@backstage/plugin-catalog-react';\nimport type { Entity } from '@backstage/catalog-model';\nimport { Chip } from '@material-ui/core';\n\nconst A = 'agentcatalog.io';\n\ninterface AgentRow {\n entity: Entity;\n name: string;\n owner: string;\n runtime: string;\n discovery: string;\n lifecycle: string;\n reachable: string;\n lastActive: string;\n requests: number | undefined;\n window: string;\n}\n\nfunction toRow(entity: Entity): AgentRow {\n const ann = entity.metadata.annotations ?? {};\n const requests = ann[`${A}/usage-requests`];\n return {\n entity,\n name: entity.metadata.title ?? entity.metadata.name,\n owner: String(entity.spec?.owner ?? '—'),\n runtime: ann[`${A}/runtime`] ?? 'unknown',\n discovery: ann[`${A}/discovery`] ?? '—',\n lifecycle: String(entity.spec?.lifecycle ?? '—'),\n reachable: ann[`${A}/reachable`] ?? '—',\n lastActive: ann[`${A}/last-active`] ?? '—',\n requests: requests !== undefined ? Number(requests) : undefined,\n window: ann[`${A}/usage-window`] ?? '',\n };\n}\n\nconst columns: TableColumn<AgentRow>[] = [\n {\n title: 'Agent',\n field: 'name',\n highlight: true,\n render: row => <EntityRefLink entityRef={row.entity} title={row.name} />,\n },\n { title: 'Owner', field: 'owner' },\n { title: 'Runtime', field: 'runtime' },\n {\n title: 'Discovery',\n field: 'discovery',\n render: row => <Chip label={row.discovery} size=\"small\" variant=\"outlined\" />,\n },\n { title: 'Lifecycle', field: 'lifecycle' },\n {\n title: 'Reachable',\n field: 'reachable',\n render: row =>\n row.reachable === '—' ? (\n <>—</>\n ) : (\n <Chip\n label={row.reachable === 'true' ? 'yes' : 'no'}\n size=\"small\"\n style={{\n backgroundColor: row.reachable === 'true' ? '#1db95433' : '#e5484d33',\n }}\n />\n ),\n },\n { title: 'Last active', field: 'lastActive' },\n {\n title: 'Requests',\n field: 'requests',\n type: 'numeric',\n render: row =>\n row.requests !== undefined ? (\n <>\n {row.requests}\n <span style={{ opacity: 0.6 }}> /{row.window}</span>\n </>\n ) : (\n <span style={{ opacity: 0.6 }}>no key alias</span>\n ),\n },\n];\n\nexport const FleetPage = () => {\n const catalogApi = useApi(catalogApiRef);\n const [rows, setRows] = useState<AgentRow[] | undefined>();\n const [error, setError] = useState<Error | undefined>();\n\n useEffect(() => {\n catalogApi\n .getEntities({\n // agents + multi-agent teams + honest heuristic findings\n filter: {\n kind: 'Component',\n 'spec.type': ['ai-agent', 'ai-agent-team', 'llm-workload'],\n },\n })\n .then(res => setRows(res.items.map(toRow)))\n .catch(setError);\n }, [catalogApi]);\n\n return (\n <Page themeId=\"tool\">\n <Header\n title=\"AI Agents\"\n subtitle=\"It's 10 PM. Do you know where your agents are?\"\n />\n <Content>\n {error && <ResponseErrorPanel error={error} />}\n {!rows && !error && <Progress />}\n {rows && (\n <Table<AgentRow>\n title={`Fleet (${rows.length})`}\n options={{ search: true, paging: false, padding: 'dense' }}\n columns={columns}\n data={rows}\n />\n )}\n </Content>\n </Page>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ import * as _backstage_plugin_catalog_react_alpha from '@backstage/plugin-catalog-react/alpha';
2
+ import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
3
+ import * as react from 'react';
4
+ import * as _backstage_filter_predicates from '@backstage/filter-predicates';
5
+ import { Entity } from '@backstage/catalog-model';
6
+
7
+ declare const _default: _backstage_frontend_plugin_api.OverridableFrontendPlugin<{}, {}, {
8
+ "entity-card:agent-catalog/agent-info": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
9
+ kind: "entity-card";
10
+ name: "agent-info";
11
+ config: {
12
+ filter: _backstage_filter_predicates.FilterPredicate | undefined;
13
+ type: "content" | "info" | undefined;
14
+ };
15
+ configInput: {
16
+ filter?: _backstage_filter_predicates.FilterPredicate | undefined;
17
+ type?: "content" | "info" | undefined;
18
+ };
19
+ output: _backstage_frontend_plugin_api.ExtensionDataRef<react.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<(entity: Entity) => boolean, "catalog.entity-filter-function", {
20
+ optional: true;
21
+ }> | _backstage_frontend_plugin_api.ExtensionDataRef<string, "catalog.entity-filter-expression", {
22
+ optional: true;
23
+ }> | _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_plugin_catalog_react_alpha.EntityCardType, "catalog.entity-card-type", {
24
+ optional: true;
25
+ }>;
26
+ inputs: {};
27
+ params: {
28
+ loader: () => Promise<JSX.Element>;
29
+ filter?: string | _backstage_filter_predicates.FilterPredicate | ((entity: Entity) => boolean);
30
+ type?: _backstage_plugin_catalog_react_alpha.EntityCardType;
31
+ };
32
+ }>;
33
+ "page:agent-catalog": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
34
+ kind: "page";
35
+ name: undefined;
36
+ config: {
37
+ path: string | undefined;
38
+ title: string | undefined;
39
+ };
40
+ configInput: {
41
+ path?: string | undefined;
42
+ title?: string | undefined;
43
+ };
44
+ output: _backstage_frontend_plugin_api.ExtensionDataRef<string, "core.routing.path", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.RouteRef<_backstage_frontend_plugin_api.AnyRouteRefParams>, "core.routing.ref", {
45
+ optional: true;
46
+ }> | _backstage_frontend_plugin_api.ExtensionDataRef<react.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<string, "core.title", {
47
+ optional: true;
48
+ }> | _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.IconElement, "core.icon", {
49
+ optional: true;
50
+ }>;
51
+ inputs: {
52
+ pages: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<react.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "core.routing.path", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<_backstage_frontend_plugin_api.RouteRef<_backstage_frontend_plugin_api.AnyRouteRefParams>, "core.routing.ref", {
53
+ optional: true;
54
+ }> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "core.title", {
55
+ optional: true;
56
+ }> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<_backstage_frontend_plugin_api.IconElement, "core.icon", {
57
+ optional: true;
58
+ }>, {
59
+ singleton: false;
60
+ optional: false;
61
+ internal: false;
62
+ }>;
63
+ };
64
+ params: {
65
+ path: string;
66
+ title?: string;
67
+ icon?: _backstage_frontend_plugin_api.IconElement;
68
+ loader?: () => Promise<react.JSX.Element>;
69
+ routeRef?: _backstage_frontend_plugin_api.RouteRef;
70
+ noHeader?: boolean;
71
+ };
72
+ }>;
73
+ }>;
74
+
75
+ declare const AgentCatalogSidebarItem: () => react.JSX.Element;
76
+
77
+ declare const agentCatalogNavItem: {
78
+ readonly path: "/agents";
79
+ readonly title: "Agents";
80
+ };
81
+
82
+ export { AgentCatalogSidebarItem, agentCatalogNavItem, _default as default };
@@ -0,0 +1,4 @@
1
+ export { default } from './plugin.esm.js';
2
+ export { AgentCatalogSidebarItem } from './components/AgentCatalogSidebarItem.esm.js';
3
+ export { agentCatalogNavItem } from './nav.esm.js';
4
+ //# sourceMappingURL=index.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
@@ -0,0 +1,7 @@
1
+ const agentCatalogNavItem = {
2
+ path: "/agents",
3
+ title: "Agents"
4
+ };
5
+
6
+ export { agentCatalogNavItem };
7
+ //# sourceMappingURL=nav.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nav.esm.js","sources":["../src/nav.ts"],"sourcesContent":["export const agentCatalogNavItem = {\n path: '/agents',\n title: 'Agents',\n} as const;\n"],"names":[],"mappings":"AAAO,MAAM,mBAAA,GAAsB;AAAA,EACjC,IAAA,EAAM,SAAA;AAAA,EACN,KAAA,EAAO;AACT;;;;"}
@@ -0,0 +1,30 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { PageBlueprint, createFrontendPlugin } from '@backstage/frontend-plugin-api';
3
+ import { EntityCardBlueprint } from '@backstage/plugin-catalog-react/alpha';
4
+ import AndroidIcon from '@material-ui/icons/Android';
5
+ import { agentCatalogNavItem } from './nav.esm.js';
6
+
7
+ const agentFleetPage = PageBlueprint.make({
8
+ params: {
9
+ path: agentCatalogNavItem.path,
10
+ title: agentCatalogNavItem.title,
11
+ icon: /* @__PURE__ */ jsx(AndroidIcon, {}),
12
+ loader: () => import('./components/FleetPage.esm.js').then((m) => /* @__PURE__ */ jsx(m.FleetPage, {}))
13
+ }
14
+ });
15
+ const agentInfoCard = EntityCardBlueprint.make({
16
+ name: "agent-info",
17
+ params: {
18
+ filter: (entity) => entity.kind === "Component" && ["ai-agent", "ai-agent-team", "llm-workload"].includes(
19
+ entity.spec?.type ?? ""
20
+ ),
21
+ loader: () => import('./components/AgentInfoCard.esm.js').then((m) => /* @__PURE__ */ jsx(m.AgentInfoCard, {}))
22
+ }
23
+ });
24
+ var plugin = createFrontendPlugin({
25
+ pluginId: "agent-catalog",
26
+ extensions: [agentFleetPage, agentInfoCard]
27
+ });
28
+
29
+ export { plugin as default };
30
+ //# sourceMappingURL=plugin.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.esm.js","sources":["../src/plugin.tsx"],"sourcesContent":["/**\n * agent-catalog frontend plugin (new frontend system).\n *\n * Two extensions, deliberately thin (see the roadmap's frontend scope):\n * - /agents: the fleet page — every AI agent across all sources\n * - an \"Agent\" info card on ai-agent Component pages (traction + status)\n *\n * Discovered automatically via `app.packages: all`; the fleet page's\n * title/icon surface it in the sidebar through the app's nav module.\n * Classic/custom sidebars can import AgentCatalogSidebarItem.\n */\n\nimport { PageBlueprint, createFrontendPlugin } from '@backstage/frontend-plugin-api';\nimport { EntityCardBlueprint } from '@backstage/plugin-catalog-react/alpha';\nimport type { Entity } from '@backstage/catalog-model';\nimport AndroidIcon from '@material-ui/icons/Android';\nimport { agentCatalogNavItem } from './nav';\n\nconst agentFleetPage = PageBlueprint.make({\n params: {\n path: agentCatalogNavItem.path,\n title: agentCatalogNavItem.title,\n icon: <AndroidIcon />,\n loader: () =>\n import('./components/FleetPage').then(m => <m.FleetPage />),\n },\n});\n\nconst agentInfoCard = EntityCardBlueprint.make({\n name: 'agent-info',\n params: {\n filter: (entity: Entity) =>\n entity.kind === 'Component' &&\n ['ai-agent', 'ai-agent-team', 'llm-workload'].includes(\n (entity.spec as { type?: string })?.type ?? '',\n ),\n loader: () =>\n import('./components/AgentInfoCard').then(m => <m.AgentInfoCard />),\n },\n});\n\nexport default createFrontendPlugin({\n pluginId: 'agent-catalog',\n extensions: [agentFleetPage, agentInfoCard],\n});\n"],"names":[],"mappings":";;;;;;AAkBA,MAAM,cAAA,GAAiB,cAAc,IAAA,CAAK;AAAA,EACxC,MAAA,EAAQ;AAAA,IACN,MAAM,mBAAA,CAAoB,IAAA;AAAA,IAC1B,OAAO,mBAAA,CAAoB,KAAA;AAAA,IAC3B,IAAA,sBAAO,WAAA,EAAA,EAAY,CAAA;AAAA,IACnB,MAAA,EAAQ,MACN,OAAO,+BAAwB,CAAA,CAAE,IAAA,CAAK,CAAA,CAAA,qBAAK,GAAA,CAAC,CAAA,CAAE,SAAA,EAAF,EAAY,CAAE;AAAA;AAEhE,CAAC,CAAA;AAED,MAAM,aAAA,GAAgB,oBAAoB,IAAA,CAAK;AAAA,EAC7C,IAAA,EAAM,YAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,MAAA,EAAQ,CAAC,MAAA,KACP,MAAA,CAAO,IAAA,KAAS,eAChB,CAAC,UAAA,EAAY,eAAA,EAAiB,cAAc,CAAA,CAAE,QAAA;AAAA,MAC3C,MAAA,CAAO,MAA4B,IAAA,IAAQ;AAAA,KAC9C;AAAA,IACF,MAAA,EAAQ,MACN,OAAO,mCAA4B,CAAA,CAAE,IAAA,CAAK,CAAA,CAAA,qBAAK,GAAA,CAAC,CAAA,CAAE,aAAA,EAAF,EAAgB,CAAE;AAAA;AAExE,CAAC,CAAA;AAED,aAAe,oBAAA,CAAqB;AAAA,EAClC,QAAA,EAAU,eAAA;AAAA,EACV,UAAA,EAAY,CAAC,cAAA,EAAgB,aAAa;AAC5C,CAAC,CAAA;;;;"}
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@showcall/backstage-plugin-agent-catalog",
3
+ "version": "0.1.0",
4
+ "description": "Backstage frontend plugin: AI agent fleet view and per-agent traction/status cards",
5
+ "license": "Apache-2.0",
6
+ "homepage": "https://github.com/Showcall/agent-catalog",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/Showcall/agent-catalog.git",
10
+ "directory": "plugins/plugin-agent-catalog"
11
+ },
12
+ "bugs": "https://github.com/Showcall/agent-catalog/issues",
13
+ "keywords": [
14
+ "backstage",
15
+ "backstage-plugin",
16
+ "ai-agents",
17
+ "a2a",
18
+ "kagent",
19
+ "catalog"
20
+ ],
21
+ "main": "src/index.ts",
22
+ "types": "src/index.ts",
23
+ "publishConfig": {
24
+ "access": "public",
25
+ "main": "dist/index.esm.js",
26
+ "module": "dist/index.esm.js",
27
+ "types": "dist/index.d.ts"
28
+ },
29
+ "backstage": {
30
+ "role": "frontend-plugin",
31
+ "pluginId": "agent-catalog"
32
+ },
33
+ "sideEffects": false,
34
+ "scripts": {
35
+ "build": "backstage-cli package build",
36
+ "lint": "backstage-cli package lint",
37
+ "test": "backstage-cli package test"
38
+ },
39
+ "dependencies": {
40
+ "@backstage/catalog-model": "^1.9.0",
41
+ "@backstage/core-components": "^0.18.11",
42
+ "@backstage/core-plugin-api": "^1.12.7",
43
+ "@backstage/frontend-plugin-api": "^0.17.2",
44
+ "@backstage/plugin-catalog-react": "^3.1.0",
45
+ "@material-ui/core": "^4.12.4",
46
+ "@material-ui/icons": "^4.11.3"
47
+ },
48
+ "peerDependencies": {
49
+ "react": "^17.0.0 || ^18.0.0",
50
+ "react-dom": "^17.0.0 || ^18.0.0",
51
+ "react-router-dom": "6.0.0-beta.0 || ^6.3.0"
52
+ },
53
+ "devDependencies": {
54
+ "@backstage/cli": "^0.36.3",
55
+ "@types/react": "^18.3.0",
56
+ "@types/react-dom": "^18.3.0",
57
+ "react": "^18.3.1",
58
+ "react-dom": "^18.3.1",
59
+ "react-router-dom": "^6.3.0"
60
+ },
61
+ "files": [
62
+ "dist"
63
+ ]
64
+ }
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export { default } from './plugin';
2
+ export { AgentCatalogSidebarItem } from './components/AgentCatalogSidebarItem';
3
+ export { agentCatalogNavItem } from './nav';