From 4af132a81004806965785ca5a0d7fec966608c40 Mon Sep 17 00:00:00 2001 From: adilei Date: Tue, 18 Aug 2026 13:55:29 +0300 Subject: [PATCH 1/2] feat: add contributor profile pages Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4691871a-4784-47af-9913-91d3012b7b75 --- README.md | 2 +- src/components/SolutionCard.astro | 18 ++-- src/pages/contributors.astro | 6 +- src/pages/contributors/[contributor].astro | 105 +++++++++++++++++++++ src/pages/solutions/[slug].astro | 2 +- 5 files changed, 122 insertions(+), 11 deletions(-) create mode 100644 src/pages/contributors/[contributor].astro diff --git a/README.md b/README.md index f2c369d..e79532c 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ The site uses Astro, Tailwind CSS, React Flow, and static GitHub Pages deploymen connected-agent delegation. - Interactive workflow previews rendered from each export's saved designer graph. - Deterministic downloadable ZIP rebuilt from the submitted exploded solution. -- Contributor directory and JSON catalog endpoint. +- Contributor directory, individual contributor profiles, and JSON catalog endpoint. - Pull-request validation for metadata, solution structure, graph availability, unsafe filesystem entries, and generated output. diff --git a/src/components/SolutionCard.astro b/src/components/SolutionCard.astro index b8f9169..41bda57 100644 --- a/src/components/SolutionCard.astro +++ b/src/components/SolutionCard.astro @@ -20,10 +20,10 @@ const buildingBlocks = [ ]; --- - +
+ + View {data.name} +
@@ -53,11 +53,17 @@ const buildingBlocks = [ {isDemo && Demo}
- by {data.author} + + by {data.author} + {data.agentCount} agent{data.agentCount === 1 ? "" : "s"} {data.workflowCount} workflow{data.workflowCount === 1 ? "" : "s"}
- +
diff --git a/src/pages/contributors.astro b/src/pages/contributors.astro index e5921a9..adfe3bd 100644 --- a/src/pages/contributors.astro +++ b/src/pages/contributors.astro @@ -42,7 +42,7 @@ const MAX_SOLUTIONS = 8; data-search={`${contributor.name} ${contributor.github ?? ""} ${contributor.solutions.map((solution) => solution.data.name).join(" ")}`.toLowerCase()} >
- + {contributor.github ? @@ -50,10 +50,10 @@ const MAX_SOLUTIONS = 8; - + {contributor.count} solution{contributor.count === 1 ? "" : "s"} diff --git a/src/pages/contributors/[contributor].astro b/src/pages/contributors/[contributor].astro new file mode 100644 index 0000000..e3132bd --- /dev/null +++ b/src/pages/contributors/[contributor].astro @@ -0,0 +1,105 @@ +--- +import { getCollection } from "astro:content"; +import SolutionCard from "../../components/SolutionCard.astro"; +import Layout from "../../layouts/Layout.astro"; +import { collectContributors, collectTags } from "../../lib/catalog"; +import { withBase } from "../../lib/url"; + +export async function getStaticPaths() { + const contributors = collectContributors(await getCollection("solutions")); + return contributors.map((contributor) => ({ + params: { contributor: contributor.key }, + props: { contributor }, + })); +} + +const { contributor } = Astro.props; +const tags = collectTags(contributor.solutions); +const externalUrl = contributor.github + ? `https://github.com/${contributor.github}` + : contributor.url; +--- + + +
+ + All contributors + + +
+
+ + {contributor.github + ? + : contributor.name.slice(0, 2).toUpperCase()} + +
+

Contributor

+

{contributor.name}

+
+ {contributor.github && @{contributor.github}} + {externalUrl && ( + + View profile + + )} + {contributor.latest && Latest contribution {contributor.latest}} +
+
+ + Filter in gallery + +
+
+
+
Solutions
+
{contributor.count}
+
+
+
Agents
+
{contributor.agents}
+
+
+
Workflows
+
{contributor.workflows}
+
+
+
Editor’s picks
+
{contributor.featured}
+
+
+
+ +
+
+
+

Shared with the community

+

+ {contributor.count === 1 ? "Solution" : "Solutions"} +

+
+

{contributor.count} published solution{contributor.count === 1 ? "" : "s"}

+
+
+ {contributor.solutions.map((solution) => )} +
+
+ +
+

Topics

+
+ {tags.map(([tag, count]) => ( + + {tag} {count} + + ))} +
+
+
+
diff --git a/src/pages/solutions/[slug].astro b/src/pages/solutions/[slug].astro index 122ffa3..4e50e1a 100644 --- a/src/pages/solutions/[slug].astro +++ b/src/pages/solutions/[slug].astro @@ -40,7 +40,7 @@ const heroGraph = data.workflows[0]?.graph ?? data.agentGraph;

{data.name}

{data.description}

- by {data.author} + by {data.author} Version {data.version} {updated && Updated {updated}}
From dd8696e5ad5c38d49498bee8eee3d4354dfafcf0 Mon Sep 17 00:00:00 2001 From: adilei Date: Tue, 18 Aug 2026 15:00:01 +0300 Subject: [PATCH 2/2] feat: polish gallery discovery and graph previews Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4691871a-4784-47af-9913-91d3012b7b75 --- public/copilot-studio.svg | 75 +++++ scripts/import-submissions.test.ts | 18 ++ scripts/import-submissions.ts | 38 +-- src/components/SolutionCard.astro | 7 +- src/components/TopologyPreview.astro | 281 +++++++++++++++++- src/components/graph/GraphCanvas.css | 9 + src/components/graph/GraphCanvas.tsx | 86 +++++- .../solutions/blastbox-demo-agents.json | 40 +-- src/content/solutions/blastbox-deploy.json | 32 +- src/content/solutions/blastbox-omega.json | 36 +-- src/content/solutions/store-modern-agent.json | 16 +- src/layouts/Layout.astro | 6 +- src/lib/graphVisuals.ts | 20 ++ src/pages/contributors/[contributor].astro | 10 +- src/pages/index.astro | 4 +- src/pages/solutions/[slug].astro | 6 +- src/styles/global.css | 36 +-- 17 files changed, 575 insertions(+), 145 deletions(-) create mode 100644 public/copilot-studio.svg diff --git a/public/copilot-studio.svg b/public/copilot-studio.svg new file mode 100644 index 0000000..01d6824 --- /dev/null +++ b/public/copilot-studio.svg @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scripts/import-submissions.test.ts b/scripts/import-submissions.test.ts index 35cd9e7..694655d 100644 --- a/scripts/import-submissions.test.ts +++ b/scripts/import-submissions.test.ts @@ -3,6 +3,7 @@ import { cp, lstat, mkdir, rm, symlink, writeFile } from "node:fs/promises"; import { join } from "node:path"; import test from "node:test"; import AdmZip from "adm-zip"; +import { isMcpNode } from "../src/lib/graphVisuals"; import { SubmissionImportError, deriveSolutionFields, @@ -116,6 +117,23 @@ test("maps XML components and normalizes tools, skills, and delegation", () => { assert.deepEqual(normalized.edges.map((edge) => edge.label), ["uses", "includes"]); }); +test("distinguishes MCP servers from ordinary tools and connectors", () => { + assert.equal(isMcpNode({ + id: "tool:mcp", + name: "Warehouse MCP Server", + type: "tool", + position: { x: 0, y: 0 }, + details: { operation: "InvokeMCP" }, + }), true); + assert.equal(isMcpNode({ + id: "connector:email", + name: "Send email", + type: "connector", + position: { x: 0, y: 0 }, + details: { operation: "send" }, + }), false); +}); + test("centers primary agents and arranges capabilities around them", () => { const graph = layoutAgentGraph([ { id: "agent:primary", name: "Primary", type: "agent", position: { x: 0, y: 0 }, details: {} }, diff --git a/scripts/import-submissions.ts b/scripts/import-submissions.ts index bf38c94..c399b90 100644 --- a/scripts/import-submissions.ts +++ b/scripts/import-submissions.ts @@ -407,6 +407,20 @@ export function layoutAgentGraph(nodes: GraphNode[], edges: GraphEdge[]): GraphD x: center.x + Math.cos(angle) * radius, y: center.y + Math.sin(angle) * radius, }); + const pointInLane = ( + center: { x: number; y: number }, + outwardAngle: number, + distance: number, + gap: number, + index: number, + count: number, + ) => { + const lateralOffset = (index - (count - 1) / 2) * gap; + return { + x: center.x + Math.cos(outwardAngle) * distance - Math.sin(outwardAngle) * lateralOffset, + y: center.y + Math.sin(outwardAngle) * distance + Math.cos(outwardAngle) * lateralOffset, + }; + }; const placeAgent = ( agentId: string, @@ -420,39 +434,27 @@ export function layoutAgentGraph(nodes: GraphNode[], edges: GraphEdge[]): GraphD .filter((id) => nodeById.has(id) && !positions.has(id)); const components = children.filter((id) => !agentIds.has(id)); const connectedAgents = children.filter((id) => agentIds.has(id)); - const ringAngle = (id: string): number => { - const index = children.indexOf(id); - if (children.length === 1) return -Math.PI / 2; - if (children.length === 2) return Math.PI * index; - return -Math.PI / 2 + (Math.PI * 2 * index) / children.length; - }; components.forEach((id, index) => { - const angle = depth === 0 - ? ringAngle(id) - : outwardAngle - Math.PI / 3 + (Math.PI * 2 / 3) * ((index + 1) / (components.length + 1)); - const point = pointOnCircle(center, depth === 0 ? 220 : 170, angle); + const angle = depth === 0 ? Math.PI / 2 : outwardAngle; + const point = pointInLane(center, angle, depth === 0 ? 360 : 320, 340, index, components.length); positions.set(id, centerPosition(point.x, point.y)); }); connectedAgents.forEach((id, index) => { - const angle = depth === 0 - ? ringAngle(id) - : connectedAgents.length === 1 - ? outwardAngle - : outwardAngle - Math.PI / 3 + (Math.PI * 2 / 3) * ((index + 1) / (connectedAgents.length + 1)); - const point = pointOnCircle(center, depth === 0 ? 360 : 300, angle); + const angle = depth === 0 ? -Math.PI / 2 : outwardAngle; + const point = pointInLane(center, angle, depth === 0 ? 500 : 520, 560, index, connectedAgents.length); placeAgent(id, point, depth + 1, angle); }); }; roots.forEach((root, index) => { - const centerX = (index - (roots.length - 1) / 2) * 1_350; + const centerX = (index - (roots.length - 1) / 2) * 1_800; placeAgent(root.id, { x: centerX, y: 0 }, 0); }); agents.filter((agent) => !positions.has(agent.id)).forEach((agent, index) => { - placeAgent(agent.id, { x: index * 1_350, y: 1_100 }, 0); + placeAgent(agent.id, { x: index * 1_800, y: 1_200 }, 0); }); const unplaced = ordered.filter((node) => !positions.has(node.id)); diff --git a/src/components/SolutionCard.astro b/src/components/SolutionCard.astro index 41bda57..243be32 100644 --- a/src/components/SolutionCard.astro +++ b/src/components/SolutionCard.astro @@ -27,7 +27,12 @@ const buildingBlocks = [
- +
diff --git a/src/components/TopologyPreview.astro b/src/components/TopologyPreview.astro index 57f8164..d11c156 100644 --- a/src/components/TopologyPreview.astro +++ b/src/components/TopologyPreview.astro @@ -1,14 +1,15 @@ --- import type { GraphData } from "../lib/schema"; -import { graphVisualColor, graphVisualKind } from "../lib/graphVisuals"; +import { graphVisualColor, graphVisualKind, isMcpNode, MCP_ICON_PATHS } from "../lib/graphVisuals"; interface Props { graph?: GraphData; label?: string; compact?: boolean; + variant?: "workflow" | "agent"; } -const { graph, label = "Solution topology", compact = false } = Astro.props; +const { graph, label = "Solution topology", compact = false, variant = "workflow" } = Astro.props; const nodes = graph?.nodes.filter((node) => node.type !== "canvasNote").slice(0, compact ? 9 : 18) ?? []; const nodeIds = new Set(nodes.map((node) => node.id)); const edges = graph?.edges.filter((edge) => nodeIds.has(edge.source) && nodeIds.has(edge.target)) ?? []; @@ -23,8 +24,14 @@ const width = 540; const height = compact ? 116 : 210; const pad = compact ? 18 : 28; const gradientId = `topology-${label.toLowerCase().replace(/[^a-z0-9]+/g, "-")}-${compact ? "compact" : "full"}`; -const scaleX = (x: number) => pad + ((x - minX) / Math.max(maxX - minX, 1)) * (width - pad * 2); -const scaleY = (y: number) => pad + ((y - minY) / Math.max(maxY - minY, 1)) * (height - pad * 2); +const arrowId = `${gradientId}-arrow`; +const singleAgent = variant === "agent" && nodes.length === 1 && nodes[0].type === "agent" ? nodes[0] : undefined; +const sparklePath = (x: number, y: number, size: number) => + `M ${x} ${y - size} L ${x + size * 0.28} ${y - size * 0.28} L ${x + size} ${y} L ${x + size * 0.28} ${y + size * 0.28} L ${x} ${y + size} L ${x - size * 0.28} ${y + size * 0.28} L ${x - size} ${y} L ${x - size * 0.28} ${y - size * 0.28} Z`; +const scaleX = (x: number) => + maxX === minX ? width / 2 : pad + ((x - minX) / (maxX - minX)) * (width - pad * 2); +const scaleY = (y: number) => + maxY === minY ? height / 2 : pad + ((y - minY) / (maxY - minY)) * (height - pad * 2); const fallback = [ { x: 35, y: height / 2 }, { x: 145, y: height / 2 }, @@ -49,11 +56,14 @@ const fallback = [ + + + { nodes.length ? ( <> - {edges.map((edge) => { + {!singleAgent && edges.map((edge) => { const source = nodeById.get(edge.source); const target = nodeById.get(edge.target); if (!source || !target) return null; @@ -61,24 +71,278 @@ const fallback = [ const y1 = scaleY(source.position.y); const x2 = scaleX(target.position.x); const y2 = scaleY(target.position.y); - const bend = Math.max(24, Math.abs(x2 - x1) * 0.35); + const distance = Math.hypot(x2 - x1, y2 - y1) || 1; + const unitX = (x2 - x1) / distance; + const unitY = (y2 - y1) / distance; + const sourceInset = compact ? 11 : 15; + const targetInset = compact ? 16 : 21; + const startX = x1 + unitX * sourceInset; + const startY = y1 + unitY * sourceInset; + const endX = x2 - unitX * targetInset; + const endY = y2 - unitY * targetInset; const color = graphVisualColor(graphVisualKind(source)); + const path = variant === "agent" + ? `M ${startX} ${startY} L ${endX} ${endY}` + : `M ${startX} ${startY} C ${startX + Math.max(24, Math.abs(endX - startX) * 0.35)} ${startY}, ${endX - Math.max(24, Math.abs(endX - startX) * 0.35)} ${endY}, ${endX} ${endY}`; return ( ); })} - {nodes.map((node) => { + {singleAgent ? (() => { + const x = width / 2; + const y = height / 2 + (compact ? 4 : 6); + const color = graphVisualColor(graphVisualKind(singleAgent)); + const headWidth = compact ? 58 : 76; + const headHeight = compact ? 40 : 52; + const headTop = y - headHeight / 2; + const visorWidth = compact ? 34 : 44; + const visorHeight = compact ? 14 : 18; + return ( + + + + + + + + + + + + ); + })() : nodes.map((node) => { const x = scaleX(node.position.x); const y = scaleY(node.position.y); const kind = graphVisualKind(node); const color = graphVisualColor(kind); + if (node.type === "agent") { + const headWidth = compact ? 22 : 28; + const headHeight = compact ? 16 : 20; + const headTop = y - headHeight / 2 + 2; + const earWidth = compact ? 3 : 4; + const visorWidth = compact ? 13 : 17; + const visorHeight = compact ? 6 : 8; + const beaconSize = compact ? 3.5 : 4.5; + return ( + + + + + + + + + + + ); + } + if (isMcpNode(node)) { + const tileSize = compact ? 30 : 38; + const iconScale = compact ? 0.105 : 0.135; + return ( + + + + {MCP_ICON_PATHS.map((path) => ( + + ))} + + + ); + } + if (node.type === "tool" || node.type === "connector") { + const moduleWidth = compact ? 11 : 14; + const moduleHeight = compact ? 15 : 19; + const gap = compact ? 4 : 5; + return ( + + + + + + + ); + } + if (node.type === "skill") { + const size = compact ? 13 : 17; + return ( + + + + + ); + } const isTerminal = node.type === "start" || node.type === "end"; if (isTerminal) return ( ); })} diff --git a/src/components/graph/GraphCanvas.css b/src/components/graph/GraphCanvas.css index 18410e5..3007941 100644 --- a/src/components/graph/GraphCanvas.css +++ b/src/components/graph/GraphCanvas.css @@ -17,6 +17,7 @@ --xy-attribution-background-color: var(--cp-panel); --xy-handle-background-color: var(--cp-violet); --xy-handle-border-color: var(--cp-surface); + position: relative; width: 100%; height: 34rem; background: @@ -80,6 +81,8 @@ .catalog-node[data-visual="content"] { --node-color: var(--graph-content); } .catalog-node[data-visual="action"] { --node-color: var(--graph-action); } .catalog-node[data-visual="tool"] { --node-color: var(--graph-tool); } +.catalog-node[data-visual="mcp"] { --node-color: var(--graph-mcp); } +.catalog-node[data-visual="connector"] { --node-color: var(--graph-connector); } .catalog-node[data-visual="skill"] { --node-color: var(--graph-skill); } .catalog-node[data-visual="end"] { --node-color: var(--graph-end); } .catalog-node[data-visual="note"] { --node-color: var(--graph-note); } @@ -133,6 +136,12 @@ text-transform: uppercase; } +.catalog-node__icon svg { + width: 1.35rem; + height: 1.35rem; + overflow: visible; +} + .catalog-node__copy { min-width: 0; } diff --git a/src/components/graph/GraphCanvas.tsx b/src/components/graph/GraphCanvas.tsx index f9070d8..739cf79 100644 --- a/src/components/graph/GraphCanvas.tsx +++ b/src/components/graph/GraphCanvas.tsx @@ -12,7 +12,7 @@ import { type NodeProps, } from "@xyflow/react"; import { useEffect, useMemo, useRef, useState } from "react"; -import { graphVisualColor, graphVisualKind } from "../../lib/graphVisuals"; +import { graphVisualColor, graphVisualKind, isMcpNode, MCP_ICON_PATHS } from "../../lib/graphVisuals"; import type { GraphData, GraphNode } from "../../lib/schema"; import "./GraphCanvas.css"; @@ -22,14 +22,12 @@ type CatalogNodeData = { }; type CatalogNode = Node; +const WORKFLOW_LAYOUT_SCALE_X = 1.7; +const WORKFLOW_LAYOUT_SCALE_Y = 1.5; const ICONS: Record = { - agent: "AI", - tool: "TL", - skill: "SK", start: "IN", end: "OUT", - connector: "CN", ifElse: "IF", loop: "LP", variable: "VR", @@ -38,8 +36,52 @@ const ICONS: Record = { canvasNote: "NT", }; +function GraphNodeIcon({ source }: { source: GraphNode }) { + const { type } = source; + if (isMcpNode(source)) { + return ( + + ); + } + if (type === "agent" || type === "classifyOnInlineAgent") { + return ( + + ); + } + if (type === "tool" || type === "connector") { + return ( + + ); + } + if (type === "skill") { + return ( + + ); + } + return <>{ICONS[type] ?? type.slice(0, 2)}; +} + function CatalogNodeView({ data, selected }: NodeProps) { const source = data.source; + const typeLabel = isMcpNode(source) ? "MCP server" : humanize(source.type); return (
) {
- {humanize(source.type)} + {typeLabel} {source.name}
@@ -144,6 +186,21 @@ function Canvas({ return () => document.removeEventListener("keydown", onKey); }, []); + useEffect(() => { + const element = wrapper.current; + if (!element) return; + let hasFittedVisibleCanvas = false; + const observer = new ResizeObserver(([entry]) => { + const { width, height } = entry.contentRect; + if (!hasFittedVisibleCanvas && width > 0 && height > 0) { + hasFittedVisibleCanvas = true; + requestAnimationFrame(() => void fitView({ padding: 0.18, duration: 0 })); + } + }); + observer.observe(element); + return () => observer.disconnect(); + }, [fitView, graph]); + const hiddenIds = useMemo( () => new Set(showNotes ? [] : graph.nodes.filter((node) => node.type === "canvasNote").map((node) => node.id)), [graph.nodes, showNotes], @@ -165,14 +222,19 @@ function Canvas({ .map((node) => ({ id: node.id, type: "catalog", - position: node.position, + position: variant === "workflow" + ? { + x: node.position.x * WORKFLOW_LAYOUT_SCALE_X, + y: node.position.y * WORKFLOW_LAYOUT_SCALE_Y, + } + : node.position, data: { source: node, primary: primaryAgentIds.has(node.id) }, width: node.type === "start" || node.type === "end" ? 160 : 224, height: 72, draggable: false, selectable: !compact, })), - [compact, graph.nodes, hiddenIds, primaryAgentIds], + [compact, graph.nodes, hiddenIds, primaryAgentIds, variant], ); const graphNodeById = useMemo(() => new Map(graph.nodes.map((node) => [node.id, node])), [graph.nodes]); const edges = useMemo( @@ -185,7 +247,7 @@ function Canvas({ ? graphVisualColor(graphVisualKind(sourceNode)) : "var(--cp-border-strong)"; const targetNode = graphNodeById.get(edge.target); - const handles = variant === "agent" && sourceNode && targetNode + const handles = sourceNode && targetNode ? nearestHandles(sourceNode, targetNode) : {}; return { @@ -193,9 +255,9 @@ function Canvas({ source: edge.source, target: edge.target, label: edge.label ?? branchLabel(edge.sourceHandle), - type: variant === "agent" ? "straight" : "smoothstep", + type: "smoothstep", ...handles, - markerEnd: { type: MarkerType.ArrowClosed, color }, + markerEnd: { type: MarkerType.ArrowClosed, color, width: 18, height: 18 }, style: { strokeWidth: 1.8, stroke: color }, }; }), diff --git a/src/content/solutions/blastbox-demo-agents.json b/src/content/solutions/blastbox-demo-agents.json index cfc576a..d6edb95 100644 --- a/src/content/solutions/blastbox-demo-agents.json +++ b/src/content/solutions/blastbox-demo-agents.json @@ -72,8 +72,8 @@ "name": "Inventory & Fullfilment Agent", "type": "agent", "position": { - "x": 563, - "y": -396 + "x": 508, + "y": -536 }, "details": { "model": "Sonnet46", @@ -89,7 +89,7 @@ "name": "Returns & Service Assistant", "type": "agent", "position": { - "x": -787, + "x": -1012, "y": -36 }, "details": { @@ -106,7 +106,7 @@ "name": "Store Associate Assistant", "type": "agent", "position": { - "x": 563, + "x": 788, "y": -36 }, "details": { @@ -125,8 +125,8 @@ "name": "Store Policy Agent", "type": "agent", "position": { - "x": 905.3803458662553, - "y": -147.24611797498108 + "x": 1068, + "y": -536 }, "details": { "model": "Sonnet46", @@ -142,8 +142,8 @@ "name": "card-reissue", "type": "skill", "position": { - "x": -787, - "y": -256 + "x": -672, + "y": 324 }, "details": { "kind": "skill", @@ -156,8 +156,8 @@ "name": "membership-card-png", "type": "skill", "position": { - "x": -596.4744111674235, - "y": 73.99999999999996 + "x": -1012, + "y": 324 }, "details": { "kind": "skill", @@ -170,8 +170,8 @@ "name": "points-reconciliation", "type": "skill", "position": { - "x": 692.3127555043441, - "y": 141.98373876248843 + "x": 1128, + "y": 324 }, "details": { "kind": "skill", @@ -184,8 +184,8 @@ "name": "prorated-refund-calculator", "type": "skill", "position": { - "x": 433.68724449565593, - "y": 141.98373876248843 + "x": 788, + "y": 324 }, "details": { "kind": "skill", @@ -198,8 +198,8 @@ "name": "slip-pdf-generator", "type": "skill", "position": { - "x": 353.7675664150662, - "y": -103.9837387624884 + "x": 448, + "y": 324 }, "details": { "kind": "skill", @@ -212,8 +212,8 @@ "name": "Membership MCP v2 — Membership MCP v2 Server", "type": "tool", "position": { - "x": -977.5255888325764, - "y": 74.00000000000007 + "x": -1352, + "y": 324 }, "details": { "kind": "tool", @@ -227,8 +227,8 @@ "name": "Warehouse MCP — Warehouse MCP Server", "type": "tool", "position": { - "x": 563, - "y": -566 + "x": 508, + "y": -856 }, "details": { "kind": "tool", diff --git a/src/content/solutions/blastbox-deploy.json b/src/content/solutions/blastbox-deploy.json index ad84ce9..3f93586 100644 --- a/src/content/solutions/blastbox-deploy.json +++ b/src/content/solutions/blastbox-deploy.json @@ -72,8 +72,8 @@ "name": "Inventory & Fullfilment Agent", "type": "agent", "position": { - "x": 563, - "y": -396 + "x": 508, + "y": -536 }, "details": { "model": "Sonnet46", @@ -89,7 +89,7 @@ "name": "Returns & Service Assistant", "type": "agent", "position": { - "x": -787, + "x": -1012, "y": -36 }, "details": { @@ -106,7 +106,7 @@ "name": "Store Associate Assistant", "type": "agent", "position": { - "x": 563, + "x": 788, "y": -36 }, "details": { @@ -125,8 +125,8 @@ "name": "Store Policy Agent", "type": "agent", "position": { - "x": 905.3803458662553, - "y": -147.24611797498108 + "x": 1068, + "y": -536 }, "details": { "model": "Sonnet46", @@ -142,8 +142,8 @@ "name": "card-reissue", "type": "skill", "position": { - "x": -567, - "y": -36 + "x": -842, + "y": 324 }, "details": { "kind": "skill", @@ -156,8 +156,8 @@ "name": "membership-card-png", "type": "skill", "position": { - "x": -1007, - "y": -35.99999999999997 + "x": -1182, + "y": 324 }, "details": { "kind": "skill", @@ -170,8 +170,8 @@ "name": "points-reconciliation", "type": "skill", "position": { - "x": 692.3127555043441, - "y": 141.98373876248843 + "x": 1128, + "y": 324 }, "details": { "kind": "skill", @@ -184,8 +184,8 @@ "name": "prorated-refund-calculator", "type": "skill", "position": { - "x": 433.68724449565593, - "y": 141.98373876248843 + "x": 788, + "y": 324 }, "details": { "kind": "skill", @@ -198,8 +198,8 @@ "name": "slip-pdf-generator", "type": "skill", "position": { - "x": 353.7675664150662, - "y": -103.9837387624884 + "x": 448, + "y": 324 }, "details": { "kind": "skill", diff --git a/src/content/solutions/blastbox-omega.json b/src/content/solutions/blastbox-omega.json index 10cc204..0c49b5d 100644 --- a/src/content/solutions/blastbox-omega.json +++ b/src/content/solutions/blastbox-omega.json @@ -63,8 +63,8 @@ "name": "Inventory & Fullfilment Agent", "type": "agent", "position": { - "x": -111.99999999999997, - "y": -396 + "x": -391.99999999999994, + "y": -536 }, "details": { "model": "Sonnet46", @@ -99,8 +99,8 @@ "name": "Store Policy Agent", "type": "agent", "position": { - "x": 169.45933368849074, - "y": -260.45632866914406 + "x": 168.00000000000006, + "y": -536 }, "details": { "model": "Sonnet46", @@ -116,8 +116,8 @@ "name": "points-reconciliation", "type": "skill", "position": { - "x": 102.48414068000119, - "y": 12.954605470389168 + "x": 568, + "y": 323.99999999999994 }, "details": { "kind": "skill", @@ -130,8 +130,8 @@ "name": "prorated-refund-calculator", "type": "skill", "position": { - "x": -16.545577394137197, - "y": 162.2131509385322 + "x": 228, + "y": 324 }, "details": { "kind": "skill", @@ -144,8 +144,8 @@ "name": "slip-pdf-generator", "type": "skill", "position": { - "x": -207.45442260586276, - "y": 162.2131509385322 + "x": -111.99999999999997, + "y": 324 }, "details": { "kind": "skill", @@ -158,8 +158,8 @@ "name": "Membership MCP v2 — Membership MCP v2 Server", "type": "tool", "position": { - "x": -326.4841406800012, - "y": 12.95460547038919 + "x": -452, + "y": 324 }, "details": { "kind": "tool", @@ -173,8 +173,8 @@ "name": "Order Management MCP — Order Management MCP Server", "type": "tool", "position": { - "x": -284.00292614296654, - "y": -173.16775640892135 + "x": -792, + "y": 324.00000000000006 }, "details": { "kind": "tool", @@ -188,8 +188,8 @@ "name": "Policy RAG MCP v2 — Policy RAG MCP v2 Server", "type": "tool", "position": { - "x": 302.3706857080558, - "y": -366.4495949851288 + "x": 168.00000000000006, + "y": -856 }, "details": { "kind": "tool", @@ -203,8 +203,8 @@ "name": "Warehouse MCP — Warehouse MCP Server", "type": "tool", "position": { - "x": -111.99999999999993, - "y": -566 + "x": -391.99999999999994, + "y": -856 }, "details": { "kind": "tool", diff --git a/src/content/solutions/store-modern-agent.json b/src/content/solutions/store-modern-agent.json index b554ad8..e23ff9c 100644 --- a/src/content/solutions/store-modern-agent.json +++ b/src/content/solutions/store-modern-agent.json @@ -56,8 +56,8 @@ "name": "Inventory & Fullfilment Agent", "type": "agent", "position": { - "x": -111.99999999999997, - "y": -396 + "x": -391.99999999999994, + "y": -536 }, "details": { "model": "Sonnet46", @@ -88,8 +88,8 @@ "name": "Store Policy Agent", "type": "agent", "position": { - "x": 248, - "y": -36 + "x": 168.00000000000006, + "y": -536 }, "details": { "model": "Sonnet46", @@ -104,8 +104,8 @@ "name": "skill1", "type": "skill", "position": { - "x": -111.99999999999999, - "y": 184 + "x": 58.00000000000003, + "y": 324 }, "details": { "kind": "skill", @@ -118,8 +118,8 @@ "name": "skill2", "type": "skill", "position": { - "x": -332, - "y": -35.99999999999997 + "x": -282, + "y": 324 }, "details": { "kind": "skill", diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index f289e11..7bc5133 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -36,15 +36,13 @@ const fullTitle = - +
@@ -132,7 +132,7 @@ const featuredSolutions = solutions.filter((solution) => solution.data.featured)