@pipelex/mthds-ui 0.5.1 → 0.6.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/{chunk-DDAAVRWG.js → chunk-2NMEKWO5.js} +15 -2
- package/dist/chunk-IZ4FH2WM.js +1 -0
- package/dist/{chunk-OMJ6DRXM.js → chunk-NISDJYQJ.js} +283 -33
- package/dist/chunk-NISDJYQJ.js.map +1 -0
- package/dist/graph/index.d.ts +52 -4
- package/dist/graph/index.js +15 -3
- package/dist/graph/react/graph-core.css +60 -0
- package/dist/graph/react/index.css +12 -0
- package/dist/graph/react/index.css.map +1 -1
- package/dist/graph/react/index.d.ts +15 -3
- package/dist/graph/react/index.js +320 -35
- package/dist/graph/react/index.js.map +1 -1
- package/dist/graph/react/viewer/GraphToolbar.css +14 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +15 -3
- package/dist/shiki/index.js +1 -1
- package/dist/{types--1tl-afL.d.ts → types-C7rr1Egj.d.ts} +23 -3
- package/package.json +1 -1
- package/dist/chunk-IX35IG2I.js +0 -1
- package/dist/chunk-OMJ6DRXM.js.map +0 -1
- /package/dist/{chunk-DDAAVRWG.js.map → chunk-2NMEKWO5.js.map} +0 -0
- /package/dist/{chunk-IX35IG2I.js.map → chunk-IZ4FH2WM.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/graph/react/index.ts","../../../src/graph/react/viewer/GraphViewer.tsx","../../../src/graph/react/stuff/stuffViewerUtils.ts","../../../src/graph/react/stuff/StuffViewer.tsx","../../../src/graph/react/detail/DetailPanel.tsx","../../../src/graph/react/detail/useResizable.ts","../../../src/graph/react/detail/PipeDetailPanel.tsx","../../../src/graph/react/detail/sections/shared.tsx","../../../src/graph/react/detail/sections/PipeLLMDetail.tsx","../../../src/graph/react/detail/sections/PipeImgGenDetail.tsx","../../../src/graph/react/detail/sections/PipeExtractDetail.tsx","../../../src/graph/react/detail/sections/PipeSearchDetail.tsx","../../../src/graph/react/detail/sections/PipeComposeDetail.tsx","../../../src/graph/react/detail/sections/PipeConditionDetail.tsx","../../../src/graph/react/detail/sections/PipeSequenceDetail.tsx","../../../src/graph/react/detail/sections/PipeParallelDetail.tsx","../../../src/graph/react/detail/sections/PipeBatchDetail.tsx","../../../src/graph/react/detail/ConceptDetailPanel.tsx","../../../src/graph/react/rfTypes.ts","../../../src/graph/react/viewer/renderLabel.tsx","../../../src/graph/react/viewer/GraphToolbar.tsx","../../../src/graph/react/nodes/controller/ControllerGroupNode.tsx","../../../src/graph/react/nodes/pipe/PipeCardNode.tsx","../../../src/graph/react/nodes/pipe/PipeCardBase.tsx","../../../src/graph/react/nodes/pipe/pipeCardRegistry.ts"],"sourcesContent":["\"use client\";\n\nimport \"./graph-core.css\";\nimport \"./detail/DetailPanel.css\";\nimport \"./stuff/StuffViewer.css\";\nimport \"./viewer/GraphToolbar.css\";\n\n// Viewer\nexport { GraphViewer, applyStatusOverrides } from \"./viewer/GraphViewer\";\nexport type { GraphViewerProps } from \"./viewer/GraphViewer\";\nexport { renderLabel, hydrateLabels } from \"./viewer/renderLabel\";\n\n// ReactFlow type bridge\nexport type { AppNode, AppEdge, AppRFInstance } from \"./rfTypes\";\nexport { toAppNodes, toAppEdges } from \"./rfTypes\";\n\n// Node types\nexport { ControllerGroupNode, controllerNodeTypes } from \"./nodes/controller/ControllerGroupNode\";\nexport { PipeCardNode } from \"./nodes/pipe/PipeCardNode\";\nexport { PipeCardBase } from \"./nodes/pipe/PipeCardBase\";\nexport type { PipeCardBaseProps } from \"./nodes/pipe/PipeCardBase\";\nexport type { PipeCardData, PipeOperatorType, PipeStatus } from \"./nodes/pipe/pipeCardTypes\";\n\n// Stuff viewer\nexport * from \"./stuff\";\n\n// Detail panel\nexport * from \"./detail\";\n","import React from \"react\";\nimport {\n ReactFlow,\n useNodesState,\n useEdgesState,\n Background,\n BackgroundVariant,\n} from \"@xyflow/react\";\n\nimport type {\n GraphSpec,\n GraphConfig,\n GraphDirection,\n GraphNode,\n GraphEdge,\n GraphNodeData,\n DataflowAnalysis,\n PipeStatus,\n ConceptInfo,\n} from \"@graph/types\";\nimport { stuffDigestFromId, EDGE_TYPE, GRAPH_DIRECTION } from \"@graph/types\";\nimport { resolveConceptRef } from \"@graph/graphAnalysis\";\nimport type { ResolveStorageUrl, StuffViewerData } from \"../stuff/stuffViewerTypes\";\nimport { findStuffDataByDigest } from \"../stuff/stuffViewerUtils\";\nimport { StuffViewer } from \"../stuff/StuffViewer\";\nimport { DetailPanel } from \"../detail/DetailPanel\";\nimport { useResizable } from \"../detail/useResizable\";\nimport { PipeDetailPanel } from \"../detail/PipeDetailPanel\";\nimport { ConceptDetailPanel } from \"../detail/ConceptDetailPanel\";\nimport type { AppNode, AppEdge, AppRFInstance } from \"../rfTypes\";\nimport { toAppNodes, toAppEdges } from \"../rfTypes\";\nimport { buildGraph } from \"@graph/graphBuilders\";\nimport { getLayoutedElements } from \"@graph/graphLayout\";\nimport { applyControllers } from \"@graph/graphControllers\";\nimport { DEFAULT_GRAPH_CONFIG } from \"@graph/graphConfig\";\nimport { hydrateLabels } from \"./renderLabel\";\nimport { GraphToolbar } from \"./GraphToolbar\";\nimport { controllerNodeTypes } from \"../nodes/controller/ControllerGroupNode\";\nimport { PipeCardRFNode } from \"../nodes/pipe/PipeCardNode\";\n\n// Stable reference — must be declared outside the component to avoid ReactFlow re-mounts\nconst nodeTypes = {\n ...controllerNodeTypes,\n pipeCard: PipeCardRFNode,\n};\n\nexport interface GraphViewerProps {\n graphspec: GraphSpec | null;\n config?: GraphConfig;\n /** Initial layout direction. Users can toggle this via the built-in toolbar. */\n initialDirection?: GraphDirection;\n /** Initial controller-grouping state. Users can toggle this via the built-in toolbar. */\n initialShowControllers?: boolean;\n /** Hide the built-in floating toolbar (direction + controllers toggle). */\n hideToolbar?: boolean;\n onNavigateToPipe?: (pipeCode: string, status?: PipeStatus) => void;\n onStuffNodeClick?: (stuffData: StuffViewerData) => void;\n onReactFlowInit?: (instance: AppRFInstance) => void;\n /** Layer 2 execution state: pipe_code → current status. Updates node status dots in real-time. */\n statusMap?: Record<string, PipeStatus>;\n /** Called when any node is clicked with full node data. Use for detail/inspector panels. */\n onNodeSelect?: (nodeId: string, nodeData: GraphNodeData, event: React.MouseEvent) => void;\n /** Called when the graph background (pane) is clicked. Use to dismiss detail panels. */\n onPaneClick?: () => void;\n /** Render extra content below the built-in detail panel content for the selected node. */\n renderDetailExtra?: (nodeId: string, nodeData: GraphNodeData) => React.ReactNode;\n /**\n * Resolver for `pipelex-storage://` URIs. Passed down to StuffViewer so it can\n * exchange internal URIs for browser-fetchable presigned URLs when rendering media.\n */\n resolveStorageUrl?: ResolveStorageUrl;\n /**\n * Set to `false` when the host cannot render `<embed type=\"application/pdf\">`\n * — e.g. VS Code webviews, which run inside Electron without the Chromium\n * PDFium plugin. Forwarded to StuffViewer.\n *\n * Default: `true`.\n */\n canEmbedPdf?: boolean;\n /**\n * Replaces the default `window.open(url, \"_blank\")` behavior used by the\n * StuffViewer toolbar and the PDF fallback tile. Wire this to your host's\n * external-open mechanism (e.g. `vscode.env.openExternal` via postMessage).\n */\n onOpenExternally?: (url: string, filename?: string) => void;\n}\n\n/** Stuff node detail: concept structure + data viewer. */\nfunction StuffNodeDetail({\n stuffData,\n graphspec,\n resolveStorageUrl,\n canEmbedPdf,\n onOpenExternally,\n}: {\n stuffData: StuffViewerData;\n graphspec: GraphSpec | null;\n resolveStorageUrl?: ResolveStorageUrl;\n canEmbedPdf?: boolean;\n onOpenExternally?: (url: string, filename?: string) => void;\n}) {\n const conceptInfo =\n stuffData.concept && graphspec ? resolveConceptRef(graphspec, stuffData.concept) : undefined;\n\n return (\n <>\n {/* Concept structure (header + schema table) */}\n {conceptInfo ? (\n <ConceptDetailPanel\n concept={conceptInfo}\n ioData={stuffData}\n resolveStorageUrl={resolveStorageUrl}\n canEmbedPdf={canEmbedPdf}\n onOpenExternally={onOpenExternally}\n />\n ) : (\n /* Fallback: just show the StuffViewer if no concept info */\n <StuffViewer\n stuff={stuffData}\n resolveStorageUrl={resolveStorageUrl}\n canEmbedPdf={canEmbedPdf}\n onOpenExternally={onOpenExternally}\n />\n )}\n </>\n );\n}\n\nfunction cloneCachedNodes(nodes: GraphNode[]): GraphNode[] {\n return nodes.map((n) => ({\n ...n,\n position: { ...n.position },\n data: { ...n.data },\n style: n.style ? { ...n.style } : undefined,\n }));\n}\n\n/** Apply Layer 2 execution state overrides to rendered nodes. */\nexport function applyStatusOverrides(\n nodes: AppNode[],\n statusMap: Record<string, PipeStatus> | undefined,\n): AppNode[] {\n if (!statusMap || Object.keys(statusMap).length === 0) return nodes;\n return nodes.map((node) => {\n const pipeCode = node.data.pipeCode;\n if (!pipeCode || !Object.hasOwn(statusMap, pipeCode)) return node;\n const newStatus = statusMap[pipeCode];\n if (node.data.pipeCardData?.status === newStatus) return node;\n return {\n ...node,\n data: {\n ...node.data,\n nodeData: node.data.nodeData\n ? { ...node.data.nodeData, status: newStatus }\n : node.data.nodeData,\n pipeCardData: node.data.pipeCardData\n ? { ...node.data.pipeCardData, status: newStatus }\n : node.data.pipeCardData,\n },\n };\n });\n}\n\n// ─── Detail panel selection state ──────────────────────────────────────\n\ninterface DetailSelection {\n kind: \"pipe\" | \"stuff\" | \"concept\";\n nodeId: string;\n nodeData: GraphNodeData;\n conceptInfo?: ConceptInfo;\n stuffData?: StuffViewerData;\n}\n\nexport function GraphViewer(props: GraphViewerProps) {\n const {\n graphspec,\n config = DEFAULT_GRAPH_CONFIG,\n initialDirection,\n initialShowControllers,\n hideToolbar = false,\n onNavigateToPipe,\n onStuffNodeClick,\n onReactFlowInit,\n statusMap,\n onNodeSelect,\n onPaneClick,\n renderDetailExtra,\n resolveStorageUrl,\n canEmbedPdf,\n onOpenExternally,\n } = props;\n\n const [direction, setDirection] = React.useState<GraphDirection>(\n () =>\n initialDirection ?? config.direction ?? DEFAULT_GRAPH_CONFIG.direction ?? GRAPH_DIRECTION.TB,\n );\n const [showControllers, setShowControllers] = React.useState<boolean>(\n () =>\n initialShowControllers ??\n config.showControllers ??\n DEFAULT_GRAPH_CONFIG.showControllers ??\n false,\n );\n\n const containerRef = React.useRef<HTMLDivElement>(null);\n\n // Detail panel state (built-in)\n const [detailSelection, setDetailSelection] = React.useState<DetailSelection | null>(null);\n const [conceptOverride, setConceptOverride] = React.useState<ConceptInfo | null>(null);\n\n // Panel resize\n const {\n width: panelWidth,\n isDragging: isPanelDragging,\n handleMouseDown: onResizeMouseDown,\n } = useResizable({ defaultWidth: 380, minWidth: 280, maxWidth: 800, containerRef });\n\n // Reset detail panel when graphspec changes\n React.useEffect(() => {\n setDetailSelection(null);\n setConceptOverride(null);\n }, [graphspec]);\n\n // Apply palette CSS vars to the container (scoped, auto-cleaned on unmount)\n React.useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n const palette = config.paletteColors ?? DEFAULT_GRAPH_CONFIG.paletteColors;\n if (!palette) return;\n\n for (const [cssVar, value] of Object.entries(palette)) {\n el.style.setProperty(cssVar, value);\n }\n\n return () => {\n for (const cssVar of Object.keys(palette)) {\n el.style.removeProperty(cssVar);\n }\n };\n }, [config.paletteColors]);\n\n const [nodes, setNodes, onNodesChange] = useNodesState<AppNode>([]);\n const [edges, setEdges, onEdgesChange] = useEdgesState<AppEdge>([]);\n const reactFlowRef = React.useRef<AppRFInstance | null>(null);\n const initialDataRef = React.useRef<{\n nodes: GraphNode[];\n edges: GraphEdge[];\n _analysis: DataflowAnalysis | null;\n _graphspec: GraphSpec | null;\n } | null>(null);\n const layoutCacheRef = React.useRef<{\n nodes: GraphNode[];\n edges: GraphEdge[];\n controllerPositions?: Record<string, { x: number; y: number; width: number; height: number }>;\n } | null>(null);\n\n // Collapse state: tracks which controllers the user explicitly expanded.\n // Parallel/Batch with >5 children are collapsed by default.\n const [expandedControllers, setExpandedControllers] = React.useState<Set<string>>(new Set());\n\n const toggleCollapse = React.useCallback((controllerId: string) => {\n setExpandedControllers((prev) => {\n const next = new Set(prev);\n if (next.has(controllerId)) next.delete(controllerId);\n else next.add(controllerId);\n return next;\n });\n }, []);\n\n const edgeType = config.edgeType || EDGE_TYPE.DEFAULT;\n const layoutConfig = React.useMemo(\n () => ({ nodesep: config.nodesep, ranksep: config.ranksep }),\n [config.nodesep, config.ranksep],\n );\n\n const showControllersRef = React.useRef(showControllers);\n showControllersRef.current = showControllers;\n const directionRef = React.useRef(direction);\n directionRef.current = direction;\n const layoutConfigRef = React.useRef(layoutConfig);\n layoutConfigRef.current = layoutConfig;\n const initialZoomRef = React.useRef(config.initialZoom);\n initialZoomRef.current = config.initialZoom;\n const panToTopRef = React.useRef(config.panToTop);\n panToTopRef.current = config.panToTop;\n const expandedRef = React.useRef(expandedControllers);\n expandedRef.current = expandedControllers;\n const toggleCollapseRef = React.useRef(toggleCollapse);\n toggleCollapseRef.current = toggleCollapse;\n const statusMapRef = React.useRef(statusMap);\n statusMapRef.current = statusMap;\n\n // Re-layout when direction or layout config changes\n React.useEffect(() => {\n if (!initialDataRef.current) return;\n let cancelled = false;\n\n (async () => {\n try {\n const data = initialDataRef.current;\n if (!data) return;\n const relayouted = await getLayoutedElements(\n data.nodes,\n data.edges,\n direction,\n layoutConfig,\n data._graphspec,\n data._analysis,\n );\n if (cancelled) return;\n layoutCacheRef.current = {\n nodes: relayouted.nodes,\n edges: relayouted.edges,\n controllerPositions: relayouted.controllerPositions,\n };\n const withControllers = applyControllers(\n cloneCachedNodes(relayouted.nodes),\n relayouted.edges,\n data._graphspec,\n data._analysis,\n showControllersRef.current,\n expandedRef.current,\n toggleCollapseRef.current,\n relayouted.controllerPositions,\n );\n setNodes(\n applyStatusOverrides(\n toAppNodes(hydrateLabels(withControllers.nodes)),\n statusMapRef.current,\n ),\n );\n setEdges(toAppEdges(withControllers.edges));\n setTimeout(() => {\n if (!cancelled && reactFlowRef.current) {\n reactFlowRef.current.fitView({ padding: 0.1 });\n }\n }, 50);\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error(\"[GraphViewer] ELK layout failed:\", err);\n }\n })();\n\n return () => {\n cancelled = true;\n };\n }, [direction, layoutConfig]);\n\n // Rebuild controllers when showControllers or collapse state changes (reuses cached layout)\n React.useEffect(() => {\n if (!layoutCacheRef.current || !initialDataRef.current) return;\n const cachedNodes = cloneCachedNodes(layoutCacheRef.current.nodes);\n const cachedEdges = layoutCacheRef.current.edges;\n const withControllers = applyControllers(\n cachedNodes,\n cachedEdges,\n initialDataRef.current._graphspec,\n initialDataRef.current._analysis,\n showControllers,\n expandedControllers,\n toggleCollapse,\n layoutCacheRef.current.controllerPositions,\n );\n setNodes(\n applyStatusOverrides(toAppNodes(hydrateLabels(withControllers.nodes)), statusMapRef.current),\n );\n setEdges(toAppEdges(withControllers.edges));\n }, [showControllers, expandedControllers, toggleCollapse]);\n\n // Build + layout when graphspec/edgeType changes\n React.useEffect(() => {\n if (!graphspec) {\n initialDataRef.current = null;\n layoutCacheRef.current = null;\n setNodes([]);\n setEdges([]);\n return;\n }\n\n let cancelled = false;\n\n // Reset expand overrides when graph changes\n setExpandedControllers(new Set());\n\n const { graphData, analysis } = buildGraph(graphspec, edgeType);\n initialDataRef.current = {\n nodes: graphData.nodes,\n edges: graphData.edges,\n _analysis: analysis,\n _graphspec: graphspec,\n };\n\n (async () => {\n try {\n const currentDirection = directionRef.current;\n const currentLayoutConfig = layoutConfigRef.current;\n const needsLayout = graphData.nodes.some(\n (n) => !n.position || (n.position.x === 0 && n.position.y === 0),\n );\n const layouted = needsLayout\n ? await getLayoutedElements(\n graphData.nodes,\n graphData.edges,\n currentDirection,\n currentLayoutConfig,\n graphspec,\n analysis,\n )\n : {\n ...graphData,\n controllerPositions: {} as Record<\n string,\n { x: number; y: number; width: number; height: number }\n >,\n };\n if (cancelled) return;\n layoutCacheRef.current = {\n nodes: layouted.nodes,\n edges: layouted.edges,\n controllerPositions: layouted.controllerPositions,\n };\n const withControllers = applyControllers(\n cloneCachedNodes(layouted.nodes),\n layouted.edges,\n graphspec,\n analysis,\n showControllersRef.current,\n expandedRef.current,\n toggleCollapseRef.current,\n layouted.controllerPositions,\n );\n\n setNodes(\n applyStatusOverrides(\n toAppNodes(hydrateLabels(withControllers.nodes)),\n statusMapRef.current,\n ),\n );\n setEdges(toAppEdges(withControllers.edges));\n\n // Fit view after render, then apply zoom/pan overrides\n setTimeout(() => {\n if (!cancelled && reactFlowRef.current) {\n reactFlowRef.current.fitView({ padding: 0.1 });\n if (initialZoomRef.current !== undefined && initialZoomRef.current !== null) {\n reactFlowRef.current.zoomTo(initialZoomRef.current);\n }\n if (panToTopRef.current) {\n const vp = reactFlowRef.current.getViewport();\n reactFlowRef.current.setViewport({ x: vp.x, y: 20, zoom: vp.zoom });\n }\n }\n }, 100);\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error(\"[GraphViewer] ELK layout failed:\", err);\n }\n })();\n\n return () => {\n cancelled = true;\n };\n }, [graphspec, edgeType]);\n\n // Apply Layer 2 execution state when statusMap changes (reuses cached layout).\n // On mount, statusMap is applied inline by the graphspec build effect above.\n // This effect handles runtime changes only (SSE updates arriving after initial render).\n React.useEffect(() => {\n if (!layoutCacheRef.current || !initialDataRef.current) return;\n const cachedNodes = cloneCachedNodes(layoutCacheRef.current.nodes);\n const cachedEdges = layoutCacheRef.current.edges;\n const withControllers = applyControllers(\n cachedNodes,\n cachedEdges,\n initialDataRef.current._graphspec,\n initialDataRef.current._analysis,\n showControllersRef.current,\n expandedRef.current,\n toggleCollapseRef.current,\n layoutCacheRef.current.controllerPositions,\n );\n setNodes(applyStatusOverrides(toAppNodes(hydrateLabels(withControllers.nodes)), statusMap));\n setEdges(toAppEdges(withControllers.edges));\n }, [statusMap]);\n\n // Handle node click — opens detail panel + fires external callbacks\n const onNodeClick = React.useCallback(\n (event: React.MouseEvent, node: AppNode) => {\n const nodeData = node.data;\n\n // Fire external callbacks\n onNodeSelect?.(node.id, nodeData, event);\n if (nodeData.isController || nodeData.isPipe) {\n const code = nodeData.pipeCode || nodeData.labelText;\n if (code && onNavigateToPipe) {\n onNavigateToPipe(code, nodeData.pipeCardData?.status as PipeStatus | undefined);\n }\n } else if (nodeData.isStuff && onStuffNodeClick && graphspec) {\n const digest = stuffDigestFromId(node.id);\n const sd = findStuffDataByDigest(graphspec, digest);\n if (sd) onStuffNodeClick(sd);\n }\n\n // Update detail panel (toggle off if same node clicked again)\n setConceptOverride(null);\n if (detailSelection?.nodeId === node.id && !conceptOverride) {\n setDetailSelection(null);\n } else if (nodeData.isPipe || nodeData.isController) {\n setDetailSelection({ kind: \"pipe\", nodeId: node.id, nodeData });\n } else if (nodeData.isStuff && graphspec) {\n const digest = stuffDigestFromId(node.id);\n const sd = findStuffDataByDigest(graphspec, digest);\n setDetailSelection({\n kind: \"stuff\",\n nodeId: node.id,\n nodeData,\n stuffData: sd ?? undefined,\n });\n }\n\n setNodes((nds) => nds.map((n) => ({ ...n, selected: n.id === node.id })));\n },\n [\n setNodes,\n onNavigateToPipe,\n onNodeSelect,\n onStuffNodeClick,\n graphspec,\n detailSelection,\n conceptOverride,\n ],\n );\n\n const onInit = React.useCallback(\n (reactFlowInstance: AppRFInstance) => {\n reactFlowRef.current = reactFlowInstance;\n if (onReactFlowInit) {\n onReactFlowInit(reactFlowInstance);\n }\n },\n [onReactFlowInit],\n );\n\n // Dismiss detail panel on pane click\n const handlePaneClick = React.useCallback(() => {\n setDetailSelection(null);\n setConceptOverride(null);\n onPaneClick?.();\n }, [onPaneClick]);\n\n // Navigate from pipe IO concept → concept detail\n const handleConceptClick = React.useCallback(\n (conceptCode: string) => {\n if (!graphspec) return;\n const info = resolveConceptRef(graphspec, conceptCode);\n if (info) setConceptOverride(info);\n },\n [graphspec],\n );\n\n // Resolve the selected pipe's GraphSpecNode for the detail panel\n const selectedSpecNode =\n detailSelection?.kind === \"pipe\" && graphspec\n ? graphspec.nodes.find((n) => n.pipe_code === detailSelection.nodeData.pipeCode)\n : undefined;\n\n const detailOpen = detailSelection !== null || conceptOverride !== null;\n\n return (\n <div ref={containerRef} className=\"react-flow-container\">\n <ReactFlow\n nodes={nodes}\n edges={edges}\n nodeTypes={nodeTypes}\n onNodesChange={onNodesChange}\n onEdgesChange={onEdgesChange}\n onNodeClick={onNodeClick}\n onPaneClick={handlePaneClick}\n onInit={onInit}\n fitView\n fitViewOptions={{ padding: 0.1 }}\n defaultEdgeOptions={{ type: edgeType }}\n panOnScroll\n minZoom={0.1}\n proOptions={{ hideAttribution: true }}\n >\n <Background\n variant={BackgroundVariant.Dots}\n gap={20}\n size={1}\n color=\"var(--color-bg-dots)\"\n />\n </ReactFlow>\n <DetailPanel\n isOpen={detailOpen}\n onClose={handlePaneClick}\n width={panelWidth}\n isDragging={isPanelDragging}\n onResizeHandleMouseDown={onResizeMouseDown}\n >\n {conceptOverride ? (\n <ConceptDetailPanel concept={conceptOverride} />\n ) : selectedSpecNode && graphspec ? (\n <PipeDetailPanel\n node={selectedSpecNode}\n spec={graphspec}\n onConceptClick={handleConceptClick}\n />\n ) : detailSelection?.stuffData ? (\n <StuffNodeDetail\n stuffData={detailSelection.stuffData}\n graphspec={graphspec}\n resolveStorageUrl={resolveStorageUrl}\n canEmbedPdf={canEmbedPdf}\n onOpenExternally={onOpenExternally}\n />\n ) : null}\n {renderDetailExtra &&\n detailSelection &&\n !conceptOverride &&\n renderDetailExtra(detailSelection.nodeId, detailSelection.nodeData)}\n </DetailPanel>\n {!hideToolbar && (\n <GraphToolbar\n direction={direction}\n onDirectionChange={setDirection}\n showControllers={showControllers}\n onShowControllersChange={setShowControllers}\n onZoomIn={() => reactFlowRef.current?.zoomIn()}\n onZoomOut={() => reactFlowRef.current?.zoomOut()}\n onFitView={() => reactFlowRef.current?.fitView({ padding: 0.1 })}\n rightOffset={detailOpen ? panelWidth : 0}\n />\n )}\n </div>\n );\n}\n","import type { GraphSpec } from \"@graph/types\";\nimport type { StuffViewerData } from \"./stuffViewerTypes\";\n\n/** Check whether a URL is safe for links/downloads (no javascript: or data: injection). */\nexport function isSafeDisplayUrl(url: unknown): url is string {\n if (!url || typeof url !== \"string\") return false;\n return (\n url.startsWith(\"https://\") ||\n url.startsWith(\"http://\") ||\n url.startsWith(\"file://\") ||\n url.startsWith(\"/\")\n );\n}\n\n/** Check whether a URL can be rendered inline in an <img> or <embed> tag.\n * Allows http://, https://, file:// (local dev / Electron), and relative paths. */\nexport function isInlineRenderableUrl(url: unknown): url is string {\n if (!url || typeof url !== \"string\") return false;\n return (\n url.startsWith(\"https://\") ||\n url.startsWith(\"http://\") ||\n url.startsWith(\"file://\") ||\n url.startsWith(\"/\")\n );\n}\n\n/**\n * Extract a displayable URL from stuff data (for links, downloads, open-external).\n * Prefers public_url (pre-signed S3 / file:// URI) over internal pipelex-storage:// URLs.\n * Returns null for unsafe or missing URLs.\n */\nexport function extractUrl(data: unknown): string | null {\n if (!data) return null;\n if (typeof data === \"string\") {\n return isSafeDisplayUrl(data) ? data : null;\n }\n if (typeof data !== \"object\") return null;\n const obj = data as Record<string, unknown>;\n const candidates = [obj.public_url, obj.src, obj.href, obj.uri, obj.url];\n for (const candidate of candidates) {\n if (isSafeDisplayUrl(candidate)) return candidate;\n }\n return null;\n}\n\n/**\n * Extract a URL that can be rendered inline in <img>/<embed> tags.\n * Returns http/https, file://, and relative URLs.\n * Internal schemes like pipelex-storage:// are excluded.\n */\nexport function extractInlineUrl(data: unknown): string | null {\n if (!data) return null;\n if (typeof data === \"string\") {\n return isInlineRenderableUrl(data) ? data : null;\n }\n if (typeof data !== \"object\") return null;\n const obj = data as Record<string, unknown>;\n const candidates = [obj.public_url, obj.src, obj.href, obj.uri, obj.url];\n for (const candidate of candidates) {\n if (isInlineRenderableUrl(candidate)) return candidate;\n }\n return null;\n}\n\n/**\n * Extract a `pipelex-storage://` URI from stuff data, if present.\n *\n * Pipelex-storage URIs are internal logical pointers that need to be resolved\n * to a browser-fetchable URL (e.g. presigned S3) before rendering inline.\n */\nexport function extractStorageUri(data: unknown): string | null {\n if (!data) return null;\n if (typeof data === \"string\") {\n return data.startsWith(\"pipelex-storage://\") ? data : null;\n }\n if (typeof data !== \"object\") return null;\n const obj = data as Record<string, unknown>;\n const candidates = [obj.uri, obj.url, obj.src, obj.href];\n for (const candidate of candidates) {\n if (typeof candidate === \"string\" && candidate.startsWith(\"pipelex-storage://\")) {\n return candidate;\n }\n }\n return null;\n}\n\n/** Extract the filename from stuff data, if available. */\nexport function extractFilename(data: unknown): string | null {\n if (!data || typeof data !== \"object\") return null;\n const obj = data as Record<string, unknown>;\n if (typeof obj.filename === \"string\" && obj.filename) return obj.filename;\n return null;\n}\n\n/**\n * Determine the effective MIME type of a stuff item for preview rendering.\n *\n * Checks (in order):\n * 1. Stuff-level `contentType` (when it's already a MIME type like \"application/pdf\")\n * 2. The `mime_type` field on the data object (Document content carries this)\n * 3. The file extension from `filename` or from the URL/URI\n *\n * The concept-level `contentType` (e.g. \"document\") is not a MIME type; we\n * ignore it and look at the data instead. Returns null when nothing recognizable\n * is found.\n */\nexport function resolveMimeType(\n data: unknown,\n contentType: string | undefined,\n url: string | null,\n): string | null {\n // 1. Already a MIME type\n if (contentType && contentType.includes(\"/\")) return contentType;\n\n // 2. data.mime_type field\n if (data && typeof data === \"object\") {\n const obj = data as Record<string, unknown>;\n if (typeof obj.mime_type === \"string\" && obj.mime_type) return obj.mime_type;\n }\n\n // 3. Guess from extension\n const source = extractFilename(data) || url || (typeof data === \"string\" ? data : null);\n if (source) {\n const match = source.match(/\\.([a-zA-Z0-9]+)(?:\\?|#|$)/);\n const ext = match?.[1]?.toLowerCase();\n if (ext) {\n if (ext === \"pdf\") return \"application/pdf\";\n if ([\"png\", \"jpg\", \"jpeg\", \"gif\", \"webp\", \"svg\", \"bmp\"].includes(ext)) {\n return `image/${ext === \"jpg\" ? \"jpeg\" : ext === \"svg\" ? \"svg+xml\" : ext}`;\n }\n }\n }\n\n return null;\n}\n\n/** Get the appropriate first-tab label based on content MIME type. */\nexport function getHtmlTabLabel(contentType?: string | null): string {\n if (contentType === \"application/pdf\") return \"PDF\";\n if (contentType?.startsWith(\"image/\")) return \"Image\";\n return \"HTML\";\n}\n\n/**\n * Find stuff data by digest in a GraphSpec.\n * Scans all nodes' IO items — outputs first (producer data), then inputs as fallback.\n */\nexport function findStuffDataByDigest(\n graphspec: GraphSpec,\n digest: string,\n): StuffViewerData | null {\n // First pass: look in outputs (producer has the richest data)\n for (const node of graphspec.nodes) {\n for (const output of node.io?.outputs ?? []) {\n if (output.digest === digest) {\n return {\n digest,\n name: output.name,\n concept: output.concept,\n contentType: output.content_type,\n data: output.data,\n dataText: output.data_text,\n dataHtml: output.data_html,\n };\n }\n }\n }\n\n // Second pass: look in inputs (for pipeline-level inputs without a producer)\n for (const node of graphspec.nodes) {\n for (const input of node.io?.inputs ?? []) {\n if (input.digest === digest) {\n return {\n digest,\n name: input.name,\n concept: input.concept,\n contentType: input.content_type,\n data: input.data,\n dataText: input.data_text,\n dataHtml: input.data_html,\n };\n }\n }\n }\n\n return null;\n}\n","import React from \"react\";\nimport DOMPurify from \"dompurify\";\n\nimport type { ResolveStorageUrl, StuffViewerData } from \"./stuffViewerTypes\";\nimport {\n extractFilename,\n extractInlineUrl,\n extractStorageUri,\n extractUrl,\n getHtmlTabLabel,\n isInlineRenderableUrl,\n resolveMimeType,\n} from \"./stuffViewerUtils\";\nimport \"./StuffViewer.css\";\n\ntype StuffTab = \"html\" | \"json\" | \"text\";\n\nexport interface StuffViewerProps {\n stuff: StuffViewerData;\n className?: string;\n /**\n * Resolver for `pipelex-storage://` URIs. If provided and the stuff data\n * references an internal URI, the viewer will call this to obtain a\n * presigned URL for inline rendering. Without a resolver, media with only\n * internal URIs falls back to the \"no preview\" placeholder.\n */\n resolveStorageUrl?: ResolveStorageUrl;\n /**\n * Set to `false` when the host cannot render `<embed type=\"application/pdf\">`\n * — e.g. VS Code webviews, which run inside Electron without the Chromium\n * PDFium plugin. The PDF view then falls back to a clickable tile that\n * triggers `onOpenExternally` (or `window.open` if not provided).\n *\n * Default: `true`.\n */\n canEmbedPdf?: boolean;\n /**\n * Replaces the default `window.open(url, \"_blank\")` behavior for both the\n * toolbar \"open externally\" button and the PDF fallback tile. Use this in\n * environments where `window.open` is blocked or undesirable — for example,\n * VS Code webviews should wire this to `vscode.env.openExternal` via\n * postMessage.\n */\n onOpenExternally?: (url: string, filename?: string) => void;\n}\n\n// ─── SVG icon paths ──────────────────────────────────────────────────────────\n\nconst ICON_COPY = (\n <svg viewBox=\"0 0 24 24\">\n <path d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\" />\n </svg>\n);\n\nconst ICON_CHECK = (\n <svg viewBox=\"0 0 24 24\">\n <path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\" />\n </svg>\n);\n\nconst ICON_DOWNLOAD = (\n <svg viewBox=\"0 0 24 24\">\n <path d=\"M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z\" />\n </svg>\n);\n\nconst ICON_EXTERNAL = (\n <svg viewBox=\"0 0 24 24\">\n <path d=\"M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z\" />\n </svg>\n);\n\nconst ICON_LOCAL_FILE = (\n <svg viewBox=\"0 0 24 24\">\n <path d=\"M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm4 18H6V4h7v5h5v11z\" />\n </svg>\n);\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction escapeHtml(text: string): string {\n return text.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\n}\n\nfunction downloadBlob(content: string, filename: string, mimeType: string) {\n const blob = new Blob([content], { type: mimeType });\n const url = URL.createObjectURL(blob);\n const link = document.createElement(\"a\");\n link.href = url;\n link.download = filename;\n link.click();\n // Defer revocation so the browser has time to start reading the blob\n setTimeout(() => URL.revokeObjectURL(url), 10_000);\n}\n\nfunction downloadUrl(url: string, filename: string) {\n const link = document.createElement(\"a\");\n link.href = url;\n link.download = filename;\n link.target = \"_blank\";\n link.click();\n}\n\n// ─── Component ───────────────────────────────────────────────────────────────\n\nexport function StuffViewer({\n stuff,\n className,\n resolveStorageUrl,\n canEmbedPdf,\n onOpenExternally,\n}: StuffViewerProps) {\n const [activeTab, setActiveTab] = React.useState<StuffTab>(\"html\");\n const [copied, setCopied] = React.useState(false);\n const contentRef = React.useRef<HTMLDivElement>(null);\n\n // URL for inline rendering (img/embed) — only http/https\n const httpInlineUrl = React.useMemo(() => extractInlineUrl(stuff.data), [stuff.data]);\n // URL for links/downloads — includes file:// too\n const httpExternalUrl = React.useMemo(() => extractUrl(stuff.data), [stuff.data]);\n // Internal pipelex-storage:// URI, if any — needs async resolution before rendering\n const storageUri = React.useMemo(() => extractStorageUri(stuff.data), [stuff.data]);\n const filename = React.useMemo(() => extractFilename(stuff.data), [stuff.data]);\n\n // Resolve pipelex-storage:// URIs to browser-fetchable URLs via the provided resolver.\n // Only runs when no direct http(s) URL is available — we prefer public_url/src/href first.\n const [resolvedStorageUrl, setResolvedStorageUrl] = React.useState<string | null>(null);\n React.useEffect(() => {\n // Clear any previously resolved URL synchronously so a second stuff item\n // never briefly renders with the prior item's resolved URL while the new\n // promise is in flight.\n setResolvedStorageUrl(null);\n if (!storageUri || !resolveStorageUrl || httpInlineUrl) {\n return;\n }\n let cancelled = false;\n resolveStorageUrl(storageUri)\n .then((url) => {\n if (cancelled) return;\n // Defensive: the resolver is consumer-supplied. Gate its output through\n // the same scheme check as every other URL path (isInlineRenderableUrl\n // rejects javascript:, data:, vbscript:, etc.) so a faulty or\n // compromised resolver can't inject an unsafe URL into <img>/<iframe>.\n setResolvedStorageUrl(isInlineRenderableUrl(url) ? url : null);\n })\n .catch(() => {\n if (!cancelled) setResolvedStorageUrl(null);\n });\n return () => {\n cancelled = true;\n };\n }, [storageUri, resolveStorageUrl, httpInlineUrl]);\n\n const inlineUrl = httpInlineUrl ?? resolvedStorageUrl;\n const externalUrl = httpExternalUrl ?? resolvedStorageUrl;\n // Effective MIME type: stuff.contentType is often the concept tag (\"document\"),\n // not a MIME. Fall back to data.mime_type or the file extension.\n const effectiveMime = React.useMemo(\n () => resolveMimeType(stuff.data, stuff.contentType, externalUrl ?? storageUri),\n [stuff.data, stuff.contentType, externalUrl, storageUri],\n );\n const isPdf = effectiveMime === \"application/pdf\";\n const isImage = effectiveMime?.startsWith(\"image/\") ?? false;\n const htmlTabLabel = getHtmlTabLabel(effectiveMime ?? stuff.contentType);\n const jsonString = React.useMemo(() => {\n if (stuff.data == null) return null;\n try {\n return JSON.stringify(stuff.data, null, 2);\n } catch {\n return \"[Unable to serialize data]\";\n }\n }, [stuff.data]);\n\n // Make links in sanitized HTML open in new windows\n React.useEffect(() => {\n if (activeTab !== \"html\" || !contentRef.current) return;\n contentRef.current.querySelectorAll(\"a\").forEach((link) => {\n link.setAttribute(\"target\", \"_blank\");\n link.setAttribute(\"rel\", \"noopener noreferrer\");\n });\n }, [activeTab, stuff.dataHtml]);\n\n // ── Tab rendering ────────────────────────────────────────────────────────\n\n /** Fallback for images/PDFs when no inline-renderable URL is available\n * (e.g., only pipelex-storage:// internal URLs exist). */\n function renderMediaFallback(mediaLabel: string) {\n const displayName = filename || stuff.name;\n return (\n <div className=\"stuff-viewer-local-file\">\n <div className=\"stuff-viewer-local-file-icon\">{ICON_LOCAL_FILE}</div>\n <div className=\"stuff-viewer-local-file-info\">\n {displayName && <div className=\"stuff-viewer-local-file-name\">{displayName}</div>}\n <div className=\"stuff-viewer-local-file-hint\">{mediaLabel} — no preview available</div>\n </div>\n </div>\n );\n }\n\n function renderContent() {\n if (activeTab === \"html\") {\n // PDF embed\n if (isPdf) {\n const canEmbed = canEmbedPdf !== false;\n if (canEmbed && inlineUrl) {\n // #pagemode=none hides the sidebar/page thumbnails in the browser PDF viewer\n const pdfUrl = inlineUrl.includes(\"#\") ? inlineUrl : `${inlineUrl}#pagemode=none`;\n return (\n <div className=\"stuff-viewer-pdf\">\n <embed src={pdfUrl} type=\"application/pdf\" />\n </div>\n );\n }\n // Either the host can't render <embed type=\"application/pdf\"> (Electron\n // webviews lack PDFium) or no inline URL is available. If we still have\n // an external URL, give the user a clickable tile to open it.\n if (externalUrl) {\n const displayName = filename || stuff.name;\n return (\n <button\n type=\"button\"\n className=\"stuff-viewer-local-file stuff-viewer-local-file--button\"\n onClick={handleOpenExternal}\n >\n <div className=\"stuff-viewer-local-file-icon\">{ICON_LOCAL_FILE}</div>\n <div className=\"stuff-viewer-local-file-info\">\n {displayName && (\n <div className=\"stuff-viewer-local-file-name\">{displayName}</div>\n )}\n <div className=\"stuff-viewer-local-file-hint\">Click to open PDF externally</div>\n </div>\n </button>\n );\n }\n return renderMediaFallback(\"PDF\");\n }\n\n // Image display\n if (isImage) {\n if (inlineUrl) {\n return (\n <div className=\"stuff-viewer-image\">\n <img src={inlineUrl} alt={stuff.name || \"Image content\"} />\n </div>\n );\n }\n return renderMediaFallback(\"Image\");\n }\n\n // HTML content\n if (stuff.dataHtml) {\n return (\n <div\n className=\"stuff-viewer-html\"\n dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(stuff.dataHtml) }}\n />\n );\n }\n\n // Fallback to JSON\n if (jsonString) {\n return (\n <pre\n className=\"stuff-viewer-pre\"\n dangerouslySetInnerHTML={{ __html: escapeHtml(jsonString) }}\n />\n );\n }\n\n return <div className=\"stuff-viewer-placeholder\">No content available</div>;\n }\n\n if (activeTab === \"json\") {\n if (jsonString) {\n return (\n <pre\n className=\"stuff-viewer-pre\"\n dangerouslySetInnerHTML={{ __html: escapeHtml(jsonString) }}\n />\n );\n }\n return <div className=\"stuff-viewer-placeholder\">No JSON data available</div>;\n }\n\n // text tab\n if (stuff.dataText) {\n return (\n <pre\n className=\"stuff-viewer-pre stuff-viewer-pre--nowrap\"\n dangerouslySetInnerHTML={{ __html: escapeHtml(stuff.dataText) }}\n />\n );\n }\n // Fallback to JSON\n if (jsonString) {\n return (\n <pre\n className=\"stuff-viewer-pre\"\n dangerouslySetInnerHTML={{ __html: escapeHtml(jsonString) }}\n />\n );\n }\n return <div className=\"stuff-viewer-placeholder\">No text data available</div>;\n }\n\n // ── Actions ──────────────────────────────────────────────────────────────\n\n function handleCopy() {\n let textToCopy: string;\n if (activeTab === \"json\") {\n textToCopy = jsonString || \"\";\n } else if (activeTab === \"text\") {\n textToCopy = stuff.dataText || jsonString || \"\";\n } else {\n textToCopy = stuff.dataText || stuff.dataHtml || jsonString || \"\";\n }\n if (!textToCopy) return;\n\n if (navigator.clipboard) {\n navigator.clipboard\n .writeText(textToCopy)\n .then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n })\n .catch(() => {\n // Clipboard API may be unavailable in non-secure contexts\n });\n }\n }\n\n function handleDownload() {\n // For images, download the actual file\n if (isImage && externalUrl) {\n const ext = effectiveMime?.split(\"/\")[1] || \"png\";\n downloadUrl(externalUrl, `${stuff.name || \"stuff\"}.${ext}`);\n return;\n }\n\n // For PDFs, download the actual file\n if (isPdf && externalUrl) {\n downloadUrl(externalUrl, `${stuff.name || \"stuff\"}.pdf`);\n return;\n }\n\n // Otherwise download current tab's text content\n if (activeTab === \"json\") {\n downloadBlob(jsonString || \"{}\", `${stuff.name || \"stuff\"}.json`, \"application/json\");\n } else if (activeTab === \"text\") {\n downloadBlob(\n stuff.dataText || jsonString || \"\",\n `${stuff.name || \"stuff\"}.txt`,\n \"text/plain\",\n );\n } else {\n downloadBlob(\n stuff.dataHtml || jsonString || \"\",\n `${stuff.name || \"stuff\"}.html`,\n \"text/html\",\n );\n }\n }\n\n function handleOpenExternal() {\n if (!externalUrl) return;\n if (onOpenExternally) {\n onOpenExternally(externalUrl, filename ?? undefined);\n return;\n }\n window.open(externalUrl, \"_blank\", \"noopener,noreferrer\");\n }\n\n // ── Render ───────────────────────────────────────────────────────────────\n\n const rootClass = [\"stuff-viewer\", className].filter(Boolean).join(\" \");\n\n return (\n <div className={rootClass}>\n <div className=\"stuff-viewer-header\">\n <h3 className=\"stuff-viewer-title\">{stuff.name || \"Data\"}</h3>\n {stuff.concept && <p className=\"stuff-viewer-subtitle\">{stuff.concept}</p>}\n </div>\n\n <div className=\"stuff-viewer-toolbar\">\n <div className=\"stuff-viewer-tabs\">\n {([\"html\", \"json\", \"text\"] as const).map((tab) => {\n const label = tab === \"html\" ? htmlTabLabel : tab === \"json\" ? \"JSON\" : \"Pretty\";\n const isActive = activeTab === tab;\n return (\n <button\n type=\"button\"\n key={tab}\n className={`stuff-viewer-tab${isActive ? \" stuff-viewer-tab--active\" : \"\"}`}\n onClick={() => setActiveTab(tab)}\n >\n {label}\n </button>\n );\n })}\n </div>\n\n <div className=\"stuff-viewer-actions\">\n {externalUrl && (\n <button\n type=\"button\"\n className=\"stuff-viewer-action-btn\"\n onClick={handleOpenExternal}\n title=\"Open in new window\"\n aria-label=\"Open in new window\"\n >\n {ICON_EXTERNAL}\n </button>\n )}\n <button\n type=\"button\"\n className={`stuff-viewer-action-btn${copied ? \" stuff-viewer-action-btn--copied\" : \"\"}`}\n onClick={handleCopy}\n title=\"Copy\"\n aria-label=\"Copy\"\n >\n {copied ? ICON_CHECK : ICON_COPY}\n </button>\n <button\n type=\"button\"\n className=\"stuff-viewer-action-btn\"\n onClick={handleDownload}\n title=\"Download\"\n aria-label=\"Download\"\n >\n {ICON_DOWNLOAD}\n </button>\n </div>\n </div>\n\n <div className=\"stuff-viewer-content\" ref={contentRef}>\n {renderContent()}\n </div>\n </div>\n );\n}\n","import React from \"react\";\nimport \"./DetailPanel.css\";\n\nexport interface DetailPanelProps {\n isOpen: boolean;\n onClose: () => void;\n children: React.ReactNode;\n /** Panel width in pixels. When provided, overrides the CSS default. */\n width?: number;\n /** Whether a resize drag is in progress. Disables CSS transition during drag. */\n isDragging?: boolean;\n /** Mouse-down handler for the resize handle. When provided, the handle is rendered. */\n onResizeHandleMouseDown?: (e: React.MouseEvent) => void;\n /** Close panel on Escape key. Defaults to true. */\n closeOnEscape?: boolean;\n}\n\nexport function DetailPanel({\n isOpen,\n onClose,\n children,\n width,\n isDragging,\n onResizeHandleMouseDown,\n closeOnEscape = true,\n}: DetailPanelProps) {\n React.useEffect(() => {\n if (!isOpen || !closeOnEscape) return;\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n document.addEventListener(\"keydown\", onKeyDown);\n return () => document.removeEventListener(\"keydown\", onKeyDown);\n }, [isOpen, closeOnEscape, onClose]);\n\n const className = [\n \"detail-panel\",\n !isOpen && \"detail-panel--closed\",\n isDragging && \"detail-panel--dragging\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div className={className} style={width ? { width: `${width}px` } : undefined}>\n {onResizeHandleMouseDown && (\n <div\n className=\"detail-panel-resize-handle\"\n onMouseDown={onResizeHandleMouseDown}\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label=\"Resize panel\"\n />\n )}\n <button className=\"detail-panel-close\" onClick={onClose} aria-label=\"Close panel\">\n x\n </button>\n <div className=\"detail-panel-content\">{children}</div>\n </div>\n );\n}\n","import React from \"react\";\n\n// ─── Types ──────────────────────────────────────────────────────────────────\n\nexport interface UseResizableOptions {\n /** Initial panel width in pixels. */\n defaultWidth: number;\n /** Minimum allowed width in pixels. */\n minWidth: number;\n /** Maximum allowed width in pixels (also clamped to 60% of container). */\n maxWidth: number;\n /** Container element ref for percentage-based max-width calculation. */\n containerRef?: React.RefObject<HTMLElement | null>;\n}\n\nexport interface UseResizableResult {\n /** Current panel width in pixels. */\n width: number;\n /** Whether a resize drag is in progress. */\n isDragging: boolean;\n /** Attach to the resize handle's onMouseDown. */\n handleMouseDown: (e: React.MouseEvent) => void;\n}\n\n// ─── Hook ───────────────────────────────────────────────────────────────────\n\nconst MAX_WIDTH_RATIO = 0.6;\n\nexport function useResizable({\n defaultWidth,\n minWidth,\n maxWidth,\n containerRef,\n}: UseResizableOptions): UseResizableResult {\n const [width, setWidth] = React.useState(defaultWidth);\n const [isDragging, setIsDragging] = React.useState(false);\n\n // Store drag state in refs to avoid stale closures in document listeners\n const dragRef = React.useRef({ startX: 0, startWidth: 0, maxAllowed: maxWidth });\n const rafRef = React.useRef<number | null>(null);\n\n const handleMouseDown = React.useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n // Compute max allowed width once at drag start\n const containerWidth = containerRef?.current?.getBoundingClientRect().width;\n const maxAllowed = containerWidth\n ? Math.min(maxWidth, containerWidth * MAX_WIDTH_RATIO)\n : maxWidth;\n\n dragRef.current = { startX: e.clientX, startWidth: width, maxAllowed };\n setIsDragging(true);\n\n // Prevent text selection and set cursor globally during drag\n document.body.style.userSelect = \"none\";\n document.body.style.cursor = \"col-resize\";\n },\n [width, maxWidth, containerRef],\n );\n\n React.useEffect(() => {\n if (!isDragging) return;\n\n const onMouseMove = (e: MouseEvent) => {\n if (rafRef.current !== null) cancelAnimationFrame(rafRef.current);\n\n rafRef.current = requestAnimationFrame(() => {\n const { startX, startWidth, maxAllowed } = dragRef.current;\n // Dragging left (negative deltaX) increases width for a right-anchored panel\n const deltaX = startX - e.clientX;\n const newWidth = Math.max(minWidth, Math.min(maxAllowed, startWidth + deltaX));\n setWidth(newWidth);\n rafRef.current = null;\n });\n };\n\n const onMouseUp = () => {\n setIsDragging(false);\n document.body.style.userSelect = \"\";\n document.body.style.cursor = \"\";\n if (rafRef.current !== null) {\n cancelAnimationFrame(rafRef.current);\n rafRef.current = null;\n }\n };\n\n document.addEventListener(\"mousemove\", onMouseMove);\n document.addEventListener(\"mouseup\", onMouseUp);\n\n return () => {\n document.removeEventListener(\"mousemove\", onMouseMove);\n document.removeEventListener(\"mouseup\", onMouseUp);\n document.body.style.userSelect = \"\";\n document.body.style.cursor = \"\";\n if (rafRef.current !== null) {\n cancelAnimationFrame(rafRef.current);\n rafRef.current = null;\n }\n };\n }, [isDragging, minWidth]);\n\n return { width, isDragging, handleMouseDown };\n}\n","import React from \"react\";\nimport type { GraphSpecNode, PipeBlueprintUnion, PipeType, GraphSpec } from \"@graph/types\";\nimport { getPipeBlueprint } from \"@graph/graphAnalysis\";\nimport {\n formatDuration,\n KV,\n PipeLLMSection,\n LLMExecutionData,\n PipeImgGenSection,\n ImgGenExecutionData,\n PipeExtractSection,\n ExtractExecutionData,\n PipeSearchSection,\n SearchExecutionData,\n PipeComposeSection,\n ComposeExecutionData,\n PipeConditionSection,\n ConditionExecutionData,\n PipeSequenceSection,\n SequenceExecutionData,\n PipeParallelSection,\n ParallelExecutionData,\n PipeBatchSection,\n BatchExecutionData,\n} from \"./sections\";\nimport \"./DetailPanel.css\";\n\n// ─── Badge / Status config ─────────────────────────────────────────────\n\nconst PIPE_TYPE_BADGES: Record<PipeType, string> = {\n PipeLLM: \"LLM\",\n PipeExtract: \"Extract\",\n PipeCompose: \"Compose\",\n PipeImgGen: \"ImgGen\",\n PipeSearch: \"Search\",\n PipeFunc: \"Func\",\n PipeSequence: \"Seq\",\n PipeParallel: \"Par\",\n PipeCondition: \"Cond\",\n PipeBatch: \"Batch\",\n};\n\nconst CONTROLLER_TYPES = new Set<string>([\n \"PipeSequence\",\n \"PipeParallel\",\n \"PipeCondition\",\n \"PipeBatch\",\n]);\n\nconst STATUS_COLORS: Record<string, string> = {\n succeeded: \"#50FA7B\",\n failed: \"#FF5555\",\n running: \"#8BE9FD\",\n scheduled: \"#6272a4\",\n skipped: \"#6272a4\",\n};\n\n// ─── Props ──────────────────────────────────────────────────────────────\n\nexport interface PipeDetailPanelProps {\n node: GraphSpecNode;\n spec: GraphSpec;\n onConceptClick?: (conceptRef: string) => void;\n}\n\n// ─── Component ──────────────────────────────────────────────────────────\n\nexport function PipeDetailPanel({ node, spec, onConceptClick }: PipeDetailPanelProps) {\n const pipeType = node.pipe_type ?? \"PipeFunc\";\n const isController = CONTROLLER_TYPES.has(pipeType);\n const badge = PIPE_TYPE_BADGES[pipeType as PipeType] ?? pipeType;\n const status = node.status ?? \"scheduled\";\n const statusColor = STATUS_COLORS[status] ?? \"#6272a4\";\n\n // Look up the full blueprint from registry — search by pipe_code suffix since\n // the registry key is domain.pipe_code and the node only has pipe_code\n const blueprint = React.useMemo(() => {\n if (!node.pipe_code || !spec.pipe_registry) return undefined;\n // Direct lookup with pipeline domain\n const directKey = `${spec.pipeline_ref?.domain ?? \"\"}.${node.pipe_code}`;\n const direct = getPipeBlueprint(spec, directKey);\n if (direct) return direct;\n // Search all registry entries by pipe_code suffix\n for (const [ref, pipe] of Object.entries(spec.pipe_registry)) {\n if (ref.endsWith(`.${node.pipe_code}`)) return pipe as PipeBlueprintUnion;\n }\n return undefined;\n }, [node.pipe_code, spec]);\n\n const inputs = node.io?.inputs ?? [];\n const outputs = node.io?.outputs ?? [];\n const description = blueprint?.description ?? node.description;\n\n return (\n <>\n {/* Sticky header: badge, status, description, IO */}\n <div className=\"detail-sticky-header\">\n {/* Header: badge + pipe code */}\n <div className=\"detail-header\">\n <span\n className={`detail-badge ${isController ? \"detail-badge--controller\" : \"detail-badge--operator\"}`}\n >\n {badge}\n </span>\n <span\n className={`detail-pipe-code ${isController ? \"detail-pipe-code--controller\" : \"\"}`}\n >\n {node.pipe_code ?? \"unknown\"}\n </span>\n </div>\n\n {/* Status + Duration */}\n <div className=\"detail-status\">\n <span className=\"detail-status-dot\" style={{ background: statusColor }} />\n <span className=\"detail-status-label\" style={{ color: statusColor }}>\n {status}\n </span>\n {node.timing?.duration != null && (\n <span className=\"detail-duration\">{formatDuration(node.timing.duration)}</span>\n )}\n </div>\n\n {/* Description */}\n {description && <div className=\"detail-description\">{description}</div>}\n\n {/* Inputs */}\n {inputs.length > 0 && (\n <div>\n <div className=\"detail-section-label\">Inputs</div>\n <div className=\"detail-io-list\">\n {inputs.map((input, idx) => (\n <div\n key={idx}\n className=\"detail-io-pill\"\n style={{ cursor: input.concept && onConceptClick ? \"pointer\" : undefined }}\n onClick={() => input.concept && onConceptClick?.(input.concept)}\n >\n <span className=\"detail-io-name\">{input.name ?? \"unnamed\"}</span>\n {input.concept && <span className=\"detail-io-concept\">{input.concept}</span>}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Outputs */}\n {outputs.length > 0 && (\n <div>\n <div className=\"detail-section-label\">Output</div>\n <div className=\"detail-io-list\">\n {outputs.map((output, idx) => (\n <div\n key={idx}\n className=\"detail-io-pill\"\n style={{ cursor: output.concept && onConceptClick ? \"pointer\" : undefined }}\n onClick={() => output.concept && onConceptClick?.(output.concept)}\n >\n <span className=\"detail-io-name\">{output.name ?? \"unnamed\"}</span>\n {output.concept && <span className=\"detail-io-concept\">{output.concept}</span>}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Separator after IO */}\n {(inputs.length > 0 || outputs.length > 0) && (\n <div style={{ borderTop: \"1px solid rgba(255,255,255,0.06)\", margin: \"4px 0\" }} />\n )}\n </div>\n\n {/* Blueprint-specific sections */}\n {blueprint && <BlueprintSection blueprint={blueprint} executionData={node.execution_data} />}\n\n {/* Execution data (runtime-resolved values) */}\n {node.execution_data && Object.keys(node.execution_data).length > 0 && (\n <ExecutionDataSection executionData={node.execution_data} pipeType={pipeType} />\n )}\n\n {/* Error */}\n {node.error && (\n <div className=\"detail-error\">\n <div className=\"detail-error-type\">{node.error.error_type}</div>\n <div className=\"detail-error-message\">{node.error.message}</div>\n {node.error.stack && <div className=\"detail-error-stack\">{node.error.stack}</div>}\n </div>\n )}\n\n {/* Metrics */}\n {node.metrics && Object.keys(node.metrics).length > 0 && (\n <div>\n <div className=\"detail-section-label\">Metrics</div>\n {Object.entries(node.metrics).map(([key, value]) => (\n <KV\n key={key}\n label={key}\n value={typeof value === \"number\" ? value.toLocaleString() : String(value)}\n />\n ))}\n </div>\n )}\n\n {/* Tags */}\n {node.tags && Object.keys(node.tags).length > 0 && (\n <div>\n <div className=\"detail-section-label\">Tags</div>\n <div className=\"detail-tags\">\n {Object.entries(node.tags).map(([key, value]) => (\n <span key={key} className=\"detail-tag\">\n <span className=\"detail-tag-key\">{key}: </span>\n <span className=\"detail-tag-value\">{value}</span>\n </span>\n ))}\n </div>\n </div>\n )}\n\n {/* Blueprint not available */}\n {!blueprint && <div className=\"detail-not-available\">Blueprint not available</div>}\n </>\n );\n}\n\n// ─── Blueprint dispatch ─────────────────────────────────────────────────────\n\nfunction BlueprintSection({\n blueprint,\n executionData,\n}: {\n blueprint: PipeBlueprintUnion;\n executionData?: Record<string, unknown>;\n}) {\n switch (blueprint.type) {\n case \"PipeLLM\":\n return <PipeLLMSection blueprint={blueprint} executionData={executionData} />;\n case \"PipeImgGen\":\n return <PipeImgGenSection blueprint={blueprint} executionData={executionData} />;\n case \"PipeCompose\":\n return <PipeComposeSection blueprint={blueprint} executionData={executionData} />;\n case \"PipeExtract\":\n return <PipeExtractSection blueprint={blueprint} executionData={executionData} />;\n case \"PipeSearch\":\n return <PipeSearchSection blueprint={blueprint} executionData={executionData} />;\n case \"PipeSequence\":\n return <PipeSequenceSection blueprint={blueprint} executionData={executionData} />;\n case \"PipeParallel\":\n return <PipeParallelSection blueprint={blueprint} executionData={executionData} />;\n case \"PipeCondition\":\n return <PipeConditionSection blueprint={blueprint} executionData={executionData} />;\n case \"PipeBatch\":\n return <PipeBatchSection blueprint={blueprint} executionData={executionData} />;\n case \"PipeFunc\":\n return null;\n }\n}\n\n// ─── Execution data dispatch ────────────────────────────────────────────────\n\nfunction ExecutionDataSection({\n executionData,\n pipeType,\n}: {\n executionData: Record<string, unknown>;\n pipeType: string;\n}) {\n switch (pipeType) {\n case \"PipeLLM\":\n return <LLMExecutionData data={executionData} />;\n case \"PipeImgGen\":\n return <ImgGenExecutionData data={executionData} />;\n case \"PipeExtract\":\n return <ExtractExecutionData data={executionData} />;\n case \"PipeSearch\":\n return <SearchExecutionData data={executionData} />;\n case \"PipeCompose\":\n return <ComposeExecutionData data={executionData} />;\n case \"PipeCondition\":\n return <ConditionExecutionData data={executionData} />;\n case \"PipeSequence\":\n return <SequenceExecutionData data={executionData} />;\n case \"PipeParallel\":\n return <ParallelExecutionData data={executionData} />;\n case \"PipeBatch\":\n return <BatchExecutionData data={executionData} />;\n default:\n return <GenericExecutionData data={executionData} />;\n }\n}\n\nfunction GenericExecutionData({ data }: { data: Record<string, unknown> }) {\n const entries = Object.entries(data);\n if (entries.length === 0) return null;\n return (\n <>\n <div className=\"detail-section-label\">Execution</div>\n {entries.map(([key, value]) => (\n <KV key={key} label={key} value={String(value)} />\n ))}\n </>\n );\n}\n","import React, { useState } from \"react\";\n\n// ─── Shared display helpers ────────────────────────────────────────────────\n\nexport function formatDuration(seconds: number): string {\n if (seconds < 1) return `${(seconds * 1000).toFixed(0)}ms`;\n return `${seconds.toFixed(2)}s`;\n}\n\nexport function KV({\n label,\n value,\n}: {\n label: string;\n value: string | number | boolean | null | undefined;\n}) {\n if (value === null || value === undefined) return null;\n return (\n <div className=\"detail-kv-row\">\n <span className=\"detail-kv-key\">{label}</span>\n <span className=\"detail-kv-value\">{String(value)}</span>\n </div>\n );\n}\n\nexport function PromptBlock({ label, text }: { label: string; text: string | null | undefined }) {\n if (!text) return null;\n return (\n <div>\n <div className=\"detail-section-label\">{label}</div>\n <div className=\"detail-prompt-block\">{text}</div>\n </div>\n );\n}\n\n/**\n * Toggle between template and rendered prompt.\n * Default shows rendered (the real prompt that was sent).\n */\nconst EXPAND_ICON = (\n <svg viewBox=\"0 0 24 24\" width=\"10\" height=\"10\" fill=\"currentColor\">\n <path d=\"M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z\" />\n </svg>\n);\n\nconst COLLAPSE_ICON = (\n <svg viewBox=\"0 0 24 24\" width=\"10\" height=\"10\" fill=\"currentColor\">\n <path d=\"M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z\" />\n </svg>\n);\n\nconst COPY_ICON = (\n <svg viewBox=\"0 0 24 24\" width=\"10\" height=\"10\" fill=\"currentColor\">\n <path d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\" />\n </svg>\n);\n\nconst CHECK_ICON = (\n <svg viewBox=\"0 0 24 24\" width=\"10\" height=\"10\" fill=\"currentColor\">\n <path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\" />\n </svg>\n);\n\nconst promptActionStyle: React.CSSProperties = {\n all: \"unset\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n gap: 4,\n fontSize: 9,\n color: \"#64748b\",\n padding: \"2px 6px\",\n borderRadius: 3,\n background: \"rgba(255,255,255,0.04)\",\n border: \"1px solid rgba(255,255,255,0.06)\",\n transition: \"color 0.15s\",\n};\n\nexport function PromptToggle({\n label,\n templateText,\n renderedText,\n}: {\n label: string;\n templateText: string | null | undefined;\n renderedText: string | null | undefined;\n}) {\n const [showTemplate, setShowTemplate] = useState(false);\n const [copied, setCopied] = useState(false);\n const [expanded, setExpanded] = useState(false);\n\n const hasTemplate = !!templateText;\n const hasRendered = !!renderedText;\n if (!hasTemplate && !hasRendered) return null;\n const canToggle = hasTemplate && hasRendered;\n // Show rendered by default when available; fall back to template\n const activeText = canToggle\n ? showTemplate\n ? templateText\n : renderedText\n : templateText || renderedText;\n\n function handleCopy() {\n if (!activeText || !navigator.clipboard) return;\n navigator.clipboard\n .writeText(activeText)\n .then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n })\n .catch(() => {});\n }\n\n return (\n <div>\n <div\n style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", gap: 4 }}\n >\n <div className=\"detail-section-label\" style={{ marginBottom: 0 }}>\n {label}\n </div>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 4 }}>\n <button\n onClick={() => setExpanded((prev) => !prev)}\n title={expanded ? \"Collapse prompt\" : \"Expand prompt\"}\n aria-label={expanded ? \"Collapse prompt\" : \"Expand prompt\"}\n className=\"detail-prompt-expand-btn\"\n >\n {expanded ? COLLAPSE_ICON : EXPAND_ICON}\n </button>\n <button\n onClick={handleCopy}\n title=\"Copy prompt\"\n aria-label=\"Copy prompt\"\n style={{\n ...promptActionStyle,\n color: copied ? \"#10b981\" : \"#64748b\",\n }}\n >\n {copied ? CHECK_ICON : COPY_ICON}\n </button>\n {canToggle && (\n <button onClick={() => setShowTemplate((prev) => !prev)} style={promptActionStyle}>\n <span\n style={{\n width: 22,\n height: 12,\n borderRadius: 6,\n background: showTemplate ? \"rgba(255,255,255,0.12)\" : \"#50FA7B33\",\n position: \"relative\",\n display: \"inline-block\",\n transition: \"background 0.15s\",\n }}\n >\n <span\n style={{\n position: \"absolute\",\n top: 2,\n left: showTemplate ? 2 : 12,\n width: 8,\n height: 8,\n borderRadius: \"50%\",\n background: showTemplate ? \"#94a3b8\" : \"#50FA7B\",\n transition: \"left 0.15s, background 0.15s\",\n }}\n />\n </span>\n {showTemplate ? \"template\" : \"rendered\"}\n </button>\n )}\n </div>\n </div>\n <div\n className={`detail-prompt-block ${expanded ? \"detail-prompt-block--expanded\" : \"detail-prompt-block--collapsed\"}`}\n style={{ marginTop: 6 }}\n >\n {activeText}\n </div>\n </div>\n );\n}\n","import React from \"react\";\nimport type { PipeBlueprintUnion } from \"@graph/types\";\nimport { KV, PromptToggle } from \"./shared\";\n\n/**\n * Unified PipeLLM detail — merges blueprint config and runtime execution data\n * into a single view. Runtime values take precedence when available.\n */\nexport function PipeLLMSection({\n blueprint,\n executionData,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeLLM\" }>;\n executionData?: Record<string, unknown>;\n}) {\n const spec = blueprint.llm_prompt_spec;\n const hasImageRefs = spec.user_image_references && spec.user_image_references.length > 0;\n const hasDocRefs = spec.user_document_references && spec.user_document_references.length > 0;\n const hasSysImageRefs = spec.system_image_references && spec.system_image_references.length > 0;\n const hasSysDocRefs =\n spec.system_document_references && spec.system_document_references.length > 0;\n\n // Runtime-resolved values (from execution_data)\n const resolvedModel = executionData?.resolved_model as string | undefined;\n const resolvedModelForObject = executionData?.resolved_model_for_object as string | undefined;\n const renderedSystem = executionData?.rendered_system_prompt as string | undefined;\n const renderedUser = executionData?.rendered_user_prompt as string | undefined;\n const structuringPath = executionData?.structuring_path as string | undefined;\n const isMultipleOutput = executionData?.is_multiple_output as boolean | undefined;\n\n // Model: show resolved if available, otherwise config choice\n const modelDisplay = resolvedModel || blueprint.llm_choices?.for_text;\n const modelForObjectDisplay = resolvedModelForObject || blueprint.llm_choices?.for_object;\n\n return (\n <>\n {/* Model */}\n <KV label=\"Model\" value={modelDisplay} />\n {modelForObjectDisplay && modelForObjectDisplay !== modelDisplay && (\n <KV label=\"Model (object)\" value={modelForObjectDisplay} />\n )}\n\n {/* Structuring — show runtime path if available, otherwise config method */}\n <KV label=\"Structuring\" value={structuringPath || blueprint.structuring_method} />\n <KV label=\"Multiple Output\" value={isMultipleOutput} />\n <KV label=\"Output Multiplicity\" value={blueprint.output_multiplicity} />\n <KV label=\"Prompt Category\" value={spec.prompt_blueprint?.category} />\n\n {/* References */}\n {hasImageRefs && (\n <KV label=\"User Image Refs\" value={`${spec.user_image_references!.length} references`} />\n )}\n {hasDocRefs && (\n <KV\n label=\"User Document Refs\"\n value={`${spec.user_document_references!.length} references`}\n />\n )}\n {hasSysImageRefs && (\n <KV\n label=\"System Image Refs\"\n value={`${spec.system_image_references!.length} references`}\n />\n )}\n {hasSysDocRefs && (\n <KV\n label=\"System Document Refs\"\n value={`${spec.system_document_references!.length} references`}\n />\n )}\n\n {/* Prompts — last, toggle between template and rendered */}\n <PromptToggle\n label=\"System Prompt\"\n templateText={spec.system_prompt_blueprint?.template}\n renderedText={renderedSystem}\n />\n <PromptToggle\n label=\"Prompt\"\n templateText={spec.prompt_blueprint?.template}\n renderedText={renderedUser}\n />\n </>\n );\n}\n\n/**\n * LLMExecutionData is now empty — all data is merged into PipeLLMSection above.\n * Kept as a no-op so the dispatcher doesn't need to change.\n */\nexport function LLMExecutionData(_props: { data: Record<string, unknown> }) {\n return null;\n}\n","import React from \"react\";\nimport type { PipeBlueprintUnion } from \"@graph/types\";\nimport { KV, PromptToggle } from \"./shared\";\n\nexport function PipeImgGenSection({\n blueprint,\n executionData,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeImgGen\" }>;\n executionData?: Record<string, unknown>;\n}) {\n const spec = blueprint.img_gen_prompt_blueprint;\n const resolvedModel = executionData?.resolved_model as string | undefined;\n const renderedPrompt = executionData?.rendered_prompt as string | undefined;\n const renderedNegative = executionData?.rendered_negative_prompt as string | undefined;\n\n return (\n <>\n <KV label=\"Model\" value={resolvedModel || blueprint.img_gen_choice} />\n <PromptToggle\n label=\"Prompt\"\n templateText={spec.prompt_blueprint?.template}\n renderedText={renderedPrompt}\n />\n <PromptToggle\n label=\"Negative Prompt\"\n templateText={spec.negative_prompt_blueprint?.template}\n renderedText={renderedNegative}\n />\n <KV label=\"Aspect Ratio\" value={blueprint.aspect_ratio} />\n <KV label=\"Output Format\" value={blueprint.output_format} />\n <KV label=\"Background\" value={blueprint.background} />\n <KV label=\"Is Raw\" value={blueprint.is_raw} />\n <KV label=\"Seed\" value={blueprint.seed} />\n <KV\n label=\"Images\"\n value={(executionData?.nb_images as number) ?? blueprint.output_multiplicity}\n />\n </>\n );\n}\n\nexport function ImgGenExecutionData(_props: { data: Record<string, unknown> }) {\n return null;\n}\n","import React from \"react\";\nimport type { PipeBlueprintUnion } from \"@graph/types\";\nimport { KV } from \"./shared\";\n\nexport function PipeExtractSection({\n blueprint,\n executionData,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeExtract\" }>;\n executionData?: Record<string, unknown>;\n}) {\n const resolvedModel = executionData?.resolved_model as string | undefined;\n\n return (\n <>\n <KV label=\"Model\" value={resolvedModel || blueprint.extract_choice} />\n <KV label=\"Document Variable\" value={blueprint.document_stuff_name} />\n <KV label=\"Caption Images\" value={blueprint.should_caption_images} />\n <KV label=\"Max Page Images\" value={blueprint.max_page_images} />\n <KV label=\"Include Page Views\" value={blueprint.should_include_page_views} />\n <KV label=\"Page Views DPI\" value={blueprint.page_views_dpi} />\n <KV label=\"Render JS\" value={blueprint.render_js} />\n <KV label=\"Include Raw HTML\" value={blueprint.include_raw_html} />\n <KV label=\"Image Variable\" value={blueprint.image_stuff_name} />\n </>\n );\n}\n\nexport function ExtractExecutionData(_props: { data: Record<string, unknown> }) {\n return null;\n}\n","import React from \"react\";\nimport type { PipeBlueprintUnion } from \"@graph/types\";\nimport { KV, PromptToggle } from \"./shared\";\n\nexport function PipeSearchSection({\n blueprint,\n executionData,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeSearch\" }>;\n executionData?: Record<string, unknown>;\n}) {\n const resolvedModel = executionData?.resolved_model as string | undefined;\n const renderedQuery = executionData?.rendered_query as string | undefined;\n\n return (\n <>\n <KV label=\"Model\" value={resolvedModel || blueprint.search_choice} />\n <PromptToggle\n label=\"Search Query\"\n templateText={blueprint.prompt_blueprint.template}\n renderedText={renderedQuery}\n />\n <KV label=\"Max Results\" value={blueprint.max_results_override} />\n <KV label=\"Include Images\" value={blueprint.include_images_override} />\n <KV label=\"Structured Output\" value={blueprint.is_structured_output} />\n <KV label=\"From Date\" value={blueprint.from_date} />\n <KV label=\"To Date\" value={blueprint.to_date} />\n {blueprint.include_domains && blueprint.include_domains.length > 0 && (\n <KV label=\"Include Domains\" value={blueprint.include_domains.join(\", \")} />\n )}\n {blueprint.exclude_domains && blueprint.exclude_domains.length > 0 && (\n <KV label=\"Exclude Domains\" value={blueprint.exclude_domains.join(\", \")} />\n )}\n </>\n );\n}\n\nexport function SearchExecutionData(_props: { data: Record<string, unknown> }) {\n return null;\n}\n","import React from \"react\";\nimport type {\n FieldResolution,\n PipeBlueprintUnion,\n PipeComposeConstructBlueprint,\n PipeComposeConstructField,\n} from \"@graph/types\";\nimport { KV, PromptToggle } from \"./shared\";\n\n/** Format a non-nested, non-template construct field as a one-line contract string.\n *\n * Design rule: the pipe detail panel shows the **contract** of each field\n * (where it comes from, or what it's hardcoded to) — NOT the runtime data.\n * Runtime data lives in input/output stuff nodes, not on the pipe.\n *\n * - `fixed` → the literal value the pipe authored (it lives in the blueprint)\n * - `from_var` → the dotted path into working memory (the value lives in the input stuff)\n * - `template` → routed to PromptToggle elsewhere; this branch is unreachable\n * - `nested` → never reaches this function; nested fields are rendered by\n * ConstructFieldsBlock recursing into the sub-construct\n */\nfunction formatLeafField(field: PipeComposeConstructField): string {\n switch (field.method) {\n case \"from_var\": {\n const base = `← ${field.from_path ?? \"?\"}`;\n return field.list_to_dict_keyed_by\n ? `${base} (keyed by ${field.list_to_dict_keyed_by})`\n : base;\n }\n case \"fixed\":\n return `= ${JSON.stringify(field.fixed_value)}`;\n case \"nested\":\n // Unreachable: nested fields are routed to recursive rendering. Kept for\n // exhaustiveness over the closed union.\n return \"(nested construct)\";\n case \"template\":\n // Unreachable: template fields are routed to PromptToggle. Kept for\n // exhaustiveness over the closed union.\n return field.template ?? \"(empty template)\";\n }\n}\n\n/** A field's string value is \"long\" when it wraps across multiple lines OR exceeds ~60 chars.\n * Long values get a dedicated text block (label above, value in a bordered scrollable box);\n * short values render inline as a KV row (label left, value right).\n */\nconst LONG_VALUE_THRESHOLD_CHARS = 60;\nfunction isLongValue(text: string): boolean {\n return text.length > LONG_VALUE_THRESHOLD_CHARS || text.includes(\"\\n\");\n}\n\n/** Labeled multi-line text block — used for long fixed-value summaries\n * (e.g. a `fixed = \"<3000 char rationale>\"` field whose JSON-stringified\n * literal won't fit on a single KV row).\n */\nfunction FieldBlock({ label, value }: { label: string; value: string }) {\n return (\n <div className=\"detail-field-block\">\n <div className=\"detail-field-block-label\">{label}</div>\n <div className=\"detail-field-block-value\">{value}</div>\n </div>\n );\n}\n\n/** Recursive renderer for a construct (or sub-construct) at a given indent depth.\n *\n * Splits the field map into:\n * - leafFields: fixed / from_var → render as KV row or FieldBlock\n * - nestedFields: nested → render as a sub-section header + recursive call\n * - templateFields: template → render via PromptToggle\n *\n * The `depth` prop drives left padding so the tree is visually obvious without\n * needing collapse state. Depth 0 has no padding; each level adds 12px.\n */\nfunction ConstructFieldsBlock({\n blueprint,\n depth,\n fieldResolutions,\n}: {\n blueprint: PipeComposeConstructBlueprint;\n depth: number;\n fieldResolutions: Record<string, FieldResolution> | null;\n}) {\n const leafFields: [string, PipeComposeConstructField][] = [];\n const nestedFields: [string, PipeComposeConstructField][] = [];\n const templateFields: [string, PipeComposeConstructField][] = [];\n for (const [name, field] of Object.entries(blueprint.fields)) {\n if (field.method === \"template\") {\n templateFields.push([name, field]);\n } else if (field.method === \"nested\") {\n nestedFields.push([name, field]);\n } else {\n leafFields.push([name, field]);\n }\n }\n\n // Indent all rows at this depth. We use padding-left rather than nested\n // containers so KV rows still align cleanly with their FIELDS section label.\n const indentStyle = depth > 0 ? { paddingLeft: depth * 12 } : undefined;\n\n return (\n <>\n {leafFields.map(([name, field]) => {\n const display = formatLeafField(field);\n if (isLongValue(display)) {\n return (\n <div key={name} style={indentStyle}>\n <FieldBlock label={name} value={display} />\n </div>\n );\n }\n return (\n <div key={name} style={indentStyle}>\n <KV label={name} value={display} />\n </div>\n );\n })}\n\n {templateFields.map(([name, field]) => {\n const renderedForField = fieldResolutions?.[name]?.rendered;\n return (\n <div key={name} style={indentStyle}>\n <PromptToggle\n label={`Template — ${name}`}\n templateText={field.template ?? null}\n renderedText={renderedForField}\n />\n </div>\n );\n })}\n\n {nestedFields.map(([name, field]) => {\n if (!field.nested) return null;\n return (\n <div key={name}>\n <div\n className=\"detail-nested-header\"\n style={depth > 0 ? { paddingLeft: depth * 12 } : undefined}\n >\n <span className=\"detail-nested-header-name\">{name}</span>\n <span className=\"detail-nested-header-meta\">\n nested · {Object.keys(field.nested.fields).length} field\n {Object.keys(field.nested.fields).length === 1 ? \"\" : \"s\"}\n </span>\n </div>\n <ConstructFieldsBlock\n blueprint={field.nested}\n depth={depth + 1}\n fieldResolutions={null}\n />\n </div>\n );\n })}\n </>\n );\n}\n\nexport function PipeComposeSection({\n blueprint,\n executionData,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeCompose\" }>;\n executionData?: Record<string, unknown>;\n}) {\n const renderedText = executionData?.rendered_text as string | undefined;\n const composeMode = executionData?.compose_mode as string | undefined;\n // Per-field record of how each field was built, emitted by\n // PipeCompose._run_construct_mode. Used to surface the rendered Jinja2 text\n // for `template` fields (and recursively for nested constructs). The contract\n // of `fixed` / `from_var` / `nested` fields lives in the blueprint, so the\n // record only carries `rendered` (templates) and `fields` (nested).\n const fieldResolutions = (executionData?.fields ?? null) as Record<\n string,\n FieldResolution\n > | null;\n\n const constructBlueprint = blueprint.construct_blueprint;\n const hasConstruct =\n constructBlueprint !== null && Object.keys(constructBlueprint.fields).length > 0;\n\n return (\n <>\n <KV label=\"Mode\" value={composeMode || (hasConstruct ? \"construct\" : \"template\")} />\n <KV label=\"Category\" value={blueprint.category} />\n <KV label=\"Templating Style\" value={blueprint.templating_style} />\n\n {/* Legacy monolithic template (when construct_blueprint is null) */}\n {blueprint.template && (\n <PromptToggle\n label=\"Template\"\n templateText={blueprint.template}\n renderedText={renderedText}\n />\n )}\n\n {/* Field-level construct form: recursively render the construct blueprint\n tree. Leaf fields (fixed/from_var) render as KV rows or FieldBlocks\n showing their contract (`= literal` or `← path`). Template fields\n render via PromptToggle. Nested sub-constructs render as a header row\n followed by their indented sub-fields. */}\n {hasConstruct && (\n <>\n <div className=\"detail-section-label\">FIELDS</div>\n <ConstructFieldsBlock\n blueprint={constructBlueprint}\n depth={0}\n fieldResolutions={fieldResolutions}\n />\n </>\n )}\n </>\n );\n}\n\nexport function ComposeExecutionData(_props: { data: Record<string, unknown> }) {\n return null;\n}\n","import React from \"react\";\nimport type { PipeBlueprintUnion } from \"@graph/types\";\nimport { KV, PromptBlock } from \"./shared\";\n\nexport function PipeConditionSection({\n blueprint,\n executionData,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeCondition\" }>;\n executionData?: Record<string, unknown>;\n}) {\n const evaluatedExpression = executionData?.evaluated_expression as string | undefined;\n const selectedOutcome = executionData?.selected_outcome as string | undefined;\n\n return (\n <>\n <PromptBlock label=\"Expression\" text={blueprint.expression} />\n {evaluatedExpression && <KV label=\"Expression Result\" value={evaluatedExpression} />}\n <div>\n <div className=\"detail-section-label\">Outcomes</div>\n {Object.entries(blueprint.outcome_map).map(([outcome, pipeCode]) => (\n <div\n key={outcome}\n className=\"detail-kv-row\"\n style={\n selectedOutcome === pipeCode ? { background: \"rgba(80,250,123,0.08)\" } : undefined\n }\n >\n <span className=\"detail-kv-key\">{outcome}</span>\n <span\n className=\"detail-kv-value\"\n style={selectedOutcome === pipeCode ? { color: \"#50FA7B\" } : undefined}\n >\n {pipeCode}\n </span>\n </div>\n ))}\n <div className=\"detail-kv-row\">\n <span className=\"detail-kv-key\">default</span>\n <span className=\"detail-kv-value\">{blueprint.default_outcome}</span>\n </div>\n </div>\n <KV label=\"Alias Expression To\" value={blueprint.add_alias_from_expression_to} />\n </>\n );\n}\n\nexport function ConditionExecutionData(_props: { data: Record<string, unknown> }) {\n return null;\n}\n","import React from \"react\";\nimport type { PipeBlueprintUnion } from \"@graph/types\";\n\nexport function PipeSequenceSection({\n blueprint,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeSequence\" }>;\n executionData?: Record<string, unknown>;\n}) {\n return (\n <div>\n <div className=\"detail-section-label\">Steps</div>\n <div className=\"detail-steps-list\">\n {blueprint.sequential_sub_pipes.map((step, idx) => (\n <div key={idx} className=\"detail-step-item\">\n <span className=\"detail-step-index\">{idx + 1}</span>\n <span className=\"detail-step-code\">{step.pipe_code}</span>\n {step.output_name && (\n <span className=\"detail-io-concept\">-> {step.output_name}</span>\n )}\n </div>\n ))}\n </div>\n </div>\n );\n}\n\nexport function SequenceExecutionData(_props: { data: Record<string, unknown> }) {\n return null;\n}\n","import React from \"react\";\nimport type { PipeBlueprintUnion } from \"@graph/types\";\nimport { KV } from \"./shared\";\n\nexport function PipeParallelSection({\n blueprint,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeParallel\" }>;\n executionData?: Record<string, unknown>;\n}) {\n return (\n <>\n <div>\n <div className=\"detail-section-label\">Branches</div>\n <div className=\"detail-steps-list\">\n {blueprint.parallel_sub_pipes.map((branch, idx) => (\n <div key={idx} className=\"detail-step-item\">\n <span className=\"detail-step-code\">{branch.pipe_code}</span>\n {branch.output_name && (\n <span className=\"detail-io-concept\">-> {branch.output_name}</span>\n )}\n </div>\n ))}\n </div>\n </div>\n <KV label=\"Add Each Output\" value={blueprint.add_each_output} />\n <KV label=\"Combined Output\" value={blueprint.combined_output} />\n </>\n );\n}\n\nexport function ParallelExecutionData(_props: { data: Record<string, unknown> }) {\n return null;\n}\n","import React from \"react\";\nimport type { PipeBlueprintUnion } from \"@graph/types\";\nimport { KV } from \"./shared\";\n\nexport function PipeBatchSection({\n blueprint,\n executionData,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeBatch\" }>;\n executionData?: Record<string, unknown>;\n}) {\n const itemCount = executionData?.item_count as number | undefined;\n\n return (\n <>\n <KV label=\"Branch Pipe\" value={blueprint.branch_pipe_code} />\n <KV label=\"Input List Variable\" value={blueprint.batch_params.input_list_stuff_name} />\n <KV label=\"Input Item Variable\" value={blueprint.batch_params.input_item_stuff_name} />\n {itemCount != null && <KV label=\"Items Processed\" value={itemCount} />}\n </>\n );\n}\n\nexport function BatchExecutionData(_props: { data: Record<string, unknown> }) {\n return null;\n}\n","import React from \"react\";\nimport type { ConceptInfo, GraphSpecNodeIoItem } from \"@graph/types\";\nimport { StuffViewer } from \"../stuff/StuffViewer\";\nimport type { ResolveStorageUrl, StuffViewerData } from \"../stuff/stuffViewerTypes\";\nimport \"./DetailPanel.css\";\n\n// ─── Props ──────────────────────────────────────────────────────────────\n\nexport interface ConceptDetailPanelProps {\n concept: ConceptInfo;\n /** IO data for this concept instance. Accepts GraphSpecNodeIoItem or StuffViewerData. */\n ioData?: GraphSpecNodeIoItem | StuffViewerData;\n /** Whether this is a dry run (schema only, no real data). */\n isDryRun?: boolean;\n /** Resolver for `pipelex-storage://` URIs when rendering media in StuffViewer. */\n resolveStorageUrl?: ResolveStorageUrl;\n /** Forwarded to {@link StuffViewer}. Set `false` when the host can't embed PDFs. */\n canEmbedPdf?: boolean;\n /** Forwarded to {@link StuffViewer}. Overrides default `window.open` behavior. */\n onOpenExternally?: (url: string, filename?: string) => void;\n}\n\n// ─── Component ──────────────────────────────────────────────────────────\n\nexport function ConceptDetailPanel({\n concept,\n ioData,\n isDryRun,\n resolveStorageUrl,\n canEmbedPdf,\n onOpenExternally,\n}: ConceptDetailPanelProps) {\n return (\n <>\n {/* Header */}\n <div className=\"detail-header\">\n <span className=\"detail-concept-code\">{concept.code}</span>\n <span className=\"detail-concept-domain\">{concept.domain_code}</span>\n </div>\n\n {/* Description */}\n {concept.description && <div className=\"detail-description\">{concept.description}</div>}\n\n {/* Refinement chain */}\n {concept.refines && (\n <div className=\"detail-refines\">\n refines <span className=\"detail-refines-code\">{concept.refines}</span>\n </div>\n )}\n\n {/* Structure schema */}\n {concept.json_schema ? (\n <div>\n <div className=\"detail-section-label\">Structure</div>\n <SchemaTable schema={concept.json_schema} isDryRun={isDryRun} />\n </div>\n ) : (\n <div className=\"detail-not-available\">Schema not available</div>\n )}\n\n {/* Instance data (live runs only) */}\n {ioData && !isDryRun && (\n <div>\n <div className=\"detail-section-label\">Data</div>\n <StuffViewer\n stuff={toStuffViewerData(ioData)}\n resolveStorageUrl={resolveStorageUrl}\n canEmbedPdf={canEmbedPdf}\n onOpenExternally={onOpenExternally}\n />\n </div>\n )}\n </>\n );\n}\n\n// ─── Schema table renderer ──────────────────────────────────────────────\n\nfunction SchemaTable({\n schema,\n isDryRun,\n}: {\n schema: Record<string, unknown>;\n isDryRun?: boolean;\n}) {\n const properties = schema.properties as Record<string, Record<string, unknown>> | undefined;\n const required = new Set<string>((schema.required as string[]) ?? []);\n\n if (!properties || Object.keys(properties).length === 0) {\n return <div className=\"detail-not-available\">No fields defined</div>;\n }\n\n const fields = Object.entries(properties);\n // In dry run mode, only show required fields\n const visibleFields = isDryRun ? fields.filter(([name]) => required.has(name)) : fields;\n\n return (\n <table className=\"detail-schema-table\">\n <thead>\n <tr>\n <th>Field</th>\n <th>Type</th>\n <th></th>\n <th>Description</th>\n </tr>\n </thead>\n <tbody>\n {visibleFields.map(([fieldName, fieldSchema]) => (\n <tr key={fieldName}>\n <td className=\"detail-schema-field\">{fieldName}</td>\n <td className=\"detail-schema-type\">{extractType(fieldSchema)}</td>\n <td>\n {required.has(fieldName) && <span className=\"detail-schema-required\">req</span>}\n </td>\n <td>{(fieldSchema.description as string) ?? \"\"}</td>\n </tr>\n ))}\n </tbody>\n </table>\n );\n}\n\nfunction extractType(schema: Record<string, unknown>): string {\n if (schema.type) return String(schema.type);\n if (schema.anyOf) return \"union\";\n if (schema.allOf) return \"all\";\n if (schema.$ref) {\n const ref = String(schema.$ref);\n return ref.split(\"/\").pop() ?? \"ref\";\n }\n return \"unknown\";\n}\n\nfunction toStuffViewerData(ioData: GraphSpecNodeIoItem | StuffViewerData): StuffViewerData {\n // Already a StuffViewerData (has \"digest\" key)\n if (\"digest\" in ioData) return ioData as StuffViewerData;\n // Convert from GraphSpecNodeIoItem\n return {\n digest: (ioData as GraphSpecNodeIoItem).digest ?? \"\",\n name: (ioData as GraphSpecNodeIoItem).name,\n concept: (ioData as GraphSpecNodeIoItem).concept,\n contentType: (ioData as GraphSpecNodeIoItem).content_type,\n data: (ioData as GraphSpecNodeIoItem).data,\n dataText: (ioData as GraphSpecNodeIoItem).data_text,\n dataHtml: (ioData as GraphSpecNodeIoItem).data_html,\n };\n}\n","/**\n * ReactFlow type boundary — \"ports and adapters\" pattern.\n *\n * The pure graph logic (types.ts, graphBuilders, graphLayout, graphControllers)\n * uses domain types: GraphNode, GraphEdge. These are React-free and used for\n * building, layout, analysis, and controller generation.\n *\n * The React layer (this directory) uses ReactFlow's generic types:\n * AppNode = Node<GraphNodeData> — ReactFlow node parameterized with our data\n * AppEdge = Edge<...> — ReactFlow edge with standard fields\n *\n * Boundary mapping functions (toAppNodes, toAppEdges) convert domain types to\n * ReactFlow types at the point where data enters ReactFlow hooks (setNodes/setEdges).\n * All type conversions are localized here — no `as any` casts elsewhere.\n *\n * Why not make GraphNode extend Node<T>?\n * types.ts must stay React-free. GraphNode.style uses Record<string, string | number>\n * (not CSSProperties) and GraphEdge has domain-specific fields (_batchEdge, _crossGroup)\n * that don't belong on ReactFlow's Edge type. The boundary mapping is the clean solution.\n */\nimport type { CSSProperties } from \"react\";\nimport type { Node, Edge, ReactFlowInstance, EdgeMarkerType, Position } from \"@xyflow/react\";\nimport type { GraphNode, GraphEdge, GraphNodeData } from \"../types\";\n\n/** ReactFlow node parameterized with our domain data. */\nexport type AppNode = Node<GraphNodeData>;\n\n/** ReactFlow edge with standard fields (domain-only fields are dropped at the boundary). */\nexport type AppEdge = Edge<Record<string, unknown>>;\n\n/** ReactFlow instance typed with our app node/edge types. */\nexport type AppRFInstance = ReactFlowInstance<AppNode, AppEdge>;\n\n/**\n * Convert domain GraphNode[] to ReactFlow AppNode[].\n *\n * Style fields use Record<string, string | number> in the domain layer but\n * CSSProperties in React. The cast is safe because graph builders only set\n * valid CSS properties (width, height, background, border, etc.).\n */\nexport function toAppNodes(nodes: GraphNode[]): AppNode[] {\n return nodes.map((n) => ({\n id: n.id,\n type: n.type,\n data: n.data,\n position: n.position,\n style: n.style as CSSProperties | undefined,\n sourcePosition: n.sourcePosition as Position | undefined,\n targetPosition: n.targetPosition as Position | undefined,\n parentId: n.parentId,\n extent: n.extent,\n selected: n.selected,\n }));\n}\n\n/**\n * Convert domain GraphEdge[] to ReactFlow AppEdge[].\n *\n * Domain-only fields (_batchEdge, _crossGroup) are dropped — they're only used\n * by pure graph logic (layout weight calculation), not by ReactFlow rendering.\n * The markerEnd cast is safe: our { type: \"arrowclosed\", color } satisfies EdgeMarker.\n */\nexport function toAppEdges(edges: GraphEdge[]): AppEdge[] {\n return edges.map((e) => ({\n id: e.id,\n source: e.source,\n target: e.target,\n type: e.type,\n animated: e.animated,\n label: e.label,\n labelStyle: e.labelStyle as CSSProperties | undefined,\n labelBgStyle: e.labelBgStyle as CSSProperties | undefined,\n labelBgPadding: e.labelBgPadding,\n labelBgBorderRadius: e.labelBgBorderRadius,\n style: e.style as CSSProperties | undefined,\n markerEnd: e.markerEnd as EdgeMarkerType | undefined,\n }));\n}\n","import React from \"react\";\nimport type { LabelDescriptor, GraphNode } from \"@graph/types\";\n\nexport function renderLabel(desc: LabelDescriptor): React.ReactNode {\n if (desc.kind === \"pipe\") {\n return (\n <div\n style={{\n padding: \"10px 14px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"2px\",\n textAlign: \"center\",\n width: \"100%\",\n boxSizing: \"border-box\",\n minWidth: 0,\n }}\n title={desc.label}\n >\n <span\n style={{\n fontFamily: \"var(--font-mono)\",\n fontSize: \"13px\",\n fontWeight: 600,\n color: \"var(--color-pipe-text)\",\n maxWidth: \"100%\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {desc.label}\n </span>\n </div>\n );\n }\n\n // desc.kind === \"stuff\"\n // width: 100% + min-width: 0 lets the flex children's overflow/ellipsis\n // actually kick in — without it, the spans would stretch the parent instead.\n return (\n <div\n style={{\n padding: \"8px 24px\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"2px\",\n textAlign: \"center\",\n width: \"100%\",\n boxSizing: \"border-box\",\n minWidth: 0,\n }}\n title={desc.concept ? `${desc.label}: ${desc.concept}` : desc.label}\n >\n <span\n style={{\n fontFamily: \"var(--font-mono)\",\n fontSize: \"12px\",\n fontWeight: 600,\n color: \"var(--color-stuff-text)\",\n maxWidth: \"100%\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {desc.label}\n </span>\n {desc.concept && (\n <span\n style={{\n fontSize: \"14px\",\n color: \"var(--color-stuff-text-dim)\",\n maxWidth: \"100%\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {desc.concept}\n </span>\n )}\n </div>\n );\n}\n\n/** Convert label descriptors to React elements on all nodes */\nexport function hydrateLabels(nodes: GraphNode[]): GraphNode[] {\n return nodes.map((n) => {\n if (!n.data.labelDescriptor) return n;\n return {\n ...n,\n data: {\n ...n.data,\n label: renderLabel(n.data.labelDescriptor),\n },\n };\n });\n}\n","import React from \"react\";\nimport \"./GraphToolbar.css\";\nimport { GRAPH_DIRECTION, type GraphDirection } from \"@graph/types\";\n\nexport interface GraphToolbarProps {\n direction: GraphDirection;\n onDirectionChange: (direction: GraphDirection) => void;\n showControllers: boolean;\n onShowControllersChange: (showControllers: boolean) => void;\n onZoomIn?: () => void;\n onZoomOut?: () => void;\n onFitView?: () => void;\n /** Pixel offset from the right edge (e.g. detail panel width when open). */\n rightOffset?: number;\n}\n\nconst ARROW_RIGHT_ICON = (\n <svg\n viewBox=\"0 0 24 24\"\n width=\"14\"\n height=\"14\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n <polyline points=\"12 5 19 12 12 19\" />\n </svg>\n);\n\nconst ARROW_DOWN_ICON = (\n <svg\n viewBox=\"0 0 24 24\"\n width=\"14\"\n height=\"14\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <polyline points=\"19 12 12 19 5 12\" />\n </svg>\n);\n\nconst MINUS_ICON = (\n <svg\n viewBox=\"0 0 24 24\"\n width=\"14\"\n height=\"14\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n);\n\nconst PLUS_ICON = (\n <svg\n viewBox=\"0 0 24 24\"\n width=\"14\"\n height=\"14\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n);\n\nconst FIT_VIEW_ICON = (\n <svg\n viewBox=\"0 0 24 24\"\n width=\"14\"\n height=\"14\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"15 3 21 3 21 9\" />\n <polyline points=\"9 21 3 21 3 15\" />\n <line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\" />\n <line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\" />\n </svg>\n);\n\nconst BOXES_ICON = (\n <svg\n viewBox=\"0 0 24 24\"\n width=\"14\"\n height=\"14\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z\" />\n <path d=\"m7 16.5-4.74-2.85\" />\n <path d=\"m7 16.5 5-3\" />\n <path d=\"M7 16.5v5.17\" />\n <path d=\"M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z\" />\n <path d=\"m17 16.5-5-3\" />\n <path d=\"m17 16.5 4.74-2.85\" />\n <path d=\"M17 16.5v5.17\" />\n <path d=\"M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z\" />\n <path d=\"M12 8 7.26 5.15\" />\n <path d=\"m12 8 4.74-2.85\" />\n <path d=\"M12 13.5V8\" />\n </svg>\n);\n\nexport function GraphToolbar({\n direction,\n onDirectionChange,\n showControllers,\n onShowControllersChange,\n onZoomIn,\n onZoomOut,\n onFitView,\n rightOffset = 0,\n}: GraphToolbarProps) {\n const isVertical = direction === GRAPH_DIRECTION.TB || direction === GRAPH_DIRECTION.BT;\n const directionLabel = isVertical ? \"Switch to horizontal layout\" : \"Switch to vertical layout\";\n const controllersLabel = showControllers\n ? \"Hide pipe controllers\"\n : \"Show pipe controllers — groups pipes by their controlling pipe\";\n\n return (\n <div className=\"graph-toolbar\" style={{ right: `${rightOffset + 8}px` }}>\n <button\n type=\"button\"\n className=\"graph-toolbar-btn\"\n onClick={() => onDirectionChange(isVertical ? GRAPH_DIRECTION.LR : GRAPH_DIRECTION.TB)}\n title={directionLabel}\n aria-label={directionLabel}\n >\n {isVertical ? ARROW_RIGHT_ICON : ARROW_DOWN_ICON}\n </button>\n\n <button\n type=\"button\"\n className={`graph-toolbar-btn${showControllers ? \" graph-toolbar-btn--active\" : \"\"}`}\n onClick={() => onShowControllersChange(!showControllers)}\n title={controllersLabel}\n aria-label={controllersLabel}\n >\n {BOXES_ICON}\n </button>\n\n {(onZoomOut || onZoomIn || onFitView) && <div className=\"graph-toolbar-separator\" />}\n\n {onZoomOut && (\n <button\n type=\"button\"\n className=\"graph-toolbar-btn\"\n onClick={onZoomOut}\n title=\"Zoom out\"\n aria-label=\"Zoom out\"\n >\n {MINUS_ICON}\n </button>\n )}\n\n {onZoomIn && (\n <button\n type=\"button\"\n className=\"graph-toolbar-btn\"\n onClick={onZoomIn}\n title=\"Zoom in\"\n aria-label=\"Zoom in\"\n >\n {PLUS_ICON}\n </button>\n )}\n\n {onFitView && (\n <button\n type=\"button\"\n className=\"graph-toolbar-btn\"\n onClick={onFitView}\n title=\"Fit view\"\n aria-label=\"Fit view\"\n >\n {FIT_VIEW_ICON}\n </button>\n )}\n </div>\n );\n}\n","import React from \"react\";\nimport type { PipeControllerType } from \"@graph/types\";\nimport { MAX_VISIBLE_CONTROLLER_CHILDREN } from \"@graph/graphControllers\";\n\ninterface ControllerGroupData {\n label?: React.ReactNode;\n pipeType?: PipeControllerType;\n childCount?: number;\n isCollapsed?: boolean;\n onToggleCollapse?: () => void;\n}\n\nconst CONTROLLER_CONFIG: Record<PipeControllerType, { badge: string; icon: string }> = {\n PipeSequence: { badge: \"Sequence\", icon: \"→\" },\n PipeParallel: { badge: \"Parallel\", icon: \"//\" },\n PipeCondition: { badge: \"Condition\", icon: \"◇\" },\n PipeBatch: { badge: \"Batch\", icon: \"≡\" },\n};\n\nfunction getControllerConfig(pipeType: PipeControllerType | undefined) {\n if (!pipeType) return { badge: \"\", icon: \"\" };\n return CONTROLLER_CONFIG[pipeType];\n}\n\nfunction getControllerModifier(pipeType: PipeControllerType | undefined): string {\n if (!pipeType) return \"\";\n const key = pipeType.replace(\"Pipe\", \"\").toLowerCase();\n return `controller-group--${key}`;\n}\n\nexport function ControllerGroupNode({ data }: { data: ControllerGroupData }) {\n const config = getControllerConfig(data.pipeType);\n const modifier = getControllerModifier(data.pipeType);\n\n const isCollapsible =\n (data.pipeType === \"PipeParallel\" || data.pipeType === \"PipeBatch\") &&\n (data.childCount ?? 0) > MAX_VISIBLE_CONTROLLER_CHILDREN;\n\n const hiddenCount = isCollapsible ? (data.childCount ?? 0) - MAX_VISIBLE_CONTROLLER_CHILDREN : 0;\n\n return (\n <div className={`controller-group-node ${modifier}`}>\n <div className=\"controller-group-header\">\n <span className=\"controller-group-icon\">{config.icon}</span>\n <span className=\"controller-group-badge\">{config.badge}</span>\n {data.label && <span className=\"controller-group-label\">{data.label}</span>}\n </div>\n {isCollapsible && (\n <button\n className=\"controller-group-collapse\"\n onClick={(e) => {\n e.stopPropagation();\n data.onToggleCollapse?.();\n }}\n >\n {data.isCollapsed ? `+${hiddenCount} hidden` : \"collapse\"}\n </button>\n )}\n </div>\n );\n}\n\n// Stable reference to avoid ReactFlow re-mount warnings\nexport const controllerNodeTypes = { controllerGroup: ControllerGroupNode };\n","import React from \"react\";\nimport { Handle, Position } from \"@xyflow/react\";\nimport type { PipeCardData } from \"./pipeCardTypes\";\nimport { getPipeCardComponent } from \"./pipeCardRegistry\";\nimport { PipeCardBase } from \"./PipeCardBase\";\n\nexport interface PipeCardNodeProps {\n data: PipeCardData;\n}\n\n/** Resolves the correct card component for the pipe type and renders it. */\nexport function PipeCardNode({ data }: PipeCardNodeProps) {\n const Card = getPipeCardComponent(data.pipeType) ?? PipeCardBase;\n return <Card data={data} />;\n}\n\n/**\n * ReactFlow custom node wrapper.\n *\n * Renders source/target handles using the positions set by the layout engine\n * (TB → top/bottom, LR → left/right, etc.).\n */\nexport function PipeCardRFNode({\n data,\n sourcePosition = Position.Bottom,\n targetPosition = Position.Top,\n}: {\n data: Record<string, unknown>;\n sourcePosition?: Position;\n targetPosition?: Position;\n}) {\n const payload = data.pipeCardData as PipeCardData | undefined;\n if (!payload) return null;\n return (\n <>\n <Handle type=\"target\" position={targetPosition} />\n <PipeCardNode data={payload} />\n <Handle type=\"source\" position={sourcePosition} />\n </>\n );\n}\n","import React, { useState } from \"react\";\nimport type { PipeCardData, PipeOperatorType, PipeStatus } from \"./pipeCardTypes\";\n\n// ─── Pipe type badge labels ──────────────────────────────────────────────\n\nconst PIPE_TYPE_BADGES: Record<PipeOperatorType, string> = {\n PipeLLM: \"LLM\",\n PipeExtract: \"Extract\",\n PipeCompose: \"Compose\",\n PipeImgGen: \"ImgGen\",\n PipeSearch: \"Search\",\n PipeFunc: \"Func\",\n};\n\nconst STATUS_CONFIG: Record<PipeStatus, { color: string; label: string }> = {\n succeeded: { color: \"#50FA7B\", label: \"Succeeded\" },\n failed: { color: \"#FF5555\", label: \"Failed\" },\n running: { color: \"#8BE9FD\", label: \"Running\" },\n scheduled: { color: \"#6272a4\", label: \"Scheduled\" },\n skipped: { color: \"#6272a4\", label: \"Skipped\" },\n};\n\nconst MAX_VISIBLE_INPUTS = 4;\n\nfunction getBadge(pipeType: PipeOperatorType): string {\n return PIPE_TYPE_BADGES[pipeType];\n}\n\n// ─── PipeCardBase — shared card rendering for all pipe types ─────────────\n\nexport interface PipeCardBaseProps {\n data: PipeCardData;\n /** Extra content rendered below the I/O section (for per-type customization) */\n children?: React.ReactNode;\n}\n\nexport function PipeCardBase({ data, children }: PipeCardBaseProps) {\n const badge = getBadge(data.pipeType);\n const statusConfig = STATUS_CONFIG[data.status] ?? STATUS_CONFIG.scheduled;\n const isRunning = data.status === \"running\";\n const [inputsExpanded, setInputsExpanded] = useState(false);\n\n const hasMany = data.inputs.length > MAX_VISIBLE_INPUTS;\n const visibleInputs =\n hasMany && !inputsExpanded ? data.inputs.slice(0, MAX_VISIBLE_INPUTS) : data.inputs;\n const hiddenCount = data.inputs.length - MAX_VISIBLE_INPUTS;\n\n const dirClass = data.direction === \"TB\" ? \"pipe-card--tb\" : \"pipe-card--lr\";\n\n return (\n <div className={`pipe-card ${dirClass}`}>\n {/* Header: badge + pipe code + status */}\n <div className=\"pipe-card-header\">\n <span className=\"pipe-card-badge\">{badge}</span>\n <span className=\"pipe-card-code\" title={data.pipeCode}>\n {data.pipeCode}\n </span>\n <span\n className=\"pipe-card-status\"\n style={{ color: statusConfig.color }}\n title={statusConfig.label}\n >\n <span\n className={`pipe-card-status-dot ${isRunning ? \"pipe-card-status-dot--pulse\" : \"\"}`}\n style={{ background: statusConfig.color }}\n />\n </span>\n </div>\n\n {/* Description — clamped via CSS */}\n {data.description && (\n <span className=\"pipe-card-description\" title={data.description}>\n {data.description}\n </span>\n )}\n\n {/* Inputs */}\n {data.inputs.length > 0 && (\n <div className=\"pipe-card-io\">\n <span className=\"pipe-card-io-label\">INPUTS</span>\n <div className=\"pipe-card-io-pills\">\n {visibleInputs.map((input) => (\n <span\n key={input.name}\n className=\"pipe-card-io-pill\"\n title={`${input.name}: ${input.concept}`}\n >\n <span className=\"pipe-card-io-pill-name\">{input.name}</span>\n <span className=\"pipe-card-io-pill-concept\">{input.concept}</span>\n </span>\n ))}\n {hasMany && (\n <button\n className=\"pipe-card-io-more\"\n onClick={(e) => {\n e.stopPropagation();\n setInputsExpanded((v) => !v);\n }}\n >\n {inputsExpanded ? \"show less\" : `+${hiddenCount} more`}\n </button>\n )}\n </div>\n </div>\n )}\n\n {/* Outputs */}\n {data.outputs.length > 0 && (\n <div className=\"pipe-card-io\">\n <span className=\"pipe-card-io-label\">OUTPUT</span>\n <div className=\"pipe-card-io-pills\">\n {data.outputs.map((output) => (\n <span\n key={output.name}\n className=\"pipe-card-io-pill\"\n title={`${output.name}: ${output.concept}`}\n >\n <span className=\"pipe-card-io-pill-name\">{output.name}</span>\n <span className=\"pipe-card-io-pill-concept\">{output.concept}</span>\n </span>\n ))}\n </div>\n </div>\n )}\n\n {/* Per-type extra content slot */}\n {children}\n </div>\n );\n}\n","import type { ComponentType } from \"react\";\nimport type { PipeOperatorType } from \"./pipeCardTypes\";\nimport type { PipeCardBaseProps } from \"./PipeCardBase\";\nimport { PipeCardBase } from \"./PipeCardBase\";\n\n/**\n * Registry mapping pipe operator type → card component.\n *\n * All types use PipeCardBase for now. To customize a specific type later,\n * create a wrapper component (e.g. PipeLLMCard) that composes PipeCardBase\n * with extra sections, then register it here.\n */\nconst PIPE_CARD_REGISTRY: Record<PipeOperatorType, ComponentType<PipeCardBaseProps>> = {\n PipeLLM: PipeCardBase,\n PipeExtract: PipeCardBase,\n PipeCompose: PipeCardBase,\n PipeImgGen: PipeCardBase,\n PipeSearch: PipeCardBase,\n PipeFunc: PipeCardBase,\n};\n\nexport function getPipeCardComponent(pipeType: PipeOperatorType): ComponentType<PipeCardBaseProps> {\n return PIPE_CARD_REGISTRY[pipeType];\n}\n"],"mappings":"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","names":["React","React","jsx","jsxs","React","React","React","jsx","jsxs","jsx","jsxs","Fragment","jsx","jsxs","Fragment","jsx","jsxs","Fragment","jsx","jsxs","Fragment","jsx","jsxs","Fragment","jsx","jsxs","jsx","jsxs","Fragment","jsx","jsxs","Fragment","jsx","jsxs","Fragment","jsx","jsxs","React","_a","_b","Fragment","jsx","jsxs","_a","jsx","jsxs","jsx","jsxs","jsx","jsxs","_a","useState","jsx","jsxs","PIPE_TYPE_BADGES","Fragment","jsx","jsxs","Fragment","jsx","jsxs","React"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/graph/react/index.ts","../../../src/graph/react/viewer/GraphViewer.tsx","../../../src/graph/react/stuff/stuffViewerUtils.ts","../../../src/graph/react/stuff/StuffViewer.tsx","../../../src/graph/react/detail/DetailPanel.tsx","../../../src/graph/react/detail/useResizable.ts","../../../src/graph/react/detail/PipeDetailPanel.tsx","../../../src/graph/react/detail/sections/shared.tsx","../../../src/graph/react/detail/sections/PipeLLMDetail.tsx","../../../src/graph/react/detail/sections/PipeImgGenDetail.tsx","../../../src/graph/react/detail/sections/PipeExtractDetail.tsx","../../../src/graph/react/detail/sections/PipeSearchDetail.tsx","../../../src/graph/react/detail/sections/PipeComposeDetail.tsx","../../../src/graph/react/detail/sections/PipeConditionDetail.tsx","../../../src/graph/react/detail/sections/PipeSequenceDetail.tsx","../../../src/graph/react/detail/sections/PipeParallelDetail.tsx","../../../src/graph/react/detail/sections/PipeBatchDetail.tsx","../../../src/graph/react/detail/ConceptDetailPanel.tsx","../../../src/graph/react/rfTypes.ts","../../../src/graph/react/viewer/renderLabel.tsx","../../../src/graph/react/viewer/GraphToolbar.tsx","../../../src/graph/react/nodes/controller/ControllerGroupNode.tsx","../../../src/graph/react/nodes/pipe/PipeCardNode.tsx","../../../src/graph/react/nodes/pipe/PipeCardBase.tsx","../../../src/graph/react/nodes/pipe/pipeCardRegistry.ts"],"sourcesContent":["\"use client\";\n\nimport \"./graph-core.css\";\nimport \"./detail/DetailPanel.css\";\nimport \"./stuff/StuffViewer.css\";\nimport \"./viewer/GraphToolbar.css\";\n\n// Viewer\nexport { GraphViewer, applyStatusOverrides } from \"./viewer/GraphViewer\";\nexport type { GraphViewerProps } from \"./viewer/GraphViewer\";\nexport { renderLabel, hydrateLabels } from \"./viewer/renderLabel\";\n\n// ReactFlow type bridge\nexport type { AppNode, AppEdge, AppRFInstance } from \"./rfTypes\";\nexport { toAppNodes, toAppEdges } from \"./rfTypes\";\n\n// Node types\nexport { ControllerGroupNode, controllerNodeTypes } from \"./nodes/controller/ControllerGroupNode\";\nexport { PipeCardNode } from \"./nodes/pipe/PipeCardNode\";\nexport { PipeCardBase } from \"./nodes/pipe/PipeCardBase\";\nexport type { PipeCardBaseProps } from \"./nodes/pipe/PipeCardBase\";\nexport type { PipeCardData, PipeOperatorType, PipeStatus } from \"./nodes/pipe/pipeCardTypes\";\n\n// Stuff viewer\nexport * from \"./stuff\";\n\n// Detail panel\nexport * from \"./detail\";\n","import React from \"react\";\nimport {\n ReactFlow,\n useNodesState,\n useEdgesState,\n Background,\n BackgroundVariant,\n} from \"@xyflow/react\";\n\nimport type {\n GraphSpec,\n GraphConfig,\n GraphDirection,\n GraphNode,\n GraphEdge,\n GraphNodeData,\n DataflowAnalysis,\n FoldMode,\n FoldToggleOptions,\n PipeStatus,\n ConceptInfo,\n} from \"@graph/types\";\nimport { stuffDigestFromId, EDGE_TYPE, FOLD_MODE, GRAPH_DIRECTION } from \"@graph/types\";\nimport { resolveConceptRef } from \"@graph/graphAnalysis\";\nimport type { ResolveStorageUrl, StuffViewerData } from \"../stuff/stuffViewerTypes\";\nimport { findStuffDataByDigest } from \"../stuff/stuffViewerUtils\";\nimport { StuffViewer } from \"../stuff/StuffViewer\";\nimport { DetailPanel } from \"../detail/DetailPanel\";\nimport { useResizable } from \"../detail/useResizable\";\nimport { PipeDetailPanel } from \"../detail/PipeDetailPanel\";\nimport { ConceptDetailPanel } from \"../detail/ConceptDetailPanel\";\nimport type { AppNode, AppEdge, AppRFInstance } from \"../rfTypes\";\nimport { toAppNodes, toAppEdges } from \"../rfTypes\";\nimport { buildGraph } from \"@graph/graphBuilders\";\nimport { applyFolds, findCousinControllers } from \"@graph/graphFolds\";\nimport { getLayoutedElements } from \"@graph/graphLayout\";\nimport { applyControllers } from \"@graph/graphControllers\";\nimport { DEFAULT_GRAPH_CONFIG } from \"@graph/graphConfig\";\nimport { hydrateLabels } from \"./renderLabel\";\nimport { GraphToolbar } from \"./GraphToolbar\";\nimport { controllerNodeTypes } from \"../nodes/controller/ControllerGroupNode\";\nimport { PipeCardRFNode } from \"../nodes/pipe/PipeCardNode\";\n\n// Stable reference — must be declared outside the component to avoid ReactFlow re-mounts\nconst nodeTypes = {\n ...controllerNodeTypes,\n pipeCard: PipeCardRFNode,\n};\n\nexport interface GraphViewerProps {\n graphspec: GraphSpec | null;\n config?: GraphConfig;\n /** Initial layout direction. Users can toggle this via the built-in toolbar. */\n initialDirection?: GraphDirection;\n /** Initial controller-grouping state. Users can toggle this via the built-in toolbar. */\n initialShowControllers?: boolean;\n /**\n * Initial fold state applied once per graphspec. `\"folded\"` collapses every\n * controller into a pipe card on first render; `\"expanded\"` leaves them all\n * as group wrappers; `\"auto\"` is reserved for future heuristics and currently\n * behaves like `\"expanded\"`. Users can still fold/unfold individually via the\n * built-in toolbar afterwards.\n */\n initialFoldMode?: FoldMode;\n /** Hide the built-in floating toolbar (direction + controllers toggle). */\n hideToolbar?: boolean;\n onNavigateToPipe?: (pipeCode: string, status?: PipeStatus) => void;\n onStuffNodeClick?: (stuffData: StuffViewerData) => void;\n onReactFlowInit?: (instance: AppRFInstance) => void;\n /** Layer 2 execution state: pipe_code → current status. Updates node status dots in real-time. */\n statusMap?: Record<string, PipeStatus>;\n /** Called when any node is clicked with full node data. Use for detail/inspector panels. */\n onNodeSelect?: (nodeId: string, nodeData: GraphNodeData, event: React.MouseEvent) => void;\n /** Called when the graph background (pane) is clicked. Use to dismiss detail panels. */\n onPaneClick?: () => void;\n /** Render extra content below the built-in detail panel content for the selected node. */\n renderDetailExtra?: (nodeId: string, nodeData: GraphNodeData) => React.ReactNode;\n /**\n * Resolver for `pipelex-storage://` URIs. Passed down to StuffViewer so it can\n * exchange internal URIs for browser-fetchable presigned URLs when rendering media.\n */\n resolveStorageUrl?: ResolveStorageUrl;\n /**\n * Set to `false` when the host cannot render `<embed type=\"application/pdf\">`\n * — e.g. VS Code webviews, which run inside Electron without the Chromium\n * PDFium plugin. Forwarded to StuffViewer.\n *\n * Default: `true`.\n */\n canEmbedPdf?: boolean;\n /**\n * Replaces the default `window.open(url, \"_blank\")` behavior used by the\n * StuffViewer toolbar and the PDF fallback tile. Wire this to your host's\n * external-open mechanism (e.g. `vscode.env.openExternal` via postMessage).\n */\n onOpenExternally?: (url: string, filename?: string) => void;\n}\n\n/** Stuff node detail: concept structure + data viewer. */\nfunction StuffNodeDetail({\n stuffData,\n graphspec,\n resolveStorageUrl,\n canEmbedPdf,\n onOpenExternally,\n}: {\n stuffData: StuffViewerData;\n graphspec: GraphSpec | null;\n resolveStorageUrl?: ResolveStorageUrl;\n canEmbedPdf?: boolean;\n onOpenExternally?: (url: string, filename?: string) => void;\n}) {\n const conceptInfo =\n stuffData.concept && graphspec ? resolveConceptRef(graphspec, stuffData.concept) : undefined;\n\n return (\n <>\n {/* Concept structure (header + schema table) */}\n {conceptInfo ? (\n <ConceptDetailPanel\n concept={conceptInfo}\n ioData={stuffData}\n resolveStorageUrl={resolveStorageUrl}\n canEmbedPdf={canEmbedPdf}\n onOpenExternally={onOpenExternally}\n />\n ) : (\n /* Fallback: just show the StuffViewer if no concept info */\n <StuffViewer\n stuff={stuffData}\n resolveStorageUrl={resolveStorageUrl}\n canEmbedPdf={canEmbedPdf}\n onOpenExternally={onOpenExternally}\n />\n )}\n </>\n );\n}\n\n/**\n * Translate a fold mode + the set of available controller IDs into an initial\n * `foldedControllers` Set. `\"auto\"` is reserved for a future renderer-defined\n * heuristic and currently behaves like `\"expanded\"`.\n */\nfunction seedFoldedControllers(mode: FoldMode, controllerIds: ReadonlySet<string>): Set<string> {\n if (mode === FOLD_MODE.FOLDED) return new Set(controllerIds);\n return new Set();\n}\n\nfunction cloneCachedNodes(nodes: GraphNode[]): GraphNode[] {\n return nodes.map((n) => ({\n ...n,\n position: { ...n.position },\n data: { ...n.data },\n style: n.style ? { ...n.style } : undefined,\n }));\n}\n\n/** Apply Layer 2 execution state overrides to rendered nodes. */\nexport function applyStatusOverrides(\n nodes: AppNode[],\n statusMap: Record<string, PipeStatus> | undefined,\n): AppNode[] {\n if (!statusMap || Object.keys(statusMap).length === 0) return nodes;\n return nodes.map((node) => {\n const pipeCode = node.data.pipeCode;\n if (!pipeCode || !Object.hasOwn(statusMap, pipeCode)) return node;\n const newStatus = statusMap[pipeCode];\n if (node.data.pipeCardData?.status === newStatus) return node;\n return {\n ...node,\n data: {\n ...node.data,\n nodeData: node.data.nodeData\n ? { ...node.data.nodeData, status: newStatus }\n : node.data.nodeData,\n pipeCardData: node.data.pipeCardData\n ? { ...node.data.pipeCardData, status: newStatus }\n : node.data.pipeCardData,\n },\n };\n });\n}\n\n// ─── Detail panel selection state ──────────────────────────────────────\n\ninterface DetailSelection {\n kind: \"pipe\" | \"stuff\" | \"concept\";\n nodeId: string;\n nodeData: GraphNodeData;\n conceptInfo?: ConceptInfo;\n stuffData?: StuffViewerData;\n}\n\nexport function GraphViewer(props: GraphViewerProps) {\n const {\n graphspec,\n config = DEFAULT_GRAPH_CONFIG,\n initialDirection,\n initialShowControllers,\n initialFoldMode,\n hideToolbar = false,\n onNavigateToPipe,\n onStuffNodeClick,\n onReactFlowInit,\n statusMap,\n onNodeSelect,\n onPaneClick,\n renderDetailExtra,\n resolveStorageUrl,\n canEmbedPdf,\n onOpenExternally,\n } = props;\n\n const [direction, setDirection] = React.useState<GraphDirection>(\n () =>\n initialDirection ?? config.direction ?? DEFAULT_GRAPH_CONFIG.direction ?? GRAPH_DIRECTION.TB,\n );\n const [showControllers, setShowControllers] = React.useState<boolean>(\n () =>\n initialShowControllers ??\n config.showControllers ??\n DEFAULT_GRAPH_CONFIG.showControllers ??\n false,\n );\n\n const effectiveFoldMode: FoldMode =\n initialFoldMode ?? config.foldMode ?? DEFAULT_GRAPH_CONFIG.foldMode ?? FOLD_MODE.EXPANDED;\n const foldModeRef = React.useRef(effectiveFoldMode);\n foldModeRef.current = effectiveFoldMode;\n\n const containerRef = React.useRef<HTMLDivElement>(null);\n\n // Detail panel state (built-in)\n const [detailSelection, setDetailSelection] = React.useState<DetailSelection | null>(null);\n const [conceptOverride, setConceptOverride] = React.useState<ConceptInfo | null>(null);\n\n // Panel resize\n const {\n width: panelWidth,\n isDragging: isPanelDragging,\n handleMouseDown: onResizeMouseDown,\n } = useResizable({ defaultWidth: 380, minWidth: 280, maxWidth: 800, containerRef });\n\n // Reset detail panel when graphspec changes\n React.useEffect(() => {\n setDetailSelection(null);\n setConceptOverride(null);\n }, [graphspec]);\n\n // Apply palette CSS vars to the container (scoped, auto-cleaned on unmount)\n React.useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n const palette = config.paletteColors ?? DEFAULT_GRAPH_CONFIG.paletteColors;\n if (!palette) return;\n\n for (const [cssVar, value] of Object.entries(palette)) {\n el.style.setProperty(cssVar, value);\n }\n\n return () => {\n for (const cssVar of Object.keys(palette)) {\n el.style.removeProperty(cssVar);\n }\n };\n }, [config.paletteColors]);\n\n const [nodes, setNodes, onNodesChange] = useNodesState<AppNode>([]);\n const [edges, setEdges, onEdgesChange] = useEdgesState<AppEdge>([]);\n const reactFlowRef = React.useRef<AppRFInstance | null>(null);\n const initialDataRef = React.useRef<{\n nodes: GraphNode[];\n edges: GraphEdge[];\n _analysis: DataflowAnalysis | null;\n _graphspec: GraphSpec | null;\n } | null>(null);\n /** Un-folded build output, cached so fold-state changes can re-derive without rebuilding. */\n const rawGraphDataRef = React.useRef<{\n nodes: GraphNode[];\n edges: GraphEdge[];\n analysis: DataflowAnalysis | null;\n graphspec: GraphSpec | null;\n } | null>(null);\n const layoutCacheRef = React.useRef<{\n nodes: GraphNode[];\n edges: GraphEdge[];\n controllerPositions?: Record<string, { x: number; y: number; width: number; height: number }>;\n } | null>(null);\n\n // Collapse state: tracks which controllers the user explicitly expanded.\n // Parallel/Batch with >5 children are collapsed by default.\n const [expandedControllers, setExpandedControllers] = React.useState<Set<string>>(new Set());\n\n const toggleCollapse = React.useCallback((controllerId: string) => {\n setExpandedControllers((prev) => {\n const next = new Set(prev);\n if (next.has(controllerId)) next.delete(controllerId);\n else next.add(controllerId);\n return next;\n });\n }, []);\n\n // Fold state: tracks which controllers the user has folded into pipe cards.\n // Empty by default. Reset when graphspec changes.\n const [foldedControllers, setFoldedControllers] = React.useState<Set<string>>(new Set());\n\n const toggleFold = React.useCallback((controllerId: string, options?: FoldToggleOptions) => {\n setFoldedControllers((prev) => {\n const next = new Set(prev);\n const shouldFold = !next.has(controllerId);\n\n // Solo mode (alt/option click) → only the clicked controller.\n // Default → mirror to cousins (controllers sharing the same pipe_code).\n const raw = rawGraphDataRef.current;\n const targets =\n !options?.soloMode && raw?.graphspec && raw.analysis\n ? findCousinControllers(controllerId, raw.graphspec, raw.analysis.controllerNodeIds)\n : new Set<string>([controllerId]);\n\n for (const id of targets) {\n if (shouldFold) next.add(id);\n else next.delete(id);\n }\n return next;\n });\n }, []);\n\n const edgeType = config.edgeType || EDGE_TYPE.DEFAULT;\n const layoutConfig = React.useMemo(\n () => ({ nodesep: config.nodesep, ranksep: config.ranksep }),\n [config.nodesep, config.ranksep],\n );\n\n const showControllersRef = React.useRef(showControllers);\n showControllersRef.current = showControllers;\n const directionRef = React.useRef(direction);\n directionRef.current = direction;\n const layoutConfigRef = React.useRef(layoutConfig);\n layoutConfigRef.current = layoutConfig;\n const initialZoomRef = React.useRef(config.initialZoom);\n initialZoomRef.current = config.initialZoom;\n const panToTopRef = React.useRef(config.panToTop);\n panToTopRef.current = config.panToTop;\n const expandedRef = React.useRef(expandedControllers);\n expandedRef.current = expandedControllers;\n const toggleCollapseRef = React.useRef(toggleCollapse);\n toggleCollapseRef.current = toggleCollapse;\n const foldedRef = React.useRef(foldedControllers);\n foldedRef.current = foldedControllers;\n const toggleFoldRef = React.useRef(toggleFold);\n toggleFoldRef.current = toggleFold;\n // Fold-effect bookkeeping refs. The graphspec effect writes to\n // `skipNextFoldEffectRef`/`prevFoldSizeRef` before the fold-state effect\n // reads them, so they must exist before either effect runs — declare them\n // alongside the other fold-related refs rather than next to the consumer.\n const isFirstFoldEffect = React.useRef(true);\n const prevFoldSizeRef = React.useRef(0);\n const skipNextFoldEffectRef = React.useRef(false);\n const statusMapRef = React.useRef(statusMap);\n statusMapRef.current = statusMap;\n\n // Re-layout when direction or layout config changes\n React.useEffect(() => {\n if (!initialDataRef.current) return;\n let cancelled = false;\n\n (async () => {\n try {\n const data = initialDataRef.current;\n if (!data) return;\n const relayouted = await getLayoutedElements(\n data.nodes,\n data.edges,\n direction,\n layoutConfig,\n data._graphspec,\n data._analysis,\n );\n if (cancelled) return;\n layoutCacheRef.current = {\n nodes: relayouted.nodes,\n edges: relayouted.edges,\n controllerPositions: relayouted.controllerPositions,\n };\n const withControllers = applyControllers(\n cloneCachedNodes(relayouted.nodes),\n relayouted.edges,\n data._graphspec,\n data._analysis,\n showControllersRef.current,\n expandedRef.current,\n toggleCollapseRef.current,\n relayouted.controllerPositions,\n toggleFoldRef.current,\n );\n setNodes(\n applyStatusOverrides(\n toAppNodes(hydrateLabels(withControllers.nodes)),\n statusMapRef.current,\n ),\n );\n setEdges(toAppEdges(withControllers.edges));\n setTimeout(() => {\n if (!cancelled && reactFlowRef.current) {\n reactFlowRef.current.fitView({ padding: 0.1 });\n }\n }, 50);\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error(\"[GraphViewer] ELK layout failed:\", err);\n }\n })();\n\n return () => {\n cancelled = true;\n };\n }, [direction, layoutConfig]);\n\n // Rebuild controllers when showControllers or collapse state changes (reuses cached layout)\n React.useEffect(() => {\n if (!layoutCacheRef.current || !initialDataRef.current) return;\n const cachedNodes = cloneCachedNodes(layoutCacheRef.current.nodes);\n const cachedEdges = layoutCacheRef.current.edges;\n const withControllers = applyControllers(\n cachedNodes,\n cachedEdges,\n initialDataRef.current._graphspec,\n initialDataRef.current._analysis,\n showControllers,\n expandedControllers,\n toggleCollapse,\n layoutCacheRef.current.controllerPositions,\n toggleFold,\n );\n setNodes(\n applyStatusOverrides(toAppNodes(hydrateLabels(withControllers.nodes)), statusMapRef.current),\n );\n setEdges(toAppEdges(withControllers.edges));\n }, [showControllers, expandedControllers, toggleCollapse, toggleFold]);\n\n // Build + layout when graphspec/edgeType changes\n React.useEffect(() => {\n if (!graphspec) {\n initialDataRef.current = null;\n rawGraphDataRef.current = null;\n layoutCacheRef.current = null;\n setNodes([]);\n setEdges([]);\n return;\n }\n\n let cancelled = false;\n\n // Reset expand overrides when graph changes. Update the ref synchronously\n // so any in-flight reads see the cleared state, not the previous graphspec's\n // expand set. Fold state is seeded below after we know the controller IDs.\n setExpandedControllers(new Set());\n expandedRef.current = new Set();\n\n const { graphData, analysis } = buildGraph(graphspec, edgeType);\n rawGraphDataRef.current = {\n nodes: graphData.nodes,\n edges: graphData.edges,\n analysis,\n graphspec,\n };\n\n // Apply the host-supplied initial fold mode now that we know which\n // controllers exist for this graph. When seedSet is empty (the\n // expanded/auto cases) or analysis is null (degenerate spec — no\n // controllers to fold), the input is the unfolded graph as-is.\n const seedSet = analysis\n ? seedFoldedControllers(foldModeRef.current, analysis.controllerNodeIds)\n : new Set<string>();\n setFoldedControllers(seedSet);\n foldedRef.current = seedSet;\n // The state update above schedules a re-render that would fire the\n // fold-state effect, which would redundantly rebuild + re-layout the\n // graph we are about to lay out with the same seed below. Tell that\n // effect to skip the next run when we already covered it here.\n skipNextFoldEffectRef.current = seedSet.size > 0;\n prevFoldSizeRef.current = seedSet.size;\n\n const folded =\n seedSet.size > 0 && analysis\n ? applyFolds(\n { nodes: graphData.nodes, edges: graphData.edges },\n analysis,\n graphspec,\n seedSet,\n toggleFoldRef.current,\n )\n : { nodes: graphData.nodes, edges: graphData.edges, analysis };\n\n initialDataRef.current = {\n nodes: folded.nodes,\n edges: folded.edges,\n _analysis: folded.analysis,\n _graphspec: graphspec,\n };\n\n (async () => {\n try {\n const currentDirection = directionRef.current;\n const currentLayoutConfig = layoutConfigRef.current;\n const needsLayout = folded.nodes.some(\n (n) => !n.position || (n.position.x === 0 && n.position.y === 0),\n );\n const layouted = needsLayout\n ? await getLayoutedElements(\n folded.nodes,\n folded.edges,\n currentDirection,\n currentLayoutConfig,\n graphspec,\n folded.analysis,\n )\n : {\n nodes: folded.nodes,\n edges: folded.edges,\n controllerPositions: {} as Record<\n string,\n { x: number; y: number; width: number; height: number }\n >,\n };\n if (cancelled) return;\n layoutCacheRef.current = {\n nodes: layouted.nodes,\n edges: layouted.edges,\n controllerPositions: layouted.controllerPositions,\n };\n const withControllers = applyControllers(\n cloneCachedNodes(layouted.nodes),\n layouted.edges,\n graphspec,\n folded.analysis,\n showControllersRef.current,\n expandedRef.current,\n toggleCollapseRef.current,\n layouted.controllerPositions,\n toggleFoldRef.current,\n );\n\n setNodes(\n applyStatusOverrides(\n toAppNodes(hydrateLabels(withControllers.nodes)),\n statusMapRef.current,\n ),\n );\n setEdges(toAppEdges(withControllers.edges));\n\n // Fit view after render, then apply zoom/pan overrides\n setTimeout(() => {\n if (!cancelled && reactFlowRef.current) {\n reactFlowRef.current.fitView({ padding: 0.1 });\n if (initialZoomRef.current !== undefined && initialZoomRef.current !== null) {\n reactFlowRef.current.zoomTo(initialZoomRef.current);\n }\n if (panToTopRef.current) {\n const vp = reactFlowRef.current.getViewport();\n reactFlowRef.current.setViewport({ x: vp.x, y: 20, zoom: vp.zoom });\n }\n }\n }, 100);\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error(\"[GraphViewer] ELK layout failed:\", err);\n }\n })();\n\n return () => {\n cancelled = true;\n };\n }, [graphspec, edgeType]);\n\n // Re-derive folded data + re-layout when foldedControllers changes (structural change)\n // Skips initial mount AND graphspec-driven resets: the graphspec effect already\n // performs the build+layout against an empty fold set and synchronously clears\n // foldedRef. If both prev and current fold sets are empty, this is a no-op\n // (avoids a redundant ELK layout pass after every graphspec change).\n // skipNextFoldEffectRef covers the non-empty-seed case where the graphspec\n // effect has already laid out the folded graph and we'd otherwise re-layout.\n React.useEffect(() => {\n if (isFirstFoldEffect.current) {\n isFirstFoldEffect.current = false;\n prevFoldSizeRef.current = foldedControllers.size;\n return;\n }\n if (skipNextFoldEffectRef.current) {\n skipNextFoldEffectRef.current = false;\n prevFoldSizeRef.current = foldedControllers.size;\n return;\n }\n const prevSize = prevFoldSizeRef.current;\n prevFoldSizeRef.current = foldedControllers.size;\n if (prevSize === 0 && foldedControllers.size === 0) return;\n if (!rawGraphDataRef.current || !rawGraphDataRef.current.analysis) return;\n const raw = rawGraphDataRef.current;\n const currentGraphspec = raw.graphspec;\n const currentAnalysis = raw.analysis;\n if (!currentGraphspec || !currentAnalysis) return;\n\n let cancelled = false;\n\n const folded = applyFolds(\n { nodes: raw.nodes, edges: raw.edges },\n currentAnalysis,\n currentGraphspec,\n foldedControllers,\n toggleFold,\n );\n initialDataRef.current = {\n nodes: folded.nodes,\n edges: folded.edges,\n _analysis: folded.analysis,\n _graphspec: currentGraphspec,\n };\n\n (async () => {\n try {\n const layouted = await getLayoutedElements(\n folded.nodes,\n folded.edges,\n directionRef.current,\n layoutConfigRef.current,\n currentGraphspec,\n folded.analysis,\n );\n if (cancelled) return;\n layoutCacheRef.current = {\n nodes: layouted.nodes,\n edges: layouted.edges,\n controllerPositions: layouted.controllerPositions,\n };\n const withControllers = applyControllers(\n cloneCachedNodes(layouted.nodes),\n layouted.edges,\n currentGraphspec,\n folded.analysis,\n showControllersRef.current,\n expandedRef.current,\n toggleCollapseRef.current,\n layouted.controllerPositions,\n toggleFoldRef.current,\n );\n setNodes(\n applyStatusOverrides(\n toAppNodes(hydrateLabels(withControllers.nodes)),\n statusMapRef.current,\n ),\n );\n setEdges(toAppEdges(withControllers.edges));\n setTimeout(() => {\n if (!cancelled && reactFlowRef.current) {\n reactFlowRef.current.fitView({ padding: 0.1 });\n }\n }, 50);\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error(\"[GraphViewer] ELK layout failed:\", err);\n }\n })();\n\n return () => {\n cancelled = true;\n };\n }, [foldedControllers, toggleFold]);\n\n // Apply Layer 2 execution state when statusMap changes (reuses cached layout).\n // On mount, statusMap is applied inline by the graphspec build effect above.\n // This effect handles runtime changes only (SSE updates arriving after initial render).\n React.useEffect(() => {\n if (!layoutCacheRef.current || !initialDataRef.current) return;\n const cachedNodes = cloneCachedNodes(layoutCacheRef.current.nodes);\n const cachedEdges = layoutCacheRef.current.edges;\n const withControllers = applyControllers(\n cachedNodes,\n cachedEdges,\n initialDataRef.current._graphspec,\n initialDataRef.current._analysis,\n showControllersRef.current,\n expandedRef.current,\n toggleCollapseRef.current,\n layoutCacheRef.current.controllerPositions,\n toggleFoldRef.current,\n );\n setNodes(applyStatusOverrides(toAppNodes(hydrateLabels(withControllers.nodes)), statusMap));\n setEdges(toAppEdges(withControllers.edges));\n }, [statusMap]);\n\n // Handle node click — opens detail panel + fires external callbacks\n const onNodeClick = React.useCallback(\n (event: React.MouseEvent, node: AppNode) => {\n const nodeData = node.data;\n\n // Fire external callbacks\n onNodeSelect?.(node.id, nodeData, event);\n if (nodeData.isController || nodeData.isPipe) {\n const code = nodeData.pipeCode || nodeData.labelText;\n if (code && onNavigateToPipe) {\n onNavigateToPipe(code, nodeData.pipeCardData?.status as PipeStatus | undefined);\n }\n } else if (nodeData.isStuff && onStuffNodeClick && graphspec) {\n const digest = stuffDigestFromId(node.id);\n const sd = findStuffDataByDigest(graphspec, digest);\n if (sd) onStuffNodeClick(sd);\n }\n\n // Update detail panel (toggle off if same node clicked again)\n setConceptOverride(null);\n if (detailSelection?.nodeId === node.id && !conceptOverride) {\n setDetailSelection(null);\n } else if (nodeData.isPipe || nodeData.isController) {\n setDetailSelection({ kind: \"pipe\", nodeId: node.id, nodeData });\n } else if (nodeData.isStuff && graphspec) {\n const digest = stuffDigestFromId(node.id);\n const sd = findStuffDataByDigest(graphspec, digest);\n setDetailSelection({\n kind: \"stuff\",\n nodeId: node.id,\n nodeData,\n stuffData: sd ?? undefined,\n });\n }\n\n setNodes((nds) => nds.map((n) => ({ ...n, selected: n.id === node.id })));\n },\n [\n setNodes,\n onNavigateToPipe,\n onNodeSelect,\n onStuffNodeClick,\n graphspec,\n detailSelection,\n conceptOverride,\n ],\n );\n\n const onInit = React.useCallback(\n (reactFlowInstance: AppRFInstance) => {\n reactFlowRef.current = reactFlowInstance;\n if (onReactFlowInit) {\n onReactFlowInit(reactFlowInstance);\n }\n },\n [onReactFlowInit],\n );\n\n // Dismiss detail panel on pane click\n const handlePaneClick = React.useCallback(() => {\n setDetailSelection(null);\n setConceptOverride(null);\n onPaneClick?.();\n }, [onPaneClick]);\n\n // Navigate from pipe IO concept → concept detail\n const handleConceptClick = React.useCallback(\n (conceptCode: string) => {\n if (!graphspec) return;\n const info = resolveConceptRef(graphspec, conceptCode);\n if (info) setConceptOverride(info);\n },\n [graphspec],\n );\n\n // Resolve the selected pipe's GraphSpecNode for the detail panel\n const selectedSpecNode =\n detailSelection?.kind === \"pipe\" && graphspec\n ? graphspec.nodes.find((n) => n.pipe_code === detailSelection.nodeData.pipeCode)\n : undefined;\n\n const detailOpen = detailSelection !== null || conceptOverride !== null;\n\n // ─── Fold-all / Expand-all toolbar wiring ────────────────────────────\n // Use the RAW analysis (pre-fold) so we can refold already-folded controllers.\n const rawAnalysis = rawGraphDataRef.current?.analysis;\n const allControllerIds = rawAnalysis?.controllerNodeIds;\n const foldAllProps = React.useMemo(() => {\n if (!showControllers || !allControllerIds || allControllerIds.size === 0) {\n return {\n onFoldAll: undefined as undefined | (() => void),\n onExpandAll: undefined as undefined | (() => void),\n foldAllDisabled: false,\n expandAllDisabled: false,\n };\n }\n return {\n onFoldAll: () => setFoldedControllers(new Set(allControllerIds)),\n onExpandAll: () => setFoldedControllers(new Set()),\n foldAllDisabled: foldedControllers.size === allControllerIds.size,\n expandAllDisabled: foldedControllers.size === 0,\n };\n }, [showControllers, allControllerIds, foldedControllers]);\n\n return (\n <div ref={containerRef} className=\"react-flow-container\">\n <ReactFlow\n nodes={nodes}\n edges={edges}\n nodeTypes={nodeTypes}\n onNodesChange={onNodesChange}\n onEdgesChange={onEdgesChange}\n onNodeClick={onNodeClick}\n onPaneClick={handlePaneClick}\n onInit={onInit}\n fitView\n fitViewOptions={{ padding: 0.1 }}\n defaultEdgeOptions={{ type: edgeType }}\n panOnScroll\n minZoom={0.1}\n proOptions={{ hideAttribution: true }}\n // Disable pan-on-space: the default Space activation key attaches a\n // window-level keydown handler that can swallow spacebar input in\n // text editors embedded alongside the graph (e.g. Monaco).\n panActivationKeyCode={null}\n >\n <Background\n variant={BackgroundVariant.Dots}\n gap={20}\n size={1}\n color=\"var(--color-bg-dots)\"\n />\n </ReactFlow>\n <DetailPanel\n isOpen={detailOpen}\n onClose={handlePaneClick}\n width={panelWidth}\n isDragging={isPanelDragging}\n onResizeHandleMouseDown={onResizeMouseDown}\n >\n {conceptOverride ? (\n <ConceptDetailPanel concept={conceptOverride} />\n ) : selectedSpecNode && graphspec ? (\n <PipeDetailPanel\n node={selectedSpecNode}\n spec={graphspec}\n onConceptClick={handleConceptClick}\n />\n ) : detailSelection?.stuffData ? (\n <StuffNodeDetail\n stuffData={detailSelection.stuffData}\n graphspec={graphspec}\n resolveStorageUrl={resolveStorageUrl}\n canEmbedPdf={canEmbedPdf}\n onOpenExternally={onOpenExternally}\n />\n ) : null}\n {renderDetailExtra &&\n detailSelection &&\n !conceptOverride &&\n renderDetailExtra(detailSelection.nodeId, detailSelection.nodeData)}\n </DetailPanel>\n {!hideToolbar && (\n <GraphToolbar\n direction={direction}\n onDirectionChange={setDirection}\n showControllers={showControllers}\n onShowControllersChange={setShowControllers}\n onZoomIn={() => reactFlowRef.current?.zoomIn()}\n onZoomOut={() => reactFlowRef.current?.zoomOut()}\n onFitView={() => reactFlowRef.current?.fitView({ padding: 0.1 })}\n onFoldAll={foldAllProps.onFoldAll}\n onExpandAll={foldAllProps.onExpandAll}\n foldAllDisabled={foldAllProps.foldAllDisabled}\n expandAllDisabled={foldAllProps.expandAllDisabled}\n rightOffset={detailOpen ? panelWidth : 0}\n />\n )}\n </div>\n );\n}\n","import type { GraphSpec } from \"@graph/types\";\nimport type { StuffViewerData } from \"./stuffViewerTypes\";\n\n/** Check whether a URL is safe for links/downloads (no javascript: or data: injection). */\nexport function isSafeDisplayUrl(url: unknown): url is string {\n if (!url || typeof url !== \"string\") return false;\n return (\n url.startsWith(\"https://\") ||\n url.startsWith(\"http://\") ||\n url.startsWith(\"file://\") ||\n url.startsWith(\"/\")\n );\n}\n\n/** Check whether a URL can be rendered inline in an <img> or <embed> tag.\n * Allows http://, https://, file:// (local dev / Electron), and relative paths. */\nexport function isInlineRenderableUrl(url: unknown): url is string {\n if (!url || typeof url !== \"string\") return false;\n return (\n url.startsWith(\"https://\") ||\n url.startsWith(\"http://\") ||\n url.startsWith(\"file://\") ||\n url.startsWith(\"/\")\n );\n}\n\n/**\n * Extract a displayable URL from stuff data (for links, downloads, open-external).\n * Prefers public_url (pre-signed S3 / file:// URI) over internal pipelex-storage:// URLs.\n * Returns null for unsafe or missing URLs.\n */\nexport function extractUrl(data: unknown): string | null {\n if (!data) return null;\n if (typeof data === \"string\") {\n return isSafeDisplayUrl(data) ? data : null;\n }\n if (typeof data !== \"object\") return null;\n const obj = data as Record<string, unknown>;\n const candidates = [obj.public_url, obj.src, obj.href, obj.uri, obj.url];\n for (const candidate of candidates) {\n if (isSafeDisplayUrl(candidate)) return candidate;\n }\n return null;\n}\n\n/**\n * Extract a URL that can be rendered inline in <img>/<embed> tags.\n * Returns http/https, file://, and relative URLs.\n * Internal schemes like pipelex-storage:// are excluded.\n */\nexport function extractInlineUrl(data: unknown): string | null {\n if (!data) return null;\n if (typeof data === \"string\") {\n return isInlineRenderableUrl(data) ? data : null;\n }\n if (typeof data !== \"object\") return null;\n const obj = data as Record<string, unknown>;\n const candidates = [obj.public_url, obj.src, obj.href, obj.uri, obj.url];\n for (const candidate of candidates) {\n if (isInlineRenderableUrl(candidate)) return candidate;\n }\n return null;\n}\n\n/**\n * Extract a `pipelex-storage://` URI from stuff data, if present.\n *\n * Pipelex-storage URIs are internal logical pointers that need to be resolved\n * to a browser-fetchable URL (e.g. presigned S3) before rendering inline.\n */\nexport function extractStorageUri(data: unknown): string | null {\n if (!data) return null;\n if (typeof data === \"string\") {\n return data.startsWith(\"pipelex-storage://\") ? data : null;\n }\n if (typeof data !== \"object\") return null;\n const obj = data as Record<string, unknown>;\n const candidates = [obj.uri, obj.url, obj.src, obj.href];\n for (const candidate of candidates) {\n if (typeof candidate === \"string\" && candidate.startsWith(\"pipelex-storage://\")) {\n return candidate;\n }\n }\n return null;\n}\n\n/** Extract the filename from stuff data, if available. */\nexport function extractFilename(data: unknown): string | null {\n if (!data || typeof data !== \"object\") return null;\n const obj = data as Record<string, unknown>;\n if (typeof obj.filename === \"string\" && obj.filename) return obj.filename;\n return null;\n}\n\n/**\n * Determine the effective MIME type of a stuff item for preview rendering.\n *\n * Checks (in order):\n * 1. Stuff-level `contentType` (when it's already a MIME type like \"application/pdf\")\n * 2. The `mime_type` field on the data object (Document content carries this)\n * 3. The file extension from `filename` or from the URL/URI\n *\n * The concept-level `contentType` (e.g. \"document\") is not a MIME type; we\n * ignore it and look at the data instead. Returns null when nothing recognizable\n * is found.\n */\nexport function resolveMimeType(\n data: unknown,\n contentType: string | undefined,\n url: string | null,\n): string | null {\n // 1. Already a MIME type\n if (contentType && contentType.includes(\"/\")) return contentType;\n\n // 2. data.mime_type field\n if (data && typeof data === \"object\") {\n const obj = data as Record<string, unknown>;\n if (typeof obj.mime_type === \"string\" && obj.mime_type) return obj.mime_type;\n }\n\n // 3. Guess from extension\n const source = extractFilename(data) || url || (typeof data === \"string\" ? data : null);\n if (source) {\n const match = source.match(/\\.([a-zA-Z0-9]+)(?:\\?|#|$)/);\n const ext = match?.[1]?.toLowerCase();\n if (ext) {\n if (ext === \"pdf\") return \"application/pdf\";\n if ([\"png\", \"jpg\", \"jpeg\", \"gif\", \"webp\", \"svg\", \"bmp\"].includes(ext)) {\n return `image/${ext === \"jpg\" ? \"jpeg\" : ext === \"svg\" ? \"svg+xml\" : ext}`;\n }\n }\n }\n\n return null;\n}\n\n/** Get the appropriate first-tab label based on content MIME type. */\nexport function getHtmlTabLabel(contentType?: string | null): string {\n if (contentType === \"application/pdf\") return \"PDF\";\n if (contentType?.startsWith(\"image/\")) return \"Image\";\n return \"HTML\";\n}\n\n/**\n * Find stuff data by digest in a GraphSpec.\n * Scans all nodes' IO items — outputs first (producer data), then inputs as fallback.\n */\nexport function findStuffDataByDigest(\n graphspec: GraphSpec,\n digest: string,\n): StuffViewerData | null {\n // First pass: look in outputs (producer has the richest data)\n for (const node of graphspec.nodes) {\n for (const output of node.io?.outputs ?? []) {\n if (output.digest === digest) {\n return {\n digest,\n name: output.name,\n concept: output.concept,\n contentType: output.content_type,\n data: output.data,\n dataText: output.data_text,\n dataHtml: output.data_html,\n };\n }\n }\n }\n\n // Second pass: look in inputs (for pipeline-level inputs without a producer)\n for (const node of graphspec.nodes) {\n for (const input of node.io?.inputs ?? []) {\n if (input.digest === digest) {\n return {\n digest,\n name: input.name,\n concept: input.concept,\n contentType: input.content_type,\n data: input.data,\n dataText: input.data_text,\n dataHtml: input.data_html,\n };\n }\n }\n }\n\n return null;\n}\n","import React from \"react\";\nimport DOMPurify from \"dompurify\";\n\nimport type { ResolveStorageUrl, StuffViewerData } from \"./stuffViewerTypes\";\nimport {\n extractFilename,\n extractInlineUrl,\n extractStorageUri,\n extractUrl,\n getHtmlTabLabel,\n isInlineRenderableUrl,\n resolveMimeType,\n} from \"./stuffViewerUtils\";\nimport \"./StuffViewer.css\";\n\ntype StuffTab = \"html\" | \"json\" | \"text\";\n\nexport interface StuffViewerProps {\n stuff: StuffViewerData;\n className?: string;\n /**\n * Resolver for `pipelex-storage://` URIs. If provided and the stuff data\n * references an internal URI, the viewer will call this to obtain a\n * presigned URL for inline rendering. Without a resolver, media with only\n * internal URIs falls back to the \"no preview\" placeholder.\n */\n resolveStorageUrl?: ResolveStorageUrl;\n /**\n * Set to `false` when the host cannot render `<embed type=\"application/pdf\">`\n * — e.g. VS Code webviews, which run inside Electron without the Chromium\n * PDFium plugin. The PDF view then falls back to a clickable tile that\n * triggers `onOpenExternally` (or `window.open` if not provided).\n *\n * Default: `true`.\n */\n canEmbedPdf?: boolean;\n /**\n * Replaces the default `window.open(url, \"_blank\")` behavior for both the\n * toolbar \"open externally\" button and the PDF fallback tile. Use this in\n * environments where `window.open` is blocked or undesirable — for example,\n * VS Code webviews should wire this to `vscode.env.openExternal` via\n * postMessage.\n */\n onOpenExternally?: (url: string, filename?: string) => void;\n}\n\n// ─── SVG icon paths ──────────────────────────────────────────────────────────\n\nconst ICON_COPY = (\n <svg viewBox=\"0 0 24 24\">\n <path d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\" />\n </svg>\n);\n\nconst ICON_CHECK = (\n <svg viewBox=\"0 0 24 24\">\n <path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\" />\n </svg>\n);\n\nconst ICON_DOWNLOAD = (\n <svg viewBox=\"0 0 24 24\">\n <path d=\"M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z\" />\n </svg>\n);\n\nconst ICON_EXTERNAL = (\n <svg viewBox=\"0 0 24 24\">\n <path d=\"M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z\" />\n </svg>\n);\n\nconst ICON_LOCAL_FILE = (\n <svg viewBox=\"0 0 24 24\">\n <path d=\"M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm4 18H6V4h7v5h5v11z\" />\n </svg>\n);\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction escapeHtml(text: string): string {\n return text.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\n}\n\nfunction downloadBlob(content: string, filename: string, mimeType: string) {\n const blob = new Blob([content], { type: mimeType });\n const url = URL.createObjectURL(blob);\n const link = document.createElement(\"a\");\n link.href = url;\n link.download = filename;\n link.click();\n // Defer revocation so the browser has time to start reading the blob\n setTimeout(() => URL.revokeObjectURL(url), 10_000);\n}\n\nfunction downloadUrl(url: string, filename: string) {\n const link = document.createElement(\"a\");\n link.href = url;\n link.download = filename;\n link.target = \"_blank\";\n link.click();\n}\n\n// ─── Component ───────────────────────────────────────────────────────────────\n\nexport function StuffViewer({\n stuff,\n className,\n resolveStorageUrl,\n canEmbedPdf,\n onOpenExternally,\n}: StuffViewerProps) {\n const [activeTab, setActiveTab] = React.useState<StuffTab>(\"html\");\n const [copied, setCopied] = React.useState(false);\n const contentRef = React.useRef<HTMLDivElement>(null);\n\n // URL for inline rendering (img/embed) — only http/https\n const httpInlineUrl = React.useMemo(() => extractInlineUrl(stuff.data), [stuff.data]);\n // URL for links/downloads — includes file:// too\n const httpExternalUrl = React.useMemo(() => extractUrl(stuff.data), [stuff.data]);\n // Internal pipelex-storage:// URI, if any — needs async resolution before rendering\n const storageUri = React.useMemo(() => extractStorageUri(stuff.data), [stuff.data]);\n const filename = React.useMemo(() => extractFilename(stuff.data), [stuff.data]);\n\n // Resolve pipelex-storage:// URIs to browser-fetchable URLs via the provided resolver.\n // Only runs when no direct http(s) URL is available — we prefer public_url/src/href first.\n const [resolvedStorageUrl, setResolvedStorageUrl] = React.useState<string | null>(null);\n React.useEffect(() => {\n // Clear any previously resolved URL synchronously so a second stuff item\n // never briefly renders with the prior item's resolved URL while the new\n // promise is in flight.\n setResolvedStorageUrl(null);\n if (!storageUri || !resolveStorageUrl || httpInlineUrl) {\n return;\n }\n let cancelled = false;\n resolveStorageUrl(storageUri)\n .then((url) => {\n if (cancelled) return;\n // Defensive: the resolver is consumer-supplied. Gate its output through\n // the same scheme check as every other URL path (isInlineRenderableUrl\n // rejects javascript:, data:, vbscript:, etc.) so a faulty or\n // compromised resolver can't inject an unsafe URL into <img>/<iframe>.\n setResolvedStorageUrl(isInlineRenderableUrl(url) ? url : null);\n })\n .catch(() => {\n if (!cancelled) setResolvedStorageUrl(null);\n });\n return () => {\n cancelled = true;\n };\n }, [storageUri, resolveStorageUrl, httpInlineUrl]);\n\n const inlineUrl = httpInlineUrl ?? resolvedStorageUrl;\n const externalUrl = httpExternalUrl ?? resolvedStorageUrl;\n // Effective MIME type: stuff.contentType is often the concept tag (\"document\"),\n // not a MIME. Fall back to data.mime_type or the file extension.\n const effectiveMime = React.useMemo(\n () => resolveMimeType(stuff.data, stuff.contentType, externalUrl ?? storageUri),\n [stuff.data, stuff.contentType, externalUrl, storageUri],\n );\n const isPdf = effectiveMime === \"application/pdf\";\n const isImage = effectiveMime?.startsWith(\"image/\") ?? false;\n const htmlTabLabel = getHtmlTabLabel(effectiveMime ?? stuff.contentType);\n const jsonString = React.useMemo(() => {\n if (stuff.data == null) return null;\n try {\n return JSON.stringify(stuff.data, null, 2);\n } catch {\n return \"[Unable to serialize data]\";\n }\n }, [stuff.data]);\n\n // Make links in sanitized HTML open in new windows\n React.useEffect(() => {\n if (activeTab !== \"html\" || !contentRef.current) return;\n contentRef.current.querySelectorAll(\"a\").forEach((link) => {\n link.setAttribute(\"target\", \"_blank\");\n link.setAttribute(\"rel\", \"noopener noreferrer\");\n });\n }, [activeTab, stuff.dataHtml]);\n\n // ── Tab rendering ────────────────────────────────────────────────────────\n\n /** Fallback for images/PDFs when no inline-renderable URL is available\n * (e.g., only pipelex-storage:// internal URLs exist). */\n function renderMediaFallback(mediaLabel: string) {\n const displayName = filename || stuff.name;\n return (\n <div className=\"stuff-viewer-local-file\">\n <div className=\"stuff-viewer-local-file-icon\">{ICON_LOCAL_FILE}</div>\n <div className=\"stuff-viewer-local-file-info\">\n {displayName && <div className=\"stuff-viewer-local-file-name\">{displayName}</div>}\n <div className=\"stuff-viewer-local-file-hint\">{mediaLabel} — no preview available</div>\n </div>\n </div>\n );\n }\n\n function renderContent() {\n if (activeTab === \"html\") {\n // PDF embed\n if (isPdf) {\n const canEmbed = canEmbedPdf !== false;\n if (canEmbed && inlineUrl) {\n // #pagemode=none hides the sidebar/page thumbnails in the browser PDF viewer\n const pdfUrl = inlineUrl.includes(\"#\") ? inlineUrl : `${inlineUrl}#pagemode=none`;\n return (\n <div className=\"stuff-viewer-pdf\">\n <embed src={pdfUrl} type=\"application/pdf\" />\n </div>\n );\n }\n // Either the host can't render <embed type=\"application/pdf\"> (Electron\n // webviews lack PDFium) or no inline URL is available. If we still have\n // an external URL, give the user a clickable tile to open it.\n if (externalUrl) {\n const displayName = filename || stuff.name;\n return (\n <button\n type=\"button\"\n className=\"stuff-viewer-local-file stuff-viewer-local-file--button\"\n onClick={handleOpenExternal}\n >\n <div className=\"stuff-viewer-local-file-icon\">{ICON_LOCAL_FILE}</div>\n <div className=\"stuff-viewer-local-file-info\">\n {displayName && (\n <div className=\"stuff-viewer-local-file-name\">{displayName}</div>\n )}\n <div className=\"stuff-viewer-local-file-hint\">Click to open PDF externally</div>\n </div>\n </button>\n );\n }\n return renderMediaFallback(\"PDF\");\n }\n\n // Image display\n if (isImage) {\n if (inlineUrl) {\n return (\n <div className=\"stuff-viewer-image\">\n <img src={inlineUrl} alt={stuff.name || \"Image content\"} />\n </div>\n );\n }\n return renderMediaFallback(\"Image\");\n }\n\n // HTML content\n if (stuff.dataHtml) {\n return (\n <div\n className=\"stuff-viewer-html\"\n dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(stuff.dataHtml) }}\n />\n );\n }\n\n // Fallback to JSON\n if (jsonString) {\n return (\n <pre\n className=\"stuff-viewer-pre\"\n dangerouslySetInnerHTML={{ __html: escapeHtml(jsonString) }}\n />\n );\n }\n\n return <div className=\"stuff-viewer-placeholder\">No content available</div>;\n }\n\n if (activeTab === \"json\") {\n if (jsonString) {\n return (\n <pre\n className=\"stuff-viewer-pre\"\n dangerouslySetInnerHTML={{ __html: escapeHtml(jsonString) }}\n />\n );\n }\n return <div className=\"stuff-viewer-placeholder\">No JSON data available</div>;\n }\n\n // text tab\n if (stuff.dataText) {\n return (\n <pre\n className=\"stuff-viewer-pre stuff-viewer-pre--nowrap\"\n dangerouslySetInnerHTML={{ __html: escapeHtml(stuff.dataText) }}\n />\n );\n }\n // Fallback to JSON\n if (jsonString) {\n return (\n <pre\n className=\"stuff-viewer-pre\"\n dangerouslySetInnerHTML={{ __html: escapeHtml(jsonString) }}\n />\n );\n }\n return <div className=\"stuff-viewer-placeholder\">No text data available</div>;\n }\n\n // ── Actions ──────────────────────────────────────────────────────────────\n\n function handleCopy() {\n let textToCopy: string;\n if (activeTab === \"json\") {\n textToCopy = jsonString || \"\";\n } else if (activeTab === \"text\") {\n textToCopy = stuff.dataText || jsonString || \"\";\n } else {\n textToCopy = stuff.dataText || stuff.dataHtml || jsonString || \"\";\n }\n if (!textToCopy) return;\n\n if (navigator.clipboard) {\n navigator.clipboard\n .writeText(textToCopy)\n .then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n })\n .catch(() => {\n // Clipboard API may be unavailable in non-secure contexts\n });\n }\n }\n\n function handleDownload() {\n // For images, download the actual file\n if (isImage && externalUrl) {\n const ext = effectiveMime?.split(\"/\")[1] || \"png\";\n downloadUrl(externalUrl, `${stuff.name || \"stuff\"}.${ext}`);\n return;\n }\n\n // For PDFs, download the actual file\n if (isPdf && externalUrl) {\n downloadUrl(externalUrl, `${stuff.name || \"stuff\"}.pdf`);\n return;\n }\n\n // Otherwise download current tab's text content\n if (activeTab === \"json\") {\n downloadBlob(jsonString || \"{}\", `${stuff.name || \"stuff\"}.json`, \"application/json\");\n } else if (activeTab === \"text\") {\n downloadBlob(\n stuff.dataText || jsonString || \"\",\n `${stuff.name || \"stuff\"}.txt`,\n \"text/plain\",\n );\n } else {\n downloadBlob(\n stuff.dataHtml || jsonString || \"\",\n `${stuff.name || \"stuff\"}.html`,\n \"text/html\",\n );\n }\n }\n\n function handleOpenExternal() {\n if (!externalUrl) return;\n if (onOpenExternally) {\n onOpenExternally(externalUrl, filename ?? undefined);\n return;\n }\n window.open(externalUrl, \"_blank\", \"noopener,noreferrer\");\n }\n\n // ── Render ───────────────────────────────────────────────────────────────\n\n const rootClass = [\"stuff-viewer\", className].filter(Boolean).join(\" \");\n\n return (\n <div className={rootClass}>\n <div className=\"stuff-viewer-header\">\n <h3 className=\"stuff-viewer-title\">{stuff.name || \"Data\"}</h3>\n {stuff.concept && <p className=\"stuff-viewer-subtitle\">{stuff.concept}</p>}\n </div>\n\n <div className=\"stuff-viewer-toolbar\">\n <div className=\"stuff-viewer-tabs\">\n {([\"html\", \"json\", \"text\"] as const).map((tab) => {\n const label = tab === \"html\" ? htmlTabLabel : tab === \"json\" ? \"JSON\" : \"Pretty\";\n const isActive = activeTab === tab;\n return (\n <button\n type=\"button\"\n key={tab}\n className={`stuff-viewer-tab${isActive ? \" stuff-viewer-tab--active\" : \"\"}`}\n onClick={() => setActiveTab(tab)}\n >\n {label}\n </button>\n );\n })}\n </div>\n\n <div className=\"stuff-viewer-actions\">\n {externalUrl && (\n <button\n type=\"button\"\n className=\"stuff-viewer-action-btn\"\n onClick={handleOpenExternal}\n title=\"Open in new window\"\n aria-label=\"Open in new window\"\n >\n {ICON_EXTERNAL}\n </button>\n )}\n <button\n type=\"button\"\n className={`stuff-viewer-action-btn${copied ? \" stuff-viewer-action-btn--copied\" : \"\"}`}\n onClick={handleCopy}\n title=\"Copy\"\n aria-label=\"Copy\"\n >\n {copied ? ICON_CHECK : ICON_COPY}\n </button>\n <button\n type=\"button\"\n className=\"stuff-viewer-action-btn\"\n onClick={handleDownload}\n title=\"Download\"\n aria-label=\"Download\"\n >\n {ICON_DOWNLOAD}\n </button>\n </div>\n </div>\n\n <div className=\"stuff-viewer-content\" ref={contentRef}>\n {renderContent()}\n </div>\n </div>\n );\n}\n","import React from \"react\";\nimport \"./DetailPanel.css\";\n\nexport interface DetailPanelProps {\n isOpen: boolean;\n onClose: () => void;\n children: React.ReactNode;\n /** Panel width in pixels. When provided, overrides the CSS default. */\n width?: number;\n /** Whether a resize drag is in progress. Disables CSS transition during drag. */\n isDragging?: boolean;\n /** Mouse-down handler for the resize handle. When provided, the handle is rendered. */\n onResizeHandleMouseDown?: (e: React.MouseEvent) => void;\n /** Close panel on Escape key. Defaults to true. */\n closeOnEscape?: boolean;\n}\n\nexport function DetailPanel({\n isOpen,\n onClose,\n children,\n width,\n isDragging,\n onResizeHandleMouseDown,\n closeOnEscape = true,\n}: DetailPanelProps) {\n React.useEffect(() => {\n if (!isOpen || !closeOnEscape) return;\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n document.addEventListener(\"keydown\", onKeyDown);\n return () => document.removeEventListener(\"keydown\", onKeyDown);\n }, [isOpen, closeOnEscape, onClose]);\n\n const className = [\n \"detail-panel\",\n !isOpen && \"detail-panel--closed\",\n isDragging && \"detail-panel--dragging\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div className={className} style={width ? { width: `${width}px` } : undefined}>\n {onResizeHandleMouseDown && (\n <div\n className=\"detail-panel-resize-handle\"\n onMouseDown={onResizeHandleMouseDown}\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label=\"Resize panel\"\n />\n )}\n <button className=\"detail-panel-close\" onClick={onClose} aria-label=\"Close panel\">\n x\n </button>\n <div className=\"detail-panel-content\">{children}</div>\n </div>\n );\n}\n","import React from \"react\";\n\n// ─── Types ──────────────────────────────────────────────────────────────────\n\nexport interface UseResizableOptions {\n /** Initial panel width in pixels. */\n defaultWidth: number;\n /** Minimum allowed width in pixels. */\n minWidth: number;\n /** Maximum allowed width in pixels (also clamped to 60% of container). */\n maxWidth: number;\n /** Container element ref for percentage-based max-width calculation. */\n containerRef?: React.RefObject<HTMLElement | null>;\n}\n\nexport interface UseResizableResult {\n /** Current panel width in pixels. */\n width: number;\n /** Whether a resize drag is in progress. */\n isDragging: boolean;\n /** Attach to the resize handle's onMouseDown. */\n handleMouseDown: (e: React.MouseEvent) => void;\n}\n\n// ─── Hook ───────────────────────────────────────────────────────────────────\n\nconst MAX_WIDTH_RATIO = 0.6;\n\nexport function useResizable({\n defaultWidth,\n minWidth,\n maxWidth,\n containerRef,\n}: UseResizableOptions): UseResizableResult {\n const [width, setWidth] = React.useState(defaultWidth);\n const [isDragging, setIsDragging] = React.useState(false);\n\n // Store drag state in refs to avoid stale closures in document listeners\n const dragRef = React.useRef({ startX: 0, startWidth: 0, maxAllowed: maxWidth });\n const rafRef = React.useRef<number | null>(null);\n\n const handleMouseDown = React.useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n // Compute max allowed width once at drag start\n const containerWidth = containerRef?.current?.getBoundingClientRect().width;\n const maxAllowed = containerWidth\n ? Math.min(maxWidth, containerWidth * MAX_WIDTH_RATIO)\n : maxWidth;\n\n dragRef.current = { startX: e.clientX, startWidth: width, maxAllowed };\n setIsDragging(true);\n\n // Prevent text selection and set cursor globally during drag\n document.body.style.userSelect = \"none\";\n document.body.style.cursor = \"col-resize\";\n },\n [width, maxWidth, containerRef],\n );\n\n React.useEffect(() => {\n if (!isDragging) return;\n\n const onMouseMove = (e: MouseEvent) => {\n if (rafRef.current !== null) cancelAnimationFrame(rafRef.current);\n\n rafRef.current = requestAnimationFrame(() => {\n const { startX, startWidth, maxAllowed } = dragRef.current;\n // Dragging left (negative deltaX) increases width for a right-anchored panel\n const deltaX = startX - e.clientX;\n const newWidth = Math.max(minWidth, Math.min(maxAllowed, startWidth + deltaX));\n setWidth(newWidth);\n rafRef.current = null;\n });\n };\n\n const onMouseUp = () => {\n setIsDragging(false);\n document.body.style.userSelect = \"\";\n document.body.style.cursor = \"\";\n if (rafRef.current !== null) {\n cancelAnimationFrame(rafRef.current);\n rafRef.current = null;\n }\n };\n\n document.addEventListener(\"mousemove\", onMouseMove);\n document.addEventListener(\"mouseup\", onMouseUp);\n\n return () => {\n document.removeEventListener(\"mousemove\", onMouseMove);\n document.removeEventListener(\"mouseup\", onMouseUp);\n document.body.style.userSelect = \"\";\n document.body.style.cursor = \"\";\n if (rafRef.current !== null) {\n cancelAnimationFrame(rafRef.current);\n rafRef.current = null;\n }\n };\n }, [isDragging, minWidth]);\n\n return { width, isDragging, handleMouseDown };\n}\n","import React from \"react\";\nimport type { GraphSpecNode, PipeBlueprintUnion, PipeType, GraphSpec } from \"@graph/types\";\nimport { getPipeBlueprint } from \"@graph/graphAnalysis\";\nimport {\n formatDuration,\n KV,\n PipeLLMSection,\n LLMExecutionData,\n PipeImgGenSection,\n ImgGenExecutionData,\n PipeExtractSection,\n ExtractExecutionData,\n PipeSearchSection,\n SearchExecutionData,\n PipeComposeSection,\n ComposeExecutionData,\n PipeConditionSection,\n ConditionExecutionData,\n PipeSequenceSection,\n SequenceExecutionData,\n PipeParallelSection,\n ParallelExecutionData,\n PipeBatchSection,\n BatchExecutionData,\n} from \"./sections\";\nimport \"./DetailPanel.css\";\n\n// ─── Badge / Status config ─────────────────────────────────────────────\n\nconst PIPE_TYPE_BADGES: Record<PipeType, string> = {\n PipeLLM: \"LLM\",\n PipeExtract: \"Extract\",\n PipeCompose: \"Compose\",\n PipeImgGen: \"ImgGen\",\n PipeSearch: \"Search\",\n PipeFunc: \"Func\",\n PipeSequence: \"Seq\",\n PipeParallel: \"Par\",\n PipeCondition: \"Cond\",\n PipeBatch: \"Batch\",\n};\n\nconst CONTROLLER_TYPES = new Set<string>([\n \"PipeSequence\",\n \"PipeParallel\",\n \"PipeCondition\",\n \"PipeBatch\",\n]);\n\nconst STATUS_COLORS: Record<string, string> = {\n succeeded: \"#50FA7B\",\n failed: \"#FF5555\",\n running: \"#8BE9FD\",\n scheduled: \"#6272a4\",\n skipped: \"#6272a4\",\n};\n\n// ─── Props ──────────────────────────────────────────────────────────────\n\nexport interface PipeDetailPanelProps {\n node: GraphSpecNode;\n spec: GraphSpec;\n onConceptClick?: (conceptRef: string) => void;\n}\n\n// ─── Component ──────────────────────────────────────────────────────────\n\nexport function PipeDetailPanel({ node, spec, onConceptClick }: PipeDetailPanelProps) {\n const pipeType = node.pipe_type ?? \"PipeFunc\";\n const isController = CONTROLLER_TYPES.has(pipeType);\n const badge = PIPE_TYPE_BADGES[pipeType as PipeType] ?? pipeType;\n const status = node.status ?? \"scheduled\";\n const statusColor = STATUS_COLORS[status] ?? \"#6272a4\";\n\n // Look up the full blueprint from registry — search by pipe_code suffix since\n // the registry key is domain.pipe_code and the node only has pipe_code\n const blueprint = React.useMemo(() => {\n if (!node.pipe_code || !spec.pipe_registry) return undefined;\n // Direct lookup with pipeline domain\n const directKey = `${spec.pipeline_ref?.domain ?? \"\"}.${node.pipe_code}`;\n const direct = getPipeBlueprint(spec, directKey);\n if (direct) return direct;\n // Search all registry entries by pipe_code suffix\n for (const [ref, pipe] of Object.entries(spec.pipe_registry)) {\n if (ref.endsWith(`.${node.pipe_code}`)) return pipe as PipeBlueprintUnion;\n }\n return undefined;\n }, [node.pipe_code, spec]);\n\n const inputs = node.io?.inputs ?? [];\n const outputs = node.io?.outputs ?? [];\n const description = blueprint?.description ?? node.description;\n\n return (\n <>\n {/* Sticky header: badge, status, description, IO */}\n <div className=\"detail-sticky-header\">\n {/* Header: badge + pipe code */}\n <div className=\"detail-header\">\n <span\n className={`detail-badge ${isController ? \"detail-badge--controller\" : \"detail-badge--operator\"}`}\n >\n {badge}\n </span>\n <span\n className={`detail-pipe-code ${isController ? \"detail-pipe-code--controller\" : \"\"}`}\n >\n {node.pipe_code ?? \"unknown\"}\n </span>\n </div>\n\n {/* Status + Duration */}\n <div className=\"detail-status\">\n <span className=\"detail-status-dot\" style={{ background: statusColor }} />\n <span className=\"detail-status-label\" style={{ color: statusColor }}>\n {status}\n </span>\n {node.timing?.duration != null && (\n <span className=\"detail-duration\">{formatDuration(node.timing.duration)}</span>\n )}\n </div>\n\n {/* Description */}\n {description && <div className=\"detail-description\">{description}</div>}\n\n {/* Inputs */}\n {inputs.length > 0 && (\n <div>\n <div className=\"detail-section-label\">Inputs</div>\n <div className=\"detail-io-list\">\n {inputs.map((input, idx) => (\n <div\n key={idx}\n className=\"detail-io-pill\"\n style={{ cursor: input.concept && onConceptClick ? \"pointer\" : undefined }}\n onClick={() => input.concept && onConceptClick?.(input.concept)}\n >\n <span className=\"detail-io-name\">{input.name ?? \"unnamed\"}</span>\n {input.concept && <span className=\"detail-io-concept\">{input.concept}</span>}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Outputs */}\n {outputs.length > 0 && (\n <div>\n <div className=\"detail-section-label\">Output</div>\n <div className=\"detail-io-list\">\n {outputs.map((output, idx) => (\n <div\n key={idx}\n className=\"detail-io-pill\"\n style={{ cursor: output.concept && onConceptClick ? \"pointer\" : undefined }}\n onClick={() => output.concept && onConceptClick?.(output.concept)}\n >\n <span className=\"detail-io-name\">{output.name ?? \"unnamed\"}</span>\n {output.concept && <span className=\"detail-io-concept\">{output.concept}</span>}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Separator after IO */}\n {(inputs.length > 0 || outputs.length > 0) && (\n <div style={{ borderTop: \"1px solid rgba(255,255,255,0.06)\", margin: \"4px 0\" }} />\n )}\n </div>\n\n {/* Blueprint-specific sections */}\n {blueprint && <BlueprintSection blueprint={blueprint} executionData={node.execution_data} />}\n\n {/* Execution data (runtime-resolved values) */}\n {node.execution_data && Object.keys(node.execution_data).length > 0 && (\n <ExecutionDataSection executionData={node.execution_data} pipeType={pipeType} />\n )}\n\n {/* Error */}\n {node.error && (\n <div className=\"detail-error\">\n <div className=\"detail-error-type\">{node.error.error_type}</div>\n <div className=\"detail-error-message\">{node.error.message}</div>\n {node.error.stack && <div className=\"detail-error-stack\">{node.error.stack}</div>}\n </div>\n )}\n\n {/* Metrics */}\n {node.metrics && Object.keys(node.metrics).length > 0 && (\n <div>\n <div className=\"detail-section-label\">Metrics</div>\n {Object.entries(node.metrics).map(([key, value]) => (\n <KV\n key={key}\n label={key}\n value={typeof value === \"number\" ? value.toLocaleString() : String(value)}\n />\n ))}\n </div>\n )}\n\n {/* Tags */}\n {node.tags && Object.keys(node.tags).length > 0 && (\n <div>\n <div className=\"detail-section-label\">Tags</div>\n <div className=\"detail-tags\">\n {Object.entries(node.tags).map(([key, value]) => (\n <span key={key} className=\"detail-tag\">\n <span className=\"detail-tag-key\">{key}: </span>\n <span className=\"detail-tag-value\">{value}</span>\n </span>\n ))}\n </div>\n </div>\n )}\n\n {/* Blueprint not available */}\n {!blueprint && <div className=\"detail-not-available\">Blueprint not available</div>}\n </>\n );\n}\n\n// ─── Blueprint dispatch ─────────────────────────────────────────────────────\n\nfunction BlueprintSection({\n blueprint,\n executionData,\n}: {\n blueprint: PipeBlueprintUnion;\n executionData?: Record<string, unknown>;\n}) {\n switch (blueprint.type) {\n case \"PipeLLM\":\n return <PipeLLMSection blueprint={blueprint} executionData={executionData} />;\n case \"PipeImgGen\":\n return <PipeImgGenSection blueprint={blueprint} executionData={executionData} />;\n case \"PipeCompose\":\n return <PipeComposeSection blueprint={blueprint} executionData={executionData} />;\n case \"PipeExtract\":\n return <PipeExtractSection blueprint={blueprint} executionData={executionData} />;\n case \"PipeSearch\":\n return <PipeSearchSection blueprint={blueprint} executionData={executionData} />;\n case \"PipeSequence\":\n return <PipeSequenceSection blueprint={blueprint} executionData={executionData} />;\n case \"PipeParallel\":\n return <PipeParallelSection blueprint={blueprint} executionData={executionData} />;\n case \"PipeCondition\":\n return <PipeConditionSection blueprint={blueprint} executionData={executionData} />;\n case \"PipeBatch\":\n return <PipeBatchSection blueprint={blueprint} executionData={executionData} />;\n case \"PipeFunc\":\n return null;\n }\n}\n\n// ─── Execution data dispatch ────────────────────────────────────────────────\n\nfunction ExecutionDataSection({\n executionData,\n pipeType,\n}: {\n executionData: Record<string, unknown>;\n pipeType: string;\n}) {\n switch (pipeType) {\n case \"PipeLLM\":\n return <LLMExecutionData data={executionData} />;\n case \"PipeImgGen\":\n return <ImgGenExecutionData data={executionData} />;\n case \"PipeExtract\":\n return <ExtractExecutionData data={executionData} />;\n case \"PipeSearch\":\n return <SearchExecutionData data={executionData} />;\n case \"PipeCompose\":\n return <ComposeExecutionData data={executionData} />;\n case \"PipeCondition\":\n return <ConditionExecutionData data={executionData} />;\n case \"PipeSequence\":\n return <SequenceExecutionData data={executionData} />;\n case \"PipeParallel\":\n return <ParallelExecutionData data={executionData} />;\n case \"PipeBatch\":\n return <BatchExecutionData data={executionData} />;\n default:\n return <GenericExecutionData data={executionData} />;\n }\n}\n\nfunction GenericExecutionData({ data }: { data: Record<string, unknown> }) {\n const entries = Object.entries(data);\n if (entries.length === 0) return null;\n return (\n <>\n <div className=\"detail-section-label\">Execution</div>\n {entries.map(([key, value]) => (\n <KV key={key} label={key} value={String(value)} />\n ))}\n </>\n );\n}\n","import React, { useState } from \"react\";\n\n// ─── Shared display helpers ────────────────────────────────────────────────\n\nexport function formatDuration(seconds: number): string {\n if (seconds < 1) return `${(seconds * 1000).toFixed(0)}ms`;\n return `${seconds.toFixed(2)}s`;\n}\n\nexport function KV({\n label,\n value,\n}: {\n label: string;\n value: string | number | boolean | null | undefined;\n}) {\n if (value === null || value === undefined) return null;\n return (\n <div className=\"detail-kv-row\">\n <span className=\"detail-kv-key\">{label}</span>\n <span className=\"detail-kv-value\">{String(value)}</span>\n </div>\n );\n}\n\nexport function PromptBlock({ label, text }: { label: string; text: string | null | undefined }) {\n if (!text) return null;\n return (\n <div>\n <div className=\"detail-section-label\">{label}</div>\n <div className=\"detail-prompt-block\">{text}</div>\n </div>\n );\n}\n\n/**\n * Toggle between template and rendered prompt.\n * Default shows rendered (the real prompt that was sent).\n */\nconst EXPAND_ICON = (\n <svg viewBox=\"0 0 24 24\" width=\"10\" height=\"10\" fill=\"currentColor\">\n <path d=\"M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z\" />\n </svg>\n);\n\nconst COLLAPSE_ICON = (\n <svg viewBox=\"0 0 24 24\" width=\"10\" height=\"10\" fill=\"currentColor\">\n <path d=\"M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z\" />\n </svg>\n);\n\nconst COPY_ICON = (\n <svg viewBox=\"0 0 24 24\" width=\"10\" height=\"10\" fill=\"currentColor\">\n <path d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\" />\n </svg>\n);\n\nconst CHECK_ICON = (\n <svg viewBox=\"0 0 24 24\" width=\"10\" height=\"10\" fill=\"currentColor\">\n <path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\" />\n </svg>\n);\n\nconst promptActionStyle: React.CSSProperties = {\n all: \"unset\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n gap: 4,\n fontSize: 9,\n color: \"#64748b\",\n padding: \"2px 6px\",\n borderRadius: 3,\n background: \"rgba(255,255,255,0.04)\",\n border: \"1px solid rgba(255,255,255,0.06)\",\n transition: \"color 0.15s\",\n};\n\nexport function PromptToggle({\n label,\n templateText,\n renderedText,\n}: {\n label: string;\n templateText: string | null | undefined;\n renderedText: string | null | undefined;\n}) {\n const [showTemplate, setShowTemplate] = useState(false);\n const [copied, setCopied] = useState(false);\n const [expanded, setExpanded] = useState(false);\n\n const hasTemplate = !!templateText;\n const hasRendered = !!renderedText;\n if (!hasTemplate && !hasRendered) return null;\n const canToggle = hasTemplate && hasRendered;\n // Show rendered by default when available; fall back to template\n const activeText = canToggle\n ? showTemplate\n ? templateText\n : renderedText\n : templateText || renderedText;\n\n function handleCopy() {\n if (!activeText || !navigator.clipboard) return;\n navigator.clipboard\n .writeText(activeText)\n .then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n })\n .catch(() => {});\n }\n\n return (\n <div>\n <div\n style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", gap: 4 }}\n >\n <div className=\"detail-section-label\" style={{ marginBottom: 0 }}>\n {label}\n </div>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 4 }}>\n <button\n onClick={() => setExpanded((prev) => !prev)}\n title={expanded ? \"Collapse prompt\" : \"Expand prompt\"}\n aria-label={expanded ? \"Collapse prompt\" : \"Expand prompt\"}\n className=\"detail-prompt-expand-btn\"\n >\n {expanded ? COLLAPSE_ICON : EXPAND_ICON}\n </button>\n <button\n onClick={handleCopy}\n title=\"Copy prompt\"\n aria-label=\"Copy prompt\"\n style={{\n ...promptActionStyle,\n color: copied ? \"#10b981\" : \"#64748b\",\n }}\n >\n {copied ? CHECK_ICON : COPY_ICON}\n </button>\n {canToggle && (\n <button onClick={() => setShowTemplate((prev) => !prev)} style={promptActionStyle}>\n <span\n style={{\n width: 22,\n height: 12,\n borderRadius: 6,\n background: showTemplate ? \"rgba(255,255,255,0.12)\" : \"#50FA7B33\",\n position: \"relative\",\n display: \"inline-block\",\n transition: \"background 0.15s\",\n }}\n >\n <span\n style={{\n position: \"absolute\",\n top: 2,\n left: showTemplate ? 2 : 12,\n width: 8,\n height: 8,\n borderRadius: \"50%\",\n background: showTemplate ? \"#94a3b8\" : \"#50FA7B\",\n transition: \"left 0.15s, background 0.15s\",\n }}\n />\n </span>\n {showTemplate ? \"template\" : \"rendered\"}\n </button>\n )}\n </div>\n </div>\n <div\n className={`detail-prompt-block ${expanded ? \"detail-prompt-block--expanded\" : \"detail-prompt-block--collapsed\"}`}\n style={{ marginTop: 6 }}\n >\n {activeText}\n </div>\n </div>\n );\n}\n","import React from \"react\";\nimport type { PipeBlueprintUnion } from \"@graph/types\";\nimport { KV, PromptToggle } from \"./shared\";\n\n/**\n * Unified PipeLLM detail — merges blueprint config and runtime execution data\n * into a single view. Runtime values take precedence when available.\n */\nexport function PipeLLMSection({\n blueprint,\n executionData,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeLLM\" }>;\n executionData?: Record<string, unknown>;\n}) {\n const spec = blueprint.llm_prompt_spec;\n const hasImageRefs = spec.user_image_references && spec.user_image_references.length > 0;\n const hasDocRefs = spec.user_document_references && spec.user_document_references.length > 0;\n const hasSysImageRefs = spec.system_image_references && spec.system_image_references.length > 0;\n const hasSysDocRefs =\n spec.system_document_references && spec.system_document_references.length > 0;\n\n // Runtime-resolved values (from execution_data)\n const resolvedModel = executionData?.resolved_model as string | undefined;\n const resolvedModelForObject = executionData?.resolved_model_for_object as string | undefined;\n const renderedSystem = executionData?.rendered_system_prompt as string | undefined;\n const renderedUser = executionData?.rendered_user_prompt as string | undefined;\n const structuringPath = executionData?.structuring_path as string | undefined;\n const isMultipleOutput = executionData?.is_multiple_output as boolean | undefined;\n\n // Model: show resolved if available, otherwise config choice\n const modelDisplay = resolvedModel || blueprint.llm_choices?.for_text;\n const modelForObjectDisplay = resolvedModelForObject || blueprint.llm_choices?.for_object;\n\n return (\n <>\n {/* Model */}\n <KV label=\"Model\" value={modelDisplay} />\n {modelForObjectDisplay && modelForObjectDisplay !== modelDisplay && (\n <KV label=\"Model (object)\" value={modelForObjectDisplay} />\n )}\n\n {/* Structuring — show runtime path if available, otherwise config method */}\n <KV label=\"Structuring\" value={structuringPath || blueprint.structuring_method} />\n <KV label=\"Multiple Output\" value={isMultipleOutput} />\n <KV label=\"Output Multiplicity\" value={blueprint.output_multiplicity} />\n <KV label=\"Prompt Category\" value={spec.prompt_blueprint?.category} />\n\n {/* References */}\n {hasImageRefs && (\n <KV label=\"User Image Refs\" value={`${spec.user_image_references!.length} references`} />\n )}\n {hasDocRefs && (\n <KV\n label=\"User Document Refs\"\n value={`${spec.user_document_references!.length} references`}\n />\n )}\n {hasSysImageRefs && (\n <KV\n label=\"System Image Refs\"\n value={`${spec.system_image_references!.length} references`}\n />\n )}\n {hasSysDocRefs && (\n <KV\n label=\"System Document Refs\"\n value={`${spec.system_document_references!.length} references`}\n />\n )}\n\n {/* Prompts — last, toggle between template and rendered */}\n <PromptToggle\n label=\"System Prompt\"\n templateText={spec.system_prompt_blueprint?.template}\n renderedText={renderedSystem}\n />\n <PromptToggle\n label=\"Prompt\"\n templateText={spec.prompt_blueprint?.template}\n renderedText={renderedUser}\n />\n </>\n );\n}\n\n/**\n * LLMExecutionData is now empty — all data is merged into PipeLLMSection above.\n * Kept as a no-op so the dispatcher doesn't need to change.\n */\nexport function LLMExecutionData(_props: { data: Record<string, unknown> }) {\n return null;\n}\n","import React from \"react\";\nimport type { PipeBlueprintUnion } from \"@graph/types\";\nimport { KV, PromptToggle } from \"./shared\";\n\nexport function PipeImgGenSection({\n blueprint,\n executionData,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeImgGen\" }>;\n executionData?: Record<string, unknown>;\n}) {\n const spec = blueprint.img_gen_prompt_blueprint;\n const resolvedModel = executionData?.resolved_model as string | undefined;\n const renderedPrompt = executionData?.rendered_prompt as string | undefined;\n const renderedNegative = executionData?.rendered_negative_prompt as string | undefined;\n\n return (\n <>\n <KV label=\"Model\" value={resolvedModel || blueprint.img_gen_choice} />\n <PromptToggle\n label=\"Prompt\"\n templateText={spec.prompt_blueprint?.template}\n renderedText={renderedPrompt}\n />\n <PromptToggle\n label=\"Negative Prompt\"\n templateText={spec.negative_prompt_blueprint?.template}\n renderedText={renderedNegative}\n />\n <KV label=\"Aspect Ratio\" value={blueprint.aspect_ratio} />\n <KV label=\"Output Format\" value={blueprint.output_format} />\n <KV label=\"Background\" value={blueprint.background} />\n <KV label=\"Is Raw\" value={blueprint.is_raw} />\n <KV label=\"Seed\" value={blueprint.seed} />\n <KV\n label=\"Images\"\n value={(executionData?.nb_images as number) ?? blueprint.output_multiplicity}\n />\n </>\n );\n}\n\nexport function ImgGenExecutionData(_props: { data: Record<string, unknown> }) {\n return null;\n}\n","import React from \"react\";\nimport type { PipeBlueprintUnion } from \"@graph/types\";\nimport { KV } from \"./shared\";\n\nexport function PipeExtractSection({\n blueprint,\n executionData,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeExtract\" }>;\n executionData?: Record<string, unknown>;\n}) {\n const resolvedModel = executionData?.resolved_model as string | undefined;\n\n return (\n <>\n <KV label=\"Model\" value={resolvedModel || blueprint.extract_choice} />\n <KV label=\"Document Variable\" value={blueprint.document_stuff_name} />\n <KV label=\"Caption Images\" value={blueprint.should_caption_images} />\n <KV label=\"Max Page Images\" value={blueprint.max_page_images} />\n <KV label=\"Include Page Views\" value={blueprint.should_include_page_views} />\n <KV label=\"Page Views DPI\" value={blueprint.page_views_dpi} />\n <KV label=\"Render JS\" value={blueprint.render_js} />\n <KV label=\"Include Raw HTML\" value={blueprint.include_raw_html} />\n <KV label=\"Image Variable\" value={blueprint.image_stuff_name} />\n </>\n );\n}\n\nexport function ExtractExecutionData(_props: { data: Record<string, unknown> }) {\n return null;\n}\n","import React from \"react\";\nimport type { PipeBlueprintUnion } from \"@graph/types\";\nimport { KV, PromptToggle } from \"./shared\";\n\nexport function PipeSearchSection({\n blueprint,\n executionData,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeSearch\" }>;\n executionData?: Record<string, unknown>;\n}) {\n const resolvedModel = executionData?.resolved_model as string | undefined;\n const renderedQuery = executionData?.rendered_query as string | undefined;\n\n return (\n <>\n <KV label=\"Model\" value={resolvedModel || blueprint.search_choice} />\n <PromptToggle\n label=\"Search Query\"\n templateText={blueprint.prompt_blueprint.template}\n renderedText={renderedQuery}\n />\n <KV label=\"Max Results\" value={blueprint.max_results_override} />\n <KV label=\"Include Images\" value={blueprint.include_images_override} />\n <KV label=\"Structured Output\" value={blueprint.is_structured_output} />\n <KV label=\"From Date\" value={blueprint.from_date} />\n <KV label=\"To Date\" value={blueprint.to_date} />\n {blueprint.include_domains && blueprint.include_domains.length > 0 && (\n <KV label=\"Include Domains\" value={blueprint.include_domains.join(\", \")} />\n )}\n {blueprint.exclude_domains && blueprint.exclude_domains.length > 0 && (\n <KV label=\"Exclude Domains\" value={blueprint.exclude_domains.join(\", \")} />\n )}\n </>\n );\n}\n\nexport function SearchExecutionData(_props: { data: Record<string, unknown> }) {\n return null;\n}\n","import React from \"react\";\nimport type {\n FieldResolution,\n PipeBlueprintUnion,\n PipeComposeConstructBlueprint,\n PipeComposeConstructField,\n} from \"@graph/types\";\nimport { KV, PromptToggle } from \"./shared\";\n\n/** Format a non-nested, non-template construct field as a one-line contract string.\n *\n * Design rule: the pipe detail panel shows the **contract** of each field\n * (where it comes from, or what it's hardcoded to) — NOT the runtime data.\n * Runtime data lives in input/output stuff nodes, not on the pipe.\n *\n * - `fixed` → the literal value the pipe authored (it lives in the blueprint)\n * - `from_var` → the dotted path into working memory (the value lives in the input stuff)\n * - `template` → routed to PromptToggle elsewhere; this branch is unreachable\n * - `nested` → never reaches this function; nested fields are rendered by\n * ConstructFieldsBlock recursing into the sub-construct\n */\nfunction formatLeafField(field: PipeComposeConstructField): string {\n switch (field.method) {\n case \"from_var\": {\n const base = `← ${field.from_path ?? \"?\"}`;\n return field.list_to_dict_keyed_by\n ? `${base} (keyed by ${field.list_to_dict_keyed_by})`\n : base;\n }\n case \"fixed\":\n return `= ${JSON.stringify(field.fixed_value)}`;\n case \"nested\":\n // Unreachable: nested fields are routed to recursive rendering. Kept for\n // exhaustiveness over the closed union.\n return \"(nested construct)\";\n case \"template\":\n // Unreachable: template fields are routed to PromptToggle. Kept for\n // exhaustiveness over the closed union.\n return field.template ?? \"(empty template)\";\n }\n}\n\n/** A field's string value is \"long\" when it wraps across multiple lines OR exceeds ~60 chars.\n * Long values get a dedicated text block (label above, value in a bordered scrollable box);\n * short values render inline as a KV row (label left, value right).\n */\nconst LONG_VALUE_THRESHOLD_CHARS = 60;\nfunction isLongValue(text: string): boolean {\n return text.length > LONG_VALUE_THRESHOLD_CHARS || text.includes(\"\\n\");\n}\n\n/** Labeled multi-line text block — used for long fixed-value summaries\n * (e.g. a `fixed = \"<3000 char rationale>\"` field whose JSON-stringified\n * literal won't fit on a single KV row).\n */\nfunction FieldBlock({ label, value }: { label: string; value: string }) {\n return (\n <div className=\"detail-field-block\">\n <div className=\"detail-field-block-label\">{label}</div>\n <div className=\"detail-field-block-value\">{value}</div>\n </div>\n );\n}\n\n/** Recursive renderer for a construct (or sub-construct) at a given indent depth.\n *\n * Splits the field map into:\n * - leafFields: fixed / from_var → render as KV row or FieldBlock\n * - nestedFields: nested → render as a sub-section header + recursive call\n * - templateFields: template → render via PromptToggle\n *\n * The `depth` prop drives left padding so the tree is visually obvious without\n * needing collapse state. Depth 0 has no padding; each level adds 12px.\n */\nfunction ConstructFieldsBlock({\n blueprint,\n depth,\n fieldResolutions,\n}: {\n blueprint: PipeComposeConstructBlueprint;\n depth: number;\n fieldResolutions: Record<string, FieldResolution> | null;\n}) {\n const leafFields: [string, PipeComposeConstructField][] = [];\n const nestedFields: [string, PipeComposeConstructField][] = [];\n const templateFields: [string, PipeComposeConstructField][] = [];\n for (const [name, field] of Object.entries(blueprint.fields)) {\n if (field.method === \"template\") {\n templateFields.push([name, field]);\n } else if (field.method === \"nested\") {\n nestedFields.push([name, field]);\n } else {\n leafFields.push([name, field]);\n }\n }\n\n // Indent all rows at this depth. We use padding-left rather than nested\n // containers so KV rows still align cleanly with their FIELDS section label.\n const indentStyle = depth > 0 ? { paddingLeft: depth * 12 } : undefined;\n\n return (\n <>\n {leafFields.map(([name, field]) => {\n const display = formatLeafField(field);\n if (isLongValue(display)) {\n return (\n <div key={name} style={indentStyle}>\n <FieldBlock label={name} value={display} />\n </div>\n );\n }\n return (\n <div key={name} style={indentStyle}>\n <KV label={name} value={display} />\n </div>\n );\n })}\n\n {templateFields.map(([name, field]) => {\n const renderedForField = fieldResolutions?.[name]?.rendered;\n return (\n <div key={name} style={indentStyle}>\n <PromptToggle\n label={`Template — ${name}`}\n templateText={field.template ?? null}\n renderedText={renderedForField}\n />\n </div>\n );\n })}\n\n {nestedFields.map(([name, field]) => {\n if (!field.nested) return null;\n return (\n <div key={name}>\n <div\n className=\"detail-nested-header\"\n style={depth > 0 ? { paddingLeft: depth * 12 } : undefined}\n >\n <span className=\"detail-nested-header-name\">{name}</span>\n <span className=\"detail-nested-header-meta\">\n nested · {Object.keys(field.nested.fields).length} field\n {Object.keys(field.nested.fields).length === 1 ? \"\" : \"s\"}\n </span>\n </div>\n <ConstructFieldsBlock\n blueprint={field.nested}\n depth={depth + 1}\n fieldResolutions={null}\n />\n </div>\n );\n })}\n </>\n );\n}\n\nexport function PipeComposeSection({\n blueprint,\n executionData,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeCompose\" }>;\n executionData?: Record<string, unknown>;\n}) {\n const renderedText = executionData?.rendered_text as string | undefined;\n const composeMode = executionData?.compose_mode as string | undefined;\n // Per-field record of how each field was built, emitted by\n // PipeCompose._run_construct_mode. Used to surface the rendered Jinja2 text\n // for `template` fields (and recursively for nested constructs). The contract\n // of `fixed` / `from_var` / `nested` fields lives in the blueprint, so the\n // record only carries `rendered` (templates) and `fields` (nested).\n const fieldResolutions = (executionData?.fields ?? null) as Record<\n string,\n FieldResolution\n > | null;\n\n const constructBlueprint = blueprint.construct_blueprint;\n const hasConstruct =\n constructBlueprint !== null && Object.keys(constructBlueprint.fields).length > 0;\n\n return (\n <>\n <KV label=\"Mode\" value={composeMode || (hasConstruct ? \"construct\" : \"template\")} />\n <KV label=\"Category\" value={blueprint.category} />\n <KV label=\"Templating Style\" value={blueprint.templating_style} />\n\n {/* Legacy monolithic template (when construct_blueprint is null) */}\n {blueprint.template && (\n <PromptToggle\n label=\"Template\"\n templateText={blueprint.template}\n renderedText={renderedText}\n />\n )}\n\n {/* Field-level construct form: recursively render the construct blueprint\n tree. Leaf fields (fixed/from_var) render as KV rows or FieldBlocks\n showing their contract (`= literal` or `← path`). Template fields\n render via PromptToggle. Nested sub-constructs render as a header row\n followed by their indented sub-fields. */}\n {hasConstruct && (\n <>\n <div className=\"detail-section-label\">FIELDS</div>\n <ConstructFieldsBlock\n blueprint={constructBlueprint}\n depth={0}\n fieldResolutions={fieldResolutions}\n />\n </>\n )}\n </>\n );\n}\n\nexport function ComposeExecutionData(_props: { data: Record<string, unknown> }) {\n return null;\n}\n","import React from \"react\";\nimport type { PipeBlueprintUnion } from \"@graph/types\";\nimport { KV, PromptBlock } from \"./shared\";\n\nexport function PipeConditionSection({\n blueprint,\n executionData,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeCondition\" }>;\n executionData?: Record<string, unknown>;\n}) {\n const evaluatedExpression = executionData?.evaluated_expression as string | undefined;\n const selectedOutcome = executionData?.selected_outcome as string | undefined;\n\n return (\n <>\n <PromptBlock label=\"Expression\" text={blueprint.expression} />\n {evaluatedExpression && <KV label=\"Expression Result\" value={evaluatedExpression} />}\n <div>\n <div className=\"detail-section-label\">Outcomes</div>\n {Object.entries(blueprint.outcome_map).map(([outcome, pipeCode]) => (\n <div\n key={outcome}\n className=\"detail-kv-row\"\n style={\n selectedOutcome === pipeCode ? { background: \"rgba(80,250,123,0.08)\" } : undefined\n }\n >\n <span className=\"detail-kv-key\">{outcome}</span>\n <span\n className=\"detail-kv-value\"\n style={selectedOutcome === pipeCode ? { color: \"#50FA7B\" } : undefined}\n >\n {pipeCode}\n </span>\n </div>\n ))}\n <div className=\"detail-kv-row\">\n <span className=\"detail-kv-key\">default</span>\n <span className=\"detail-kv-value\">{blueprint.default_outcome}</span>\n </div>\n </div>\n <KV label=\"Alias Expression To\" value={blueprint.add_alias_from_expression_to} />\n </>\n );\n}\n\nexport function ConditionExecutionData(_props: { data: Record<string, unknown> }) {\n return null;\n}\n","import React from \"react\";\nimport type { PipeBlueprintUnion } from \"@graph/types\";\n\nexport function PipeSequenceSection({\n blueprint,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeSequence\" }>;\n executionData?: Record<string, unknown>;\n}) {\n return (\n <div>\n <div className=\"detail-section-label\">Steps</div>\n <div className=\"detail-steps-list\">\n {blueprint.sequential_sub_pipes.map((step, idx) => (\n <div key={idx} className=\"detail-step-item\">\n <span className=\"detail-step-index\">{idx + 1}</span>\n <span className=\"detail-step-code\">{step.pipe_code}</span>\n {step.output_name && (\n <span className=\"detail-io-concept\">-> {step.output_name}</span>\n )}\n </div>\n ))}\n </div>\n </div>\n );\n}\n\nexport function SequenceExecutionData(_props: { data: Record<string, unknown> }) {\n return null;\n}\n","import React from \"react\";\nimport type { PipeBlueprintUnion } from \"@graph/types\";\nimport { KV } from \"./shared\";\n\nexport function PipeParallelSection({\n blueprint,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeParallel\" }>;\n executionData?: Record<string, unknown>;\n}) {\n return (\n <>\n <div>\n <div className=\"detail-section-label\">Branches</div>\n <div className=\"detail-steps-list\">\n {blueprint.parallel_sub_pipes.map((branch, idx) => (\n <div key={idx} className=\"detail-step-item\">\n <span className=\"detail-step-code\">{branch.pipe_code}</span>\n {branch.output_name && (\n <span className=\"detail-io-concept\">-> {branch.output_name}</span>\n )}\n </div>\n ))}\n </div>\n </div>\n <KV label=\"Add Each Output\" value={blueprint.add_each_output} />\n <KV label=\"Combined Output\" value={blueprint.combined_output} />\n </>\n );\n}\n\nexport function ParallelExecutionData(_props: { data: Record<string, unknown> }) {\n return null;\n}\n","import React from \"react\";\nimport type { PipeBlueprintUnion } from \"@graph/types\";\nimport { KV } from \"./shared\";\n\nexport function PipeBatchSection({\n blueprint,\n executionData,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeBatch\" }>;\n executionData?: Record<string, unknown>;\n}) {\n const itemCount = executionData?.item_count as number | undefined;\n\n return (\n <>\n <KV label=\"Branch Pipe\" value={blueprint.branch_pipe_code} />\n <KV label=\"Input List Variable\" value={blueprint.batch_params.input_list_stuff_name} />\n <KV label=\"Input Item Variable\" value={blueprint.batch_params.input_item_stuff_name} />\n {itemCount != null && <KV label=\"Items Processed\" value={itemCount} />}\n </>\n );\n}\n\nexport function BatchExecutionData(_props: { data: Record<string, unknown> }) {\n return null;\n}\n","import React from \"react\";\nimport type { ConceptInfo, GraphSpecNodeIoItem } from \"@graph/types\";\nimport { StuffViewer } from \"../stuff/StuffViewer\";\nimport type { ResolveStorageUrl, StuffViewerData } from \"../stuff/stuffViewerTypes\";\nimport \"./DetailPanel.css\";\n\n// ─── Props ──────────────────────────────────────────────────────────────\n\nexport interface ConceptDetailPanelProps {\n concept: ConceptInfo;\n /** IO data for this concept instance. Accepts GraphSpecNodeIoItem or StuffViewerData. */\n ioData?: GraphSpecNodeIoItem | StuffViewerData;\n /** Whether this is a dry run (schema only, no real data). */\n isDryRun?: boolean;\n /** Resolver for `pipelex-storage://` URIs when rendering media in StuffViewer. */\n resolveStorageUrl?: ResolveStorageUrl;\n /** Forwarded to {@link StuffViewer}. Set `false` when the host can't embed PDFs. */\n canEmbedPdf?: boolean;\n /** Forwarded to {@link StuffViewer}. Overrides default `window.open` behavior. */\n onOpenExternally?: (url: string, filename?: string) => void;\n}\n\n// ─── Component ──────────────────────────────────────────────────────────\n\nexport function ConceptDetailPanel({\n concept,\n ioData,\n isDryRun,\n resolveStorageUrl,\n canEmbedPdf,\n onOpenExternally,\n}: ConceptDetailPanelProps) {\n return (\n <>\n {/* Header */}\n <div className=\"detail-header\">\n <span className=\"detail-concept-code\">{concept.code}</span>\n <span className=\"detail-concept-domain\">{concept.domain_code}</span>\n </div>\n\n {/* Description */}\n {concept.description && <div className=\"detail-description\">{concept.description}</div>}\n\n {/* Refinement chain */}\n {concept.refines && (\n <div className=\"detail-refines\">\n refines <span className=\"detail-refines-code\">{concept.refines}</span>\n </div>\n )}\n\n {/* Structure schema */}\n {concept.json_schema ? (\n <div>\n <div className=\"detail-section-label\">Structure</div>\n <SchemaTable schema={concept.json_schema} isDryRun={isDryRun} />\n </div>\n ) : (\n <div className=\"detail-not-available\">Schema not available</div>\n )}\n\n {/* Instance data (live runs only) */}\n {ioData && !isDryRun && (\n <div>\n <div className=\"detail-section-label\">Data</div>\n <StuffViewer\n stuff={toStuffViewerData(ioData)}\n resolveStorageUrl={resolveStorageUrl}\n canEmbedPdf={canEmbedPdf}\n onOpenExternally={onOpenExternally}\n />\n </div>\n )}\n </>\n );\n}\n\n// ─── Schema table renderer ──────────────────────────────────────────────\n\nfunction SchemaTable({\n schema,\n isDryRun,\n}: {\n schema: Record<string, unknown>;\n isDryRun?: boolean;\n}) {\n const properties = schema.properties as Record<string, Record<string, unknown>> | undefined;\n const required = new Set<string>((schema.required as string[]) ?? []);\n\n if (!properties || Object.keys(properties).length === 0) {\n return <div className=\"detail-not-available\">No fields defined</div>;\n }\n\n const fields = Object.entries(properties);\n // In dry run mode, only show required fields\n const visibleFields = isDryRun ? fields.filter(([name]) => required.has(name)) : fields;\n\n return (\n <table className=\"detail-schema-table\">\n <thead>\n <tr>\n <th>Field</th>\n <th>Type</th>\n <th></th>\n <th>Description</th>\n </tr>\n </thead>\n <tbody>\n {visibleFields.map(([fieldName, fieldSchema]) => (\n <tr key={fieldName}>\n <td className=\"detail-schema-field\">{fieldName}</td>\n <td className=\"detail-schema-type\">{extractType(fieldSchema)}</td>\n <td>\n {required.has(fieldName) && <span className=\"detail-schema-required\">req</span>}\n </td>\n <td>{(fieldSchema.description as string) ?? \"\"}</td>\n </tr>\n ))}\n </tbody>\n </table>\n );\n}\n\nfunction extractType(schema: Record<string, unknown>): string {\n if (schema.type) return String(schema.type);\n if (schema.anyOf) return \"union\";\n if (schema.allOf) return \"all\";\n if (schema.$ref) {\n const ref = String(schema.$ref);\n return ref.split(\"/\").pop() ?? \"ref\";\n }\n return \"unknown\";\n}\n\nfunction toStuffViewerData(ioData: GraphSpecNodeIoItem | StuffViewerData): StuffViewerData {\n // Already a StuffViewerData (has \"digest\" key)\n if (\"digest\" in ioData) return ioData as StuffViewerData;\n // Convert from GraphSpecNodeIoItem\n return {\n digest: (ioData as GraphSpecNodeIoItem).digest ?? \"\",\n name: (ioData as GraphSpecNodeIoItem).name,\n concept: (ioData as GraphSpecNodeIoItem).concept,\n contentType: (ioData as GraphSpecNodeIoItem).content_type,\n data: (ioData as GraphSpecNodeIoItem).data,\n dataText: (ioData as GraphSpecNodeIoItem).data_text,\n dataHtml: (ioData as GraphSpecNodeIoItem).data_html,\n };\n}\n","/**\n * ReactFlow type boundary — \"ports and adapters\" pattern.\n *\n * The pure graph logic (types.ts, graphBuilders, graphLayout, graphControllers)\n * uses domain types: GraphNode, GraphEdge. These are React-free and used for\n * building, layout, analysis, and controller generation.\n *\n * The React layer (this directory) uses ReactFlow's generic types:\n * AppNode = Node<GraphNodeData> — ReactFlow node parameterized with our data\n * AppEdge = Edge<...> — ReactFlow edge with standard fields\n *\n * Boundary mapping functions (toAppNodes, toAppEdges) convert domain types to\n * ReactFlow types at the point where data enters ReactFlow hooks (setNodes/setEdges).\n * All type conversions are localized here — no `as any` casts elsewhere.\n *\n * Why not make GraphNode extend Node<T>?\n * types.ts must stay React-free. GraphNode.style uses Record<string, string | number>\n * (not CSSProperties) and GraphEdge has domain-specific fields (_batchEdge, _crossGroup)\n * that don't belong on ReactFlow's Edge type. The boundary mapping is the clean solution.\n */\nimport type { CSSProperties } from \"react\";\nimport type { Node, Edge, ReactFlowInstance, EdgeMarkerType, Position } from \"@xyflow/react\";\nimport type { GraphNode, GraphEdge, GraphNodeData } from \"../types\";\n\n/** ReactFlow node parameterized with our domain data. */\nexport type AppNode = Node<GraphNodeData>;\n\n/** ReactFlow edge with standard fields (domain-only fields are dropped at the boundary). */\nexport type AppEdge = Edge<Record<string, unknown>>;\n\n/** ReactFlow instance typed with our app node/edge types. */\nexport type AppRFInstance = ReactFlowInstance<AppNode, AppEdge>;\n\n/**\n * Convert domain GraphNode[] to ReactFlow AppNode[].\n *\n * Style fields use Record<string, string | number> in the domain layer but\n * CSSProperties in React. The cast is safe because graph builders only set\n * valid CSS properties (width, height, background, border, etc.).\n */\nexport function toAppNodes(nodes: GraphNode[]): AppNode[] {\n return nodes.map((n) => ({\n id: n.id,\n type: n.type,\n data: n.data,\n position: n.position,\n style: n.style as CSSProperties | undefined,\n sourcePosition: n.sourcePosition as Position | undefined,\n targetPosition: n.targetPosition as Position | undefined,\n parentId: n.parentId,\n extent: n.extent,\n selected: n.selected,\n }));\n}\n\n/**\n * Convert domain GraphEdge[] to ReactFlow AppEdge[].\n *\n * Domain-only fields (_batchEdge, _crossGroup) are dropped — they're only used\n * by pure graph logic (layout weight calculation), not by ReactFlow rendering.\n * The markerEnd cast is safe: our { type: \"arrowclosed\", color } satisfies EdgeMarker.\n */\nexport function toAppEdges(edges: GraphEdge[]): AppEdge[] {\n return edges.map((e) => ({\n id: e.id,\n source: e.source,\n target: e.target,\n type: e.type,\n animated: e.animated,\n label: e.label,\n labelStyle: e.labelStyle as CSSProperties | undefined,\n labelBgStyle: e.labelBgStyle as CSSProperties | undefined,\n labelBgPadding: e.labelBgPadding,\n labelBgBorderRadius: e.labelBgBorderRadius,\n style: e.style as CSSProperties | undefined,\n markerEnd: e.markerEnd as EdgeMarkerType | undefined,\n }));\n}\n","import React from \"react\";\nimport type { LabelDescriptor, GraphNode } from \"@graph/types\";\n\nexport function renderLabel(desc: LabelDescriptor): React.ReactNode {\n if (desc.kind === \"pipe\") {\n return (\n <div\n style={{\n padding: \"10px 14px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"2px\",\n textAlign: \"center\",\n width: \"100%\",\n boxSizing: \"border-box\",\n minWidth: 0,\n }}\n title={desc.label}\n >\n <span\n style={{\n fontFamily: \"var(--font-mono)\",\n fontSize: \"13px\",\n fontWeight: 600,\n color: \"var(--color-pipe-text)\",\n maxWidth: \"100%\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {desc.label}\n </span>\n </div>\n );\n }\n\n // desc.kind === \"stuff\"\n // width: 100% + min-width: 0 lets the flex children's overflow/ellipsis\n // actually kick in — without it, the spans would stretch the parent instead.\n return (\n <div\n style={{\n padding: \"8px 24px\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"2px\",\n textAlign: \"center\",\n width: \"100%\",\n boxSizing: \"border-box\",\n minWidth: 0,\n }}\n title={desc.concept ? `${desc.label}: ${desc.concept}` : desc.label}\n >\n <span\n style={{\n fontFamily: \"var(--font-mono)\",\n fontSize: \"12px\",\n fontWeight: 600,\n color: \"var(--color-stuff-text)\",\n maxWidth: \"100%\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {desc.label}\n </span>\n {desc.concept && (\n <span\n style={{\n fontSize: \"14px\",\n color: \"var(--color-stuff-text-dim)\",\n maxWidth: \"100%\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {desc.concept}\n </span>\n )}\n </div>\n );\n}\n\n/** Convert label descriptors to React elements on all nodes */\nexport function hydrateLabels(nodes: GraphNode[]): GraphNode[] {\n return nodes.map((n) => {\n if (!n.data.labelDescriptor) return n;\n return {\n ...n,\n data: {\n ...n.data,\n label: renderLabel(n.data.labelDescriptor),\n },\n };\n });\n}\n","import React from \"react\";\nimport \"./GraphToolbar.css\";\nimport { GRAPH_DIRECTION, type GraphDirection } from \"@graph/types\";\n\nexport interface GraphToolbarProps {\n direction: GraphDirection;\n onDirectionChange: (direction: GraphDirection) => void;\n showControllers: boolean;\n onShowControllersChange: (showControllers: boolean) => void;\n onZoomIn?: () => void;\n onZoomOut?: () => void;\n onFitView?: () => void;\n /** Fold every controller to a card. Renders the fold-all section when set. */\n onFoldAll?: () => void;\n /** Expand every folded controller. Renders the fold-all section when set. */\n onExpandAll?: () => void;\n /** Disable the fold-all button (e.g. everything already folded). */\n foldAllDisabled?: boolean;\n /** Disable the expand-all button (e.g. nothing currently folded). */\n expandAllDisabled?: boolean;\n /** Pixel offset from the right edge (e.g. detail panel width when open). */\n rightOffset?: number;\n}\n\nconst ARROW_RIGHT_ICON = (\n <svg\n viewBox=\"0 0 24 24\"\n width=\"14\"\n height=\"14\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n <polyline points=\"12 5 19 12 12 19\" />\n </svg>\n);\n\nconst ARROW_DOWN_ICON = (\n <svg\n viewBox=\"0 0 24 24\"\n width=\"14\"\n height=\"14\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <polyline points=\"19 12 12 19 5 12\" />\n </svg>\n);\n\nconst MINUS_ICON = (\n <svg\n viewBox=\"0 0 24 24\"\n width=\"14\"\n height=\"14\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n);\n\nconst PLUS_ICON = (\n <svg\n viewBox=\"0 0 24 24\"\n width=\"14\"\n height=\"14\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n);\n\nconst FIT_VIEW_ICON = (\n <svg\n viewBox=\"0 0 24 24\"\n width=\"14\"\n height=\"14\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"15 3 21 3 21 9\" />\n <polyline points=\"9 21 3 21 3 15\" />\n <line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\" />\n <line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\" />\n </svg>\n);\n\nconst BOXES_ICON = (\n <svg\n viewBox=\"0 0 24 24\"\n width=\"14\"\n height=\"14\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z\" />\n <path d=\"m7 16.5-4.74-2.85\" />\n <path d=\"m7 16.5 5-3\" />\n <path d=\"M7 16.5v5.17\" />\n <path d=\"M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z\" />\n <path d=\"m17 16.5-5-3\" />\n <path d=\"m17 16.5 4.74-2.85\" />\n <path d=\"M17 16.5v5.17\" />\n <path d=\"M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z\" />\n <path d=\"M12 8 7.26 5.15\" />\n <path d=\"m12 8 4.74-2.85\" />\n <path d=\"M12 13.5V8\" />\n </svg>\n);\n\nconst FOLD_ALL_ICON = (\n <svg\n viewBox=\"0 0 24 24\"\n width=\"14\"\n height=\"14\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect x=\"6\" y=\"6\" width=\"12\" height=\"12\" rx=\"2\" />\n <polyline points=\"2 2 6 6 2 6\" />\n <polyline points=\"22 2 18 6 22 6\" />\n <polyline points=\"2 22 6 18 2 18\" />\n <polyline points=\"22 22 18 18 22 18\" />\n </svg>\n);\n\nconst EXPAND_ALL_ICON = (\n <svg\n viewBox=\"0 0 24 24\"\n width=\"14\"\n height=\"14\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect x=\"9\" y=\"9\" width=\"6\" height=\"6\" rx=\"1\" />\n <polyline points=\"3 3 7 7 3 7\" />\n <polyline points=\"21 3 17 7 21 7\" />\n <polyline points=\"3 21 7 17 3 17\" />\n <polyline points=\"21 21 17 17 21 17\" />\n </svg>\n);\n\nexport function GraphToolbar({\n direction,\n onDirectionChange,\n showControllers,\n onShowControllersChange,\n onZoomIn,\n onZoomOut,\n onFitView,\n onFoldAll,\n onExpandAll,\n foldAllDisabled = false,\n expandAllDisabled = false,\n rightOffset = 0,\n}: GraphToolbarProps) {\n const isVertical = direction === GRAPH_DIRECTION.TB || direction === GRAPH_DIRECTION.BT;\n const directionLabel = isVertical ? \"Switch to horizontal layout\" : \"Switch to vertical layout\";\n const controllersLabel = showControllers\n ? \"Hide pipe controllers\"\n : \"Show pipe controllers — groups pipes by their controlling pipe\";\n\n const foldAllSection = onFoldAll || onExpandAll;\n const foldAllTitle = foldAllDisabled\n ? \"Fold all controllers (nothing to fold)\"\n : \"Fold all controllers\";\n const expandAllTitle = expandAllDisabled\n ? \"Expand all controllers (nothing to expand)\"\n : \"Expand all controllers\";\n\n return (\n <div className=\"graph-toolbar\" style={{ right: `${rightOffset + 8}px` }}>\n <button\n type=\"button\"\n className=\"graph-toolbar-btn\"\n onClick={() => onDirectionChange(isVertical ? GRAPH_DIRECTION.LR : GRAPH_DIRECTION.TB)}\n title={directionLabel}\n aria-label={directionLabel}\n >\n {isVertical ? ARROW_RIGHT_ICON : ARROW_DOWN_ICON}\n </button>\n\n <button\n type=\"button\"\n className={`graph-toolbar-btn${showControllers ? \" graph-toolbar-btn--active\" : \"\"}`}\n onClick={() => onShowControllersChange(!showControllers)}\n title={controllersLabel}\n aria-label={controllersLabel}\n >\n {BOXES_ICON}\n </button>\n\n {foldAllSection && <div className=\"graph-toolbar-separator\" />}\n\n {onFoldAll && (\n <button\n type=\"button\"\n className=\"graph-toolbar-btn\"\n onClick={onFoldAll}\n disabled={foldAllDisabled}\n title={foldAllTitle}\n aria-label={foldAllTitle}\n >\n {FOLD_ALL_ICON}\n </button>\n )}\n\n {onExpandAll && (\n <button\n type=\"button\"\n className=\"graph-toolbar-btn\"\n onClick={onExpandAll}\n disabled={expandAllDisabled}\n title={expandAllTitle}\n aria-label={expandAllTitle}\n >\n {EXPAND_ALL_ICON}\n </button>\n )}\n\n {(onZoomOut || onZoomIn || onFitView) && <div className=\"graph-toolbar-separator\" />}\n\n {onZoomOut && (\n <button\n type=\"button\"\n className=\"graph-toolbar-btn\"\n onClick={onZoomOut}\n title=\"Zoom out\"\n aria-label=\"Zoom out\"\n >\n {MINUS_ICON}\n </button>\n )}\n\n {onZoomIn && (\n <button\n type=\"button\"\n className=\"graph-toolbar-btn\"\n onClick={onZoomIn}\n title=\"Zoom in\"\n aria-label=\"Zoom in\"\n >\n {PLUS_ICON}\n </button>\n )}\n\n {onFitView && (\n <button\n type=\"button\"\n className=\"graph-toolbar-btn\"\n onClick={onFitView}\n title=\"Fit view\"\n aria-label=\"Fit view\"\n >\n {FIT_VIEW_ICON}\n </button>\n )}\n </div>\n );\n}\n","import React from \"react\";\nimport type { FoldToggleOptions, PipeControllerType } from \"@graph/types\";\nimport { MAX_VISIBLE_CONTROLLER_CHILDREN } from \"@graph/graphControllers\";\n\ninterface ControllerGroupData {\n label?: React.ReactNode;\n pipeType?: PipeControllerType;\n childCount?: number;\n isCollapsed?: boolean;\n onToggleCollapse?: () => void;\n onToggleFold?: (options?: FoldToggleOptions) => void;\n}\n\nconst CONTROLLER_CONFIG: Record<PipeControllerType, { badge: string; icon: string }> = {\n PipeSequence: { badge: \"Sequence\", icon: \"→\" },\n PipeParallel: { badge: \"Parallel\", icon: \"//\" },\n PipeCondition: { badge: \"Condition\", icon: \"◇\" },\n PipeBatch: { badge: \"Batch\", icon: \"≡\" },\n};\n\nfunction getControllerConfig(pipeType: PipeControllerType | undefined) {\n if (!pipeType) return { badge: \"\", icon: \"\" };\n return CONTROLLER_CONFIG[pipeType];\n}\n\nfunction getControllerModifier(pipeType: PipeControllerType | undefined): string {\n if (!pipeType) return \"\";\n const key = pipeType.replace(\"Pipe\", \"\").toLowerCase();\n return `controller-group--${key}`;\n}\n\nexport function ControllerGroupNode({ data }: { data: ControllerGroupData }) {\n const config = getControllerConfig(data.pipeType);\n const modifier = getControllerModifier(data.pipeType);\n\n const isCollapsible =\n (data.pipeType === \"PipeParallel\" || data.pipeType === \"PipeBatch\") &&\n (data.childCount ?? 0) > MAX_VISIBLE_CONTROLLER_CHILDREN;\n\n const hiddenCount = isCollapsible ? (data.childCount ?? 0) - MAX_VISIBLE_CONTROLLER_CHILDREN : 0;\n\n return (\n <div className={`controller-group-node ${modifier}`}>\n <div className=\"controller-group-header\">\n <span className=\"controller-group-icon\">{config.icon}</span>\n <span className=\"controller-group-badge\">{config.badge}</span>\n {data.label && <span className=\"controller-group-label\">{data.label}</span>}\n {data.onToggleFold && (\n <button\n type=\"button\"\n className=\"controller-group-fold\"\n title=\"Fold controller (alt/option: only this one)\"\n aria-label=\"Fold controller\"\n onClick={(e) => {\n e.stopPropagation();\n data.onToggleFold?.({ soloMode: e.altKey });\n }}\n >\n ⤡\n </button>\n )}\n </div>\n {isCollapsible && (\n <button\n className=\"controller-group-collapse\"\n onClick={(e) => {\n e.stopPropagation();\n data.onToggleCollapse?.();\n }}\n >\n {data.isCollapsed ? `+${hiddenCount} hidden` : \"collapse\"}\n </button>\n )}\n </div>\n );\n}\n\n// Stable reference to avoid ReactFlow re-mount warnings\nexport const controllerNodeTypes = { controllerGroup: ControllerGroupNode };\n","import React from \"react\";\nimport { Handle, Position } from \"@xyflow/react\";\nimport type { PipeCardData } from \"./pipeCardTypes\";\nimport { getPipeCardComponent } from \"./pipeCardRegistry\";\nimport { PipeCardBase } from \"./PipeCardBase\";\n\nexport interface PipeCardNodeProps {\n data: PipeCardData;\n}\n\n/** Resolves the correct card component for the pipe type and renders it. */\nexport function PipeCardNode({ data }: PipeCardNodeProps) {\n const Card = getPipeCardComponent(data.pipeType) ?? PipeCardBase;\n return <Card data={data} />;\n}\n\n/**\n * ReactFlow custom node wrapper.\n *\n * Renders source/target handles using the positions set by the layout engine\n * (TB → top/bottom, LR → left/right, etc.).\n */\nexport function PipeCardRFNode({\n data,\n sourcePosition = Position.Bottom,\n targetPosition = Position.Top,\n}: {\n data: Record<string, unknown>;\n sourcePosition?: Position;\n targetPosition?: Position;\n}) {\n const payload = data.pipeCardData as PipeCardData | undefined;\n if (!payload) return null;\n return (\n <>\n <Handle type=\"target\" position={targetPosition} />\n <PipeCardNode data={payload} />\n <Handle type=\"source\" position={sourcePosition} />\n </>\n );\n}\n","import React, { useState } from \"react\";\nimport type { PipeCardData, PipeControllerType, PipeStatus, PipeType } from \"./pipeCardTypes\";\n\n// ─── Pipe type badge labels ──────────────────────────────────────────────\n\nconst PIPE_TYPE_BADGES: Record<PipeType, string> = {\n PipeLLM: \"LLM\",\n PipeExtract: \"Extract\",\n PipeCompose: \"Compose\",\n PipeImgGen: \"ImgGen\",\n PipeSearch: \"Search\",\n PipeFunc: \"Func\",\n PipeSequence: \"Sequence\",\n PipeParallel: \"Parallel\",\n PipeCondition: \"Condition\",\n PipeBatch: \"Batch\",\n};\n\n// Derived from `PipeControllerType` so adding a new controller variant in\n// `types.ts` produces a compile error here until the table is updated.\nconst CONTROLLER_TYPE_TABLE: Record<PipeControllerType, true> = {\n PipeSequence: true,\n PipeParallel: true,\n PipeCondition: true,\n PipeBatch: true,\n};\n\nfunction isControllerType(pipeType: PipeType): pipeType is PipeControllerType {\n return pipeType in CONTROLLER_TYPE_TABLE;\n}\n\nconst STATUS_CONFIG: Record<PipeStatus, { color: string; label: string }> = {\n succeeded: { color: \"#50FA7B\", label: \"Succeeded\" },\n failed: { color: \"#FF5555\", label: \"Failed\" },\n running: { color: \"#8BE9FD\", label: \"Running\" },\n scheduled: { color: \"#6272a4\", label: \"Scheduled\" },\n skipped: { color: \"#6272a4\", label: \"Skipped\" },\n};\n\nconst MAX_VISIBLE_INPUTS = 4;\n\nfunction getBadge(pipeType: PipeType): string {\n return PIPE_TYPE_BADGES[pipeType];\n}\n\n// ─── PipeCardBase — shared card rendering for all pipe types ─────────────\n\nexport interface PipeCardBaseProps {\n data: PipeCardData;\n /** Extra content rendered below the I/O section (for per-type customization) */\n children?: React.ReactNode;\n}\n\nexport function PipeCardBase({ data, children }: PipeCardBaseProps) {\n const badge = getBadge(data.pipeType);\n const statusConfig = STATUS_CONFIG[data.status] ?? STATUS_CONFIG.scheduled;\n const isRunning = data.status === \"running\";\n const isController = isControllerType(data.pipeType);\n const [inputsExpanded, setInputsExpanded] = useState(false);\n\n const hasMany = data.inputs.length > MAX_VISIBLE_INPUTS;\n const visibleInputs =\n hasMany && !inputsExpanded ? data.inputs.slice(0, MAX_VISIBLE_INPUTS) : data.inputs;\n const hiddenCount = data.inputs.length - MAX_VISIBLE_INPUTS;\n\n const dirClass = data.direction === \"TB\" ? \"pipe-card--tb\" : \"pipe-card--lr\";\n const controllerClass = isController ? \" pipe-card--controller\" : \"\";\n const badgeClass = isController\n ? \"pipe-card-badge pipe-card-badge--controller\"\n : \"pipe-card-badge\";\n\n return (\n <div className={`pipe-card ${dirClass}${controllerClass}`}>\n {/* Header: badge + pipe code + status + (optional) expand */}\n <div className=\"pipe-card-header\">\n <span className={badgeClass}>{badge}</span>\n <span className=\"pipe-card-code\" title={data.pipeCode}>\n {data.pipeCode}\n </span>\n <span\n className=\"pipe-card-status\"\n style={{ color: statusConfig.color }}\n title={statusConfig.label}\n >\n <span\n className={`pipe-card-status-dot ${isRunning ? \"pipe-card-status-dot--pulse\" : \"\"}`}\n style={{ background: statusConfig.color }}\n />\n </span>\n {data.onExpand && (\n <button\n type=\"button\"\n className=\"pipe-card-expand\"\n title=\"Expand controller (alt/option: only this one)\"\n aria-label=\"Expand controller\"\n onClick={(e) => {\n e.stopPropagation();\n data.onExpand?.({ soloMode: e.altKey });\n }}\n >\n ⤢\n </button>\n )}\n </div>\n\n {/* Description — clamped via CSS */}\n {data.description && (\n <span className=\"pipe-card-description\" title={data.description}>\n {data.description}\n </span>\n )}\n\n {/* Inputs */}\n {data.inputs.length > 0 && (\n <div className=\"pipe-card-io\">\n <span className=\"pipe-card-io-label\">INPUTS</span>\n <div className=\"pipe-card-io-pills\">\n {visibleInputs.map((input) => (\n <span\n key={input.name}\n className=\"pipe-card-io-pill\"\n title={`${input.name}: ${input.concept}`}\n >\n <span className=\"pipe-card-io-pill-name\">{input.name}</span>\n <span className=\"pipe-card-io-pill-concept\">{input.concept}</span>\n </span>\n ))}\n {hasMany && (\n <button\n className=\"pipe-card-io-more\"\n onClick={(e) => {\n e.stopPropagation();\n setInputsExpanded((v) => !v);\n }}\n >\n {inputsExpanded ? \"show less\" : `+${hiddenCount} more`}\n </button>\n )}\n </div>\n </div>\n )}\n\n {/* Outputs */}\n {data.outputs.length > 0 && (\n <div className=\"pipe-card-io\">\n <span className=\"pipe-card-io-label\">OUTPUT</span>\n <div className=\"pipe-card-io-pills\">\n {data.outputs.map((output) => (\n <span\n key={output.name}\n className=\"pipe-card-io-pill\"\n title={`${output.name}: ${output.concept}`}\n >\n <span className=\"pipe-card-io-pill-name\">{output.name}</span>\n <span className=\"pipe-card-io-pill-concept\">{output.concept}</span>\n </span>\n ))}\n </div>\n </div>\n )}\n\n {/* Per-type extra content slot */}\n {children}\n </div>\n );\n}\n","import type { ComponentType } from \"react\";\nimport type { PipeType } from \"./pipeCardTypes\";\nimport type { PipeCardBaseProps } from \"./PipeCardBase\";\nimport { PipeCardBase } from \"./PipeCardBase\";\n\n/**\n * Registry mapping pipe type → card component.\n *\n * All types use PipeCardBase for now. To customize a specific type later,\n * create a wrapper component (e.g. PipeLLMCard) that composes PipeCardBase\n * with extra sections, then register it here.\n */\nconst PIPE_CARD_REGISTRY: Record<PipeType, ComponentType<PipeCardBaseProps>> = {\n PipeLLM: PipeCardBase,\n PipeExtract: PipeCardBase,\n PipeCompose: PipeCardBase,\n PipeImgGen: PipeCardBase,\n PipeSearch: PipeCardBase,\n PipeFunc: PipeCardBase,\n PipeSequence: PipeCardBase,\n PipeParallel: PipeCardBase,\n PipeCondition: PipeCardBase,\n PipeBatch: PipeCardBase,\n};\n\nexport function getPipeCardComponent(pipeType: PipeType): ComponentType<PipeCardBaseProps> {\n return PIPE_CARD_REGISTRY[pipeType];\n}\n"],"mappings":"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","names":["React","React","jsx","jsxs","React","React","React","jsx","jsxs","jsx","jsxs","Fragment","jsx","jsxs","Fragment","jsx","jsxs","Fragment","jsx","jsxs","Fragment","jsx","jsxs","Fragment","jsx","jsxs","jsx","jsxs","Fragment","jsx","jsxs","Fragment","jsx","jsxs","Fragment","jsx","jsxs","React","_a","_b","Fragment","jsx","jsxs","_a","jsx","jsxs","jsx","jsxs","jsx","jsxs","_a","useState","jsx","jsxs","PIPE_TYPE_BADGES","_a","Fragment","jsx","jsxs","Fragment","jsx","jsxs","React","_a","_b"]}
|