@pipelex/mthds-ui 0.30.1 → 0.32.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/graph/react/index.ts","../../../src/graph/react/viewer/GraphViewer.tsx","../../../src/graph/react/viewer/useSystemTheme.ts","../../../src/graph/react/detail/StuffResultPanel.tsx","../../../src/graph/react/viewer/graphArtifacts.ts","../../../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/usageFormat.ts","../../../src/graph/react/detail/sections/UsageSection.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/llmChoice.ts","../../../src/graph/react/detail/sections/PipeStructureDetail.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/sections/BindingStepDetail.tsx","../../../src/graph/react/detail/sections/executionData.ts","../../../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/viewer/ValidationPanel.tsx","../../../src/graph/react/viewer/StyleMenu.tsx","../../../src/graph/react/viewer/usePopoverDismiss.ts","../../../src/graph/react/nodes/NodeValidationBadge.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","../../../src/graph/react/styles/simple/SimpleNodes.tsx","../../../src/graph/react/edges/RoutedEdge.tsx"],"sourcesContent":["\"use client\";\n\n// The graph's stylesheets are imported here and nowhere else. A component\n// importing its own would be bundled into a `dist/graph/react/index.css` that\n// nothing loads, beside the copy this import keeps (`make smoke-pack` checks).\nimport \"./graph-core.css\";\nimport \"./detail/DetailPanel.css\";\nimport \"./viewer/GraphToolbar.css\";\nimport \"./styles/simple/SimpleStyle.css\";\n// No form kernel stylesheet is imported here, on purpose. The detail panel\n// renders kernel controls (`StuffResultPanel` is the kernel's result view), and\n// the host styles those in the way its kind of host needs: a host with\n// Tailwind 4 compiles the kernel's classes itself, with\n// `@import \"@pipelex/mthds-ui/tailwind.css\"` in place of the `@source` line of\n// the kernel's documented setup, and a host without Tailwind imports\n// `@pipelex/mthds-ui/form-kernel.css` once. The README's \"Styling the form\n// controls\" section is the host's side of it.\n//\n// Do not put an import back. v0.20.0 made the kernel's sheet this entry's job\n// because Tailwind 3 hosts kept forgetting a content glob into node_modules and\n// silently lost the classes only the kernel uses; v0.21.0 wrapped the sheet in\n// a cascade layer after the raw copy beat the host's own responsive variants.\n// Neither arrangement works. The sheet is a complete Tailwind build, and in a\n// Tailwind 4 host its preflight belongs below the host's base while its\n// utilities belong above the host's base and below the host's utilities, which\n// one `@import … layer()` cannot express: appended, the layer outranked every\n// variant the host wrote; named first, the host's preflight stripped the\n// kernel's utilities. In a host without Tailwind, the preflight reset every\n// browser default on the page the moment a graph mounted.\n// `docs/run-form-panel.md` has the full account.\n\n// Viewer\nexport { GraphViewer, applyStatusOverrides } from \"./viewer/GraphViewer\";\nexport type { GraphViewerProps } from \"./viewer/GraphViewer\";\n// The one object GraphViewer draws: a graph and the descriptors from its source.\nexport { graphArtifactsFrom, resultDescriptors } from \"./viewer/graphArtifacts\";\nexport type {\n GraphArtifacts,\n GraphArtifactsSource,\n ResultDescriptors,\n} from \"./viewer/graphArtifacts\";\nexport { renderLabel, hydrateLabels } from \"./viewer/renderLabel\";\n// Validation widget — the panel + its pure helpers (the widget itself is part\n// of GraphToolbar and enabled via GraphViewer's `validationState` prop).\nexport {\n ValidationPanel,\n validationLabel,\n validationPanelPlacement,\n} from \"./viewer/ValidationPanel\";\nexport type { ValidationPanelPlacement, ValidationPanelProps } from \"./viewer/ValidationPanel\";\n// System-theme detection — for hosts that drive `system` from their own\n// environment signal (e.g. a VS Code webview) or need the browser default.\nexport { useSystemTheme, detectSystemTheme } from \"./viewer/useSystemTheme\";\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// The graph's data panel, rendered from the standard's own artifacts. Exported\n// for a host that wants the same view outside the graph.\nexport { StuffResultPanel } from \"./detail/StuffResultPanel\";\nexport type { StuffResultPanelProps, StuffResultRendererOptions } from \"./detail/StuffResultPanel\";\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 GraphSpecNodeIoItem,\n DataflowAnalysis,\n FoldMode,\n FoldToggleOptions,\n GraphStyleId,\n GraphTheme,\n GraphThemeMode,\n PipeStatus,\n ConceptInfo,\n ToolbarPosition,\n ValidationIssue,\n ValidationState,\n} from \"@graph/types\";\nimport {\n BINDING_STEP_TYPE,\n stuffDigestFromId,\n EDGE_TYPE,\n EDGE_TYPE_ROUTED,\n FOLD_MODE,\n GRAPH_SPEC_MODE,\n GRAPH_DIRECTION,\n GRAPH_THEME_MODE,\n graphSpecMode,\n} from \"@graph/types\";\nimport { useSystemTheme } from \"./useSystemTheme\";\nimport { buildChildToControllerMap, resolveConceptRef } from \"@graph/graphAnalysis\";\nimport {\n applyValidationDecorations,\n buildValidationDecorations,\n resolveIssueTargetNodeId,\n} from \"@graph/graphValidation\";\nimport { findStuffByDigest } from \"@graph/stuffLookup\";\nimport type { SaveFiles } from \"@pipelex/mthds-form\";\nimport type { DownloadDisplay, ResolveShareUrl, ResolveUrl } from \"@pipelex/mthds-form/react\";\nimport { StuffResultPanel } from \"../detail/StuffResultPanel\";\nimport { resultDescriptors, type GraphArtifacts } from \"./graphArtifacts\";\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 { validateGraphSpec } from \"@graph/validateGraphSpec\";\nimport { applyFolds, findCousinControllers } from \"@graph/graphFolds\";\nimport { getLayoutedElements } from \"@graph/graphLayout\";\nimport type { ControllerRect } from \"@graph/graphControllers\";\nimport { DEFAULT_GRAPH_CONFIG, getPaletteForTheme } from \"@graph/graphConfig\";\nimport { GRAPH_STYLES, resolveGraphStyle, resolveStyleMenu } from \"@graph/styles/graphStyles\";\nimport { GRAPH_STYLE_PIPELINES } from \"@graph/styles/stylePipelines\";\nimport { hydrateLabels } from \"./renderLabel\";\nimport { GraphToolbar } from \"./GraphToolbar\";\nimport { controllerNodeTypes } from \"../nodes/controller/ControllerGroupNode\";\nimport { PipeCardRFNode } from \"../nodes/pipe/PipeCardNode\";\nimport { simpleNodeTypes } from \"../styles/simple/SimpleNodes\";\nimport { RoutedEdge } from \"../edges/RoutedEdge\";\n\n// Stable reference — must be declared outside the component to avoid ReactFlow\n// re-mounts. Every style's node components are registered once, here.\nconst nodeTypes = {\n ...controllerNodeTypes,\n pipeCard: PipeCardRFNode,\n ...simpleNodeTypes,\n};\n\n// Likewise for edge components: the built-in curves, plus the edge drawn along\n// the layout's route, for the styles that ask the layout to route edges.\nconst edgeTypes = { [EDGE_TYPE_ROUTED]: RoutedEdge };\n\nexport interface GraphViewerProps {\n /**\n * The graph to draw, together with the artifacts that describe its pipes —\n * all four from ONE source: a run's results, or a method's validate report\n * beside the dry or static graph of that same method. `null` draws nothing.\n *\n * One object rather than a spec prop and three descriptor props, because the\n * detail panel looks a data node's descriptor up by the `pipe_ref` of the pipe\n * that produced it IN THIS GRAPH. A graph paired with another source's\n * descriptors misses every lookup. See `GraphArtifacts`.\n *\n * Without `pipeIoContracts` and `outputForm`, the panel still works: it shows\n * the concept's structure table and no data tab, which is the honest floor\n * for a graph whose artifacts the host does not hold.\n */\n graph: GraphArtifacts | 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 /**\n * Theme *mode*: `dark | light | system`. Reactive: passing it as a prop drives\n * the active mode, and clearing it back to `undefined` hands control back to\n * `config.theme` (or the default `system`). Users can also cycle it via the\n * built-in toolbar button (unless `showThemeToggle` is `false`).\n *\n * `system` resolves to the environment theme — the browser's\n * `prefers-color-scheme`, or `systemTheme` when injected.\n *\n * Defaults to `config.theme` or `\"system\"`.\n */\n theme?: GraphThemeMode;\n /**\n * Anchor for the built-in toolbar. Controlled + reactive: pass a new value to\n * move it, and the viewer reacts immediately. This library does NOT persist the\n * value — the host owns it (read its own state, change it by passing a new prop).\n *\n * Orientation (horizontal row vs vertical column) is derived from the position,\n * not configured separately: only `center-left` / `center-right` render a\n * vertical bar; the four corners plus `top-center` / `bottom-center` are\n * horizontal.\n *\n * Precedence: this prop → `config.toolbarPosition` → `\"top-right\"`.\n */\n toolbarPosition?: ToolbarPosition;\n /**\n * The style the graph is drawn in: `detailed` (every pipe with its inputs,\n * outputs and settings) or `simple` (the method's steps in plain words).\n * Reactive, like `theme`: passing it drives the active style, and clearing it\n * back to `undefined` hands control to `config.graphStyle`, then the default\n * `detailed`. The toolbar's style menu, when shown, changes it too. A value\n * naming no registered style is treated as unset. This library persists\n * nothing: the host keeps the choice, reported by `onGraphStyleChange`.\n */\n graphStyle?: GraphStyleId;\n /**\n * Called whenever the style changes — from the menu, or from a prop or config\n * update — so the host can persist it. Not called on mount.\n */\n onGraphStyleChange?: (style: GraphStyleId) => void;\n /**\n * Show a style menu in the toolbar. Opt-in: `true` offers every registered\n * style in registry order, a list offers those styles in that order, and the\n * default offers no menu, for a host that fixes the style for its audience.\n * A menu needs two styles to choose between.\n */\n styleMenu?: boolean | readonly GraphStyleId[];\n /**\n * Host-injected environment theme, authoritative when set. Forwarded to the\n * `system` resolver so non-browser hosts (e.g. VS Code webviews, where\n * `prefers-color-scheme` is unreliable) can drive `system` from their own\n * detection. When omitted, `system` follows the browser's `prefers-color-scheme`.\n */\n systemTheme?: GraphTheme;\n /**\n * Whether to render the theme toggle button in the built-in toolbar.\n * Defaults to `true`. Set to `false` to hide it (useful when the host app\n * fully controls `theme` from the outside).\n */\n showThemeToggle?: boolean;\n /**\n * Called whenever the theme changes — from the built-in toggle, from external\n * prop / config updates, or when `system` re-resolves because the environment\n * changed. Receives both the selected `mode` (for persistence) and the\n * `resolvedTheme` (for keeping page chrome outside the container in sync).\n */\n onThemeChange?: (mode: GraphThemeMode, resolvedTheme: GraphTheme) => void;\n onNavigateToPipe?: (pipeCode: string, status?: PipeStatus) => void;\n onStuffNodeClick?: (stuff: GraphSpecNodeIoItem) => void;\n onReactFlowInit?: (instance: AppRFInstance) => void;\n /**\n * Layer 2 execution state: pipe_code → current status. Updates node status dots in real-time.\n * A binding card is never matched: its `pipeCode` is the path it binds, not a pipe's code.\n */\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 * Turns the runtime's own `pipelex-storage://…` reference into a URL a\n * browser can fetch, so files in a result actually paint.\n *\n * Without it the panel falls back to whatever `public_url` the payload\n * carries — which on the hosted platform is a PRESIGNED URL with an hour's\n * life, baked into the stored result. Yesterday's run then shows broken\n * images, and the URL answers `403` in a way that reads as a permissions\n * problem rather than an expiry. A resolver is what makes a stored result\n * durable, so supply one if your storage has an authenticated read path.\n */\n resolveUrl?: ResolveUrl;\n /**\n * Mints a URL that works OUTSIDE this page, for the copy control.\n *\n * Distinct from `resolveUrl` because the two answers genuinely differ: a\n * display URL may be a path behind the host's own session — which is what\n * lets a strict `img-src 'self'` stand — and that URL is useless to whoever\n * pastes it. A shared one carries its own credential and is minted per click,\n * since it starts expiring the moment it exists.\n */\n resolveShareUrl?: ResolveShareUrl;\n /**\n * Delivers the files the result panel's downloads hand over: its Download\n * control and each file's own button.\n *\n * Without it the kernel saves them in the browser tab, through an object URL\n * and a clicked link. A host whose view runs in a sandboxed frame is refused\n * both, so its downloads fail without a word unless it supplies this, handing\n * the planned files to its own bridge. It goes on the panel's provider beside\n * `resolveUrl`, which replaces an outer provider rather than merging with it,\n * so a `saveFiles` set around the graph does not reach the panel.\n */\n saveFiles?: SaveFiles;\n /**\n * Which of the result panel's download controls are drawn: the whole-result\n * Download (`result`) and each file's own button (`files`, which also takes\n * the kinds that carry one). Both are drawn by default.\n */\n downloads?: DownloadDisplay;\n /**\n * State of the toolbar's validation widget. The widget renders only when this\n * is set — `undefined` (the default) disables the feature entirely. Reactive:\n * a host typically drives `validating → valid | invalid | error` as its\n * validator progresses, without re-mounting the viewer.\n */\n validationState?: ValidationState;\n /**\n * Issues listed in the validation widget's dropdown (the badge shows their\n * count). Presentation-only — the host decides which issues to surface per\n * state (validator errors, static-analysis diagnostics, or a mix; see\n * `staticDiagnosticsToValidationIssues` in `@pipelex/mthds-ui/static-graph`).\n */\n validationIssues?: ValidationIssue[];\n /**\n * Called when an issue row is clicked, with the row's index in\n * `validationIssues`. Wire this to source navigation in the host.\n */\n onValidationIssueClick?: (index: number, issue: ValidationIssue) => void;\n}\n\n/** Stuff node detail: concept structure, plus whatever the host renders for its data. */\nfunction StuffNodeDetail({\n nodeId,\n stuffData,\n producerPipeRef,\n consumer,\n graphspec,\n artifacts,\n theme,\n resolveUrl,\n resolveShareUrl,\n saveFiles,\n downloads,\n}: {\n /** Selected graph node id — identity for per-node panel state (tab reset). */\n nodeId: string;\n stuffData: GraphSpecNodeIoItem;\n producerPipeRef?: string;\n consumer?: { pipeRef: string; slotName: string };\n graphspec: GraphSpec | null;\n /** The descriptors that came with `graphspec`, in the same `graph` object. */\n artifacts: GraphArtifacts | null;\n theme: GraphTheme;\n resolveUrl?: ResolveUrl;\n resolveShareUrl?: ResolveShareUrl;\n saveFiles?: SaveFiles;\n downloads?: DownloadDisplay;\n}) {\n const conceptInfo =\n stuffData.concept && graphspec ? resolveConceptRef(graphspec, stuffData.concept) : undefined;\n const isDryRun = graphSpecMode(graphspec) === GRAPH_SPEC_MODE.DRY;\n\n // Built here rather than inside `ConceptDetailPanel` so both branches below\n // render the SAME panel: a stuff with no concept in the spec is still a stuff\n // whose value can be shown, and it is exactly the case the old fallback\n // treated as second-class.\n //\n // Both artifacts or neither. The contract names the payload's shape and the\n // descriptor says what the result IS, so a panel given one of the two would be\n // guessing the other — which is the whole failure `output_form` exists to end.\n const descriptors = resultDescriptors(artifacts);\n const renderData = descriptors\n ? () => (\n <StuffResultPanel\n {...descriptors}\n stuff={stuffData}\n {...(conceptInfo ? { concept: conceptInfo } : {})}\n {...(producerPipeRef ? { producerPipeRef } : {})}\n {...(consumer ? { consumer } : {})}\n {...(resolveUrl ? { resolveUrl } : {})}\n {...(resolveShareUrl ? { resolveShareUrl } : {})}\n {...(saveFiles ? { saveFiles } : {})}\n {...(downloads ? { downloads } : {})}\n theme={theme}\n />\n )\n : undefined;\n\n if (conceptInfo) {\n return (\n <ConceptDetailPanel\n concept={conceptInfo}\n ioData={stuffData}\n isDryRun={isDryRun}\n instanceKey={nodeId}\n renderData={renderData}\n />\n );\n }\n if (isDryRun) return <div className=\"detail-not-available\">Dry run data hidden</div>;\n // No concept in the spec, so there is no structure to show and no tabs to\n // choose between — just the data, if anything can render it.\n return <>{renderData?.() ?? <div className=\"detail-not-available\">No data</div>}</>;\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\n/**\n * Resolve the externally-driven theme *mode* from `(themeProp, config.theme,\n * default)`. Pure function so the reactivity contract is unit-testable without\n * React.\n *\n * Contract — must hold for every transition (regression-tested in\n * `__tests__/themeResolution.test.ts`):\n * - `themeProp` wins when set\n * - falls back to `config.theme` when `themeProp` is undefined (so a host can\n * hand theme control back to config after passing it as a prop)\n * - falls back to the library default (`system`) when neither is set\n * - a `themeProp` transition controlled→undefined→same-prior-value still\n * round-trips through the config fallback rather than silently re-using\n * the previous prop value\n */\nexport function resolveExternalThemeMode(\n themeProp: GraphThemeMode | undefined,\n configTheme: GraphThemeMode | undefined,\n): GraphThemeMode {\n return themeProp ?? configTheme ?? DEFAULT_GRAPH_CONFIG.theme ?? GRAPH_THEME_MODE.SYSTEM;\n}\n\n/**\n * Collapse a theme mode + the detected environment theme into the binary\n * `GraphTheme` that drives the palette and container class. `system` follows the\n * environment; `dark`/`light` are returned as-is. Pure + exported for testing.\n */\nexport function resolveActiveTheme(mode: GraphThemeMode, systemTheme: GraphTheme): GraphTheme {\n return mode === GRAPH_THEME_MODE.SYSTEM ? systemTheme : mode;\n}\n\n/**\n * Resolve the toolbar anchor from `(positionProp, config.toolbarPosition,\n * default)`. Pure + exported so the controlled/reactive precedence is\n * unit-testable without React. Mirrors `resolveExternalThemeMode`:\n * - the `toolbarPosition` prop wins when set,\n * - falls back to `config.toolbarPosition` when the prop is undefined,\n * - falls back to the library default (`top-right`) when neither is set.\n */\nexport function resolveToolbarPosition(\n positionProp: ToolbarPosition | undefined,\n configPosition: ToolbarPosition | undefined,\n): ToolbarPosition {\n // `DEFAULT_GRAPH_CONFIG.toolbarPosition` is the single source of the library\n // default (typed non-optional), so the chain needs no extra literal floor.\n return positionProp ?? configPosition ?? DEFAULT_GRAPH_CONFIG.toolbarPosition;\n}\n\n/** Remove the transient flash class (undefined when nothing else remains). */\nfunction stripFlash(className: string | undefined): string | undefined {\n return className?.replace(/\\s*\\bnode-validation-flash\\b/, \"\") || undefined;\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/**\n * The run status a node shows, whatever the style: a card's, or a simple-style\n * step's, decision's or frame's. Undefined for data and for a node without one.\n */\nexport function nodeRunStatus(data: AppNode[\"data\"]): PipeStatus | undefined {\n const simple = data.simple;\n if (simple) return \"status\" in simple ? simple.status : undefined;\n return data.pipeCardData?.status;\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 if (node.data.graphMode === \"static\" || node.data.pipeCardData?.graphMode === \"static\") {\n return node;\n }\n // A binding card's `pipeCode` is its `from` path, which a pipe may share\n // (`from = \"summary\"` beside a pipe coded `summary`): no status keyed by\n // pipe code is about it.\n if (node.data.pipeType === BINDING_STEP_TYPE) return node;\n const pipeCode = node.data.pipeCode;\n if (!pipeCode || !Object.hasOwn(statusMap, pipeCode)) return node;\n const newStatus = statusMap[pipeCode];\n const simple = node.data.simple;\n // The simple style's steps, decisions and frames carry a status; its inputs and outputs do not.\n const simpleWithStatus = simple && \"status\" in simple ? simple : undefined;\n if (nodeRunStatus(node.data) === 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 simple: simpleWithStatus ? { ...simpleWithStatus, status: newStatus } : simple,\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?: GraphSpecNodeIoItem;\n /** `domain.code` of the pipe that produced the stuff, when one did. */\n producerPipeRef?: string;\n /** The first pipe reading it, for the method inputs no pipe produced. */\n consumer?: { pipeRef: string; slotName: string };\n}\n\nexport function GraphViewer(props: GraphViewerProps) {\n const {\n graph,\n config = DEFAULT_GRAPH_CONFIG,\n initialDirection,\n initialShowControllers,\n initialFoldMode,\n hideToolbar = false,\n theme: themeProp,\n graphStyle: graphStyleProp,\n onGraphStyleChange,\n styleMenu,\n toolbarPosition: toolbarPositionProp,\n systemTheme: systemThemeProp,\n showThemeToggle = true,\n onThemeChange,\n onNavigateToPipe,\n onStuffNodeClick,\n onReactFlowInit,\n statusMap,\n onNodeSelect,\n onPaneClick,\n renderDetailExtra,\n resolveUrl,\n resolveShareUrl,\n saveFiles,\n downloads,\n validationState,\n validationIssues,\n onValidationIssueClick,\n } = props;\n\n // The spec is read out of the `graph` bundle and memoized on ITS identity,\n // not the wrapper's: a host writing `graph={{ graphSpec, … }}` inline hands\n // over a new wrapper every render, and keying the build on that would re-run\n // the ELK layout on every parent render.\n const graphspecProp = graph?.graphSpec ?? null;\n\n // Single boundary validator for the React render path — mirrors the standalone\n // adapter (src/standalone/adapter.ts). Memoized on prop identity so it runs\n // once per spec; validateGraphSpec normalizes io in place and is idempotent.\n const graphspec = React.useMemo(\n () => (graphspecProp === null ? null : validateGraphSpec(graphspecProp)),\n [graphspecProp],\n );\n\n const [direction, setDirection] = React.useState<GraphDirection>(\n () =>\n initialDirection ?? config.direction ?? DEFAULT_GRAPH_CONFIG.direction ?? GRAPH_DIRECTION.TB,\n );\n\n // Resolve the externally-driven mode on every render so prop AND config\n // changes both propagate (regression for PR-41 review comments: prop\n // clearing must fall back through config, and config.theme changes must\n // not stay stale). `resolveExternalThemeMode` is exported + unit-tested.\n const externalMode = resolveExternalThemeMode(themeProp, config.theme);\n const [mode, setMode] = React.useState<GraphThemeMode>(externalMode);\n const prevExternalModeRef = React.useRef<GraphThemeMode>(externalMode);\n React.useEffect(() => {\n if (externalMode !== prevExternalModeRef.current) {\n prevExternalModeRef.current = externalMode;\n setMode(externalMode);\n }\n }, [externalMode]);\n\n // Resolve `system` to a binary theme via the environment. `systemThemeProp`,\n // when set, is authoritative (host owns detection); otherwise this follows\n // the browser's `prefers-color-scheme` live.\n const systemTheme = useSystemTheme(systemThemeProp);\n const resolvedTheme = resolveActiveTheme(mode, systemTheme);\n\n // Notify the host whenever the mode OR the resolved theme changes. Covers\n // internal toggle clicks, external prop/config updates, and `system`\n // re-resolving on an environment change — all from one place — and stays\n // correct even if the host re-renders for unrelated reasons. Reports both so\n // chrome-sync uses `resolvedTheme` while persistence uses `mode`.\n const onThemeChangeRef = React.useRef(onThemeChange);\n onThemeChangeRef.current = onThemeChange;\n const prevReportedRef = React.useRef<{ mode: GraphThemeMode; resolvedTheme: GraphTheme }>({\n mode,\n resolvedTheme,\n });\n React.useEffect(() => {\n const prev = prevReportedRef.current;\n if (prev.mode !== mode || prev.resolvedTheme !== resolvedTheme) {\n prevReportedRef.current = { mode, resolvedTheme };\n onThemeChangeRef.current?.(mode, resolvedTheme);\n }\n }, [mode, resolvedTheme]);\n\n // The style follows the same controlled + reactive contract as the theme\n // mode: resolved from (prop, config, default) on every render, adopted when\n // that resolution changes, and changeable from the toolbar menu in between.\n const externalStyle = resolveGraphStyle(graphStyleProp, config.graphStyle);\n const [graphStyle, setGraphStyle] = React.useState<GraphStyleId>(externalStyle);\n const prevExternalStyleRef = React.useRef<GraphStyleId>(externalStyle);\n React.useEffect(() => {\n if (externalStyle !== prevExternalStyleRef.current) {\n prevExternalStyleRef.current = externalStyle;\n setGraphStyle(externalStyle);\n }\n }, [externalStyle]);\n const onGraphStyleChangeRef = React.useRef(onGraphStyleChange);\n onGraphStyleChangeRef.current = onGraphStyleChange;\n const prevReportedStyleRef = React.useRef<GraphStyleId>(graphStyle);\n React.useEffect(() => {\n if (prevReportedStyleRef.current !== graphStyle) {\n prevReportedStyleRef.current = graphStyle;\n onGraphStyleChangeRef.current?.(graphStyle);\n }\n }, [graphStyle]);\n const graphStyleRef = React.useRef(graphStyle);\n graphStyleRef.current = graphStyle;\n const styleCapabilities = GRAPH_STYLES[graphStyle].capabilities;\n\n const effectiveFoldMode: FoldMode =\n initialFoldMode ?? config.foldMode ?? DEFAULT_GRAPH_CONFIG.foldMode ?? FOLD_MODE.EXPANDED;\n\n // Folded mode requires showControllers — without it the toolbar's expand-all\n // button is hidden and the user has no global path to unfold the graph.\n const [showControllers, setShowControllers] = React.useState<boolean>(() => {\n if (effectiveFoldMode === FOLD_MODE.FOLDED) return true;\n return (\n initialShowControllers ??\n config.showControllers ??\n DEFAULT_GRAPH_CONFIG.showControllers ??\n false\n );\n });\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 // Theme-derived palette is the base; explicit `config.paletteColors` wins per-key.\n React.useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n const themePalette = getPaletteForTheme(resolvedTheme);\n const overrides = config.paletteColors;\n const palette = overrides ? { ...themePalette, ...overrides } : themePalette;\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, resolvedTheme]);\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 /** The style these nodes were projected for. */\n _graphStyle: GraphStyleId;\n /** What the style draws for each spec node it does not draw. */\n _standIns?: ReadonlyMap<string, string>;\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 /** Containment map derived once per graphspec (pure in graphspec+analysis). */\n childToCtrl: Record<string, string>;\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 /**\n * The graphspec these layouted nodes belong to. Cache-reuse effects must\n * skip when this is not the graphspec in `initialDataRef` — on a graphspec\n * swap the cache is only refreshed after the async layout resolves, and\n * rebuilding controllers from old nodes against the new spec would render\n * garbage (or throw on the id mismatch).\n */\n graphspec: GraphSpec | null;\n /**\n * The style these layouted nodes were drawn in. The same guard as\n * `graphspec`, for a style switch: until the new style's layout resolves,\n * the cache holds the previous style's nodes, and framing them with the new\n * style's pass would render garbage.\n */\n graphStyle: GraphStyleId;\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 // The folds the current style added on its own, as opposed to the host's fold\n // mode and the reader's: a style switch swaps these and keeps the others.\n // Once the reader folds or opens a controller, the choice is theirs, and a\n // controller they opened stays open whatever a later style folds by itself.\n const styleDefaultFoldsRef = React.useRef<Set<string>>(new Set());\n const readerOpenedRef = React.useRef<Set<string>>(new Set());\n const markReaderFolds = React.useCallback((ids: Iterable<string>, folded: boolean) => {\n for (const id of ids) {\n styleDefaultFoldsRef.current.delete(id);\n if (folded) readerOpenedRef.current.delete(id);\n else readerOpenedRef.current.add(id);\n }\n }, []);\n\n const toggleFold = React.useCallback(\n (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 markReaderFolds(targets, shouldFold);\n return next;\n });\n },\n [markReaderFolds],\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 const validationIssuesRef = React.useRef(validationIssues);\n validationIssuesRef.current = validationIssues;\n const selectedNodeIdRef = React.useRef<string | null>(null);\n selectedNodeIdRef.current = detailSelection?.nodeId ?? null;\n\n // Validation dropdown open state — owned here (not in GraphToolbar) so node\n // badges can open the panel too. The toolbar reports toggle/dismiss requests\n // through onValidationOpenChange.\n const [validationOpen, setValidationOpen] = React.useState(false);\n const openValidationPanel = React.useCallback(() => setValidationOpen(true), []);\n // Badges only get a click handler while the panel can actually appear —\n // otherwise they'd render as buttons whose click has no visible effect.\n const validationWidgetAvailable = validationState !== undefined && !hideToolbar;\n const validationWidgetAvailableRef = React.useRef(validationWidgetAvailable);\n validationWidgetAvailableRef.current = validationWidgetAvailable;\n\n // Final per-render node pass, shared by every setNodes site: hydrate labels,\n // apply execution-status overrides, then stamp validation decorations derived\n // from the CURRENT issues + fold state (folded controllers roll up their\n // hidden descendants' issues). Reads refs only, so the callback is stable.\n const decorateNodes = React.useCallback(\n (nodes: GraphNode[]): AppNode[] => {\n const raw = rawGraphDataRef.current;\n const decorations = buildValidationDecorations(\n validationIssuesRef.current,\n raw?.graphspec ?? null,\n raw?.childToCtrl ?? {},\n foldedRef.current,\n initialDataRef.current?._standIns,\n );\n const decorated = applyValidationDecorations(\n applyStatusOverrides(toAppNodes(hydrateLabels(nodes)), statusMapRef.current),\n decorations,\n validationWidgetAvailableRef.current ? openValidationPanel : undefined,\n );\n // The node open in the detail panel stays selected through a rebuild —\n // a style switch, a re-layout — since a node drawn in every style keeps\n // its spec id. One the new style does not draw stays open, unselected.\n const selectedId = selectedNodeIdRef.current;\n return selectedId\n ? decorated.map((n) => (n.id === selectedId ? { ...n, selected: true } : n))\n : decorated;\n },\n [openValidationPanel],\n );\n\n // The style's frame pass over a laid-out graph: the one place the viewer\n // wraps nodes in frames, shared by every path that re-renders from a layout.\n // Takes the style the layout was drawn in, never the current one, so a path\n // reusing a cached layout frames it the way it was projected.\n const frameLayout = React.useCallback(\n (\n style: GraphStyleId,\n layout: {\n nodes: GraphNode[];\n edges: GraphEdge[];\n controllerPositions?: Record<string, ControllerRect>;\n },\n graphspec: GraphSpec | null,\n analysis: DataflowAnalysis | null,\n ) =>\n GRAPH_STYLE_PIPELINES[style].frame({\n nodes: cloneCachedNodes(layout.nodes),\n edges: layout.edges,\n graphspec,\n analysis,\n controllerPositions: layout.controllerPositions,\n showControllers: showControllersRef.current,\n expandedControllers: expandedRef.current,\n onToggleCollapse: toggleCollapseRef.current,\n onToggleFold: toggleFoldRef.current,\n }),\n [],\n );\n\n /** Whether the layout cache holds the nodes `initialDataRef` was projected to. */\n const cacheMatchesData = (): boolean => {\n const cache = layoutCacheRef.current;\n const data = initialDataRef.current;\n return (\n cache !== null &&\n data !== null &&\n cache.graphspec === data._graphspec &&\n cache.graphStyle === data._graphStyle\n );\n };\n\n // Panel row click → host source-jump AND graph pan/flash to the target node\n // (when the issue targets one). The flash is a transient class on the\n // ReactFlow node wrapper; it is dropped on the next full node rebuild, which\n // is fine — it only needs to outlive its CSS animation.\n const nodesRef = React.useRef<AppNode[]>([]);\n nodesRef.current = nodes;\n const onValidationIssueClickRef = React.useRef(onValidationIssueClick);\n onValidationIssueClickRef.current = onValidationIssueClick;\n const flashTimeoutRef = React.useRef<ReturnType<typeof setTimeout> | null>(null);\n React.useEffect(\n () => () => {\n if (flashTimeoutRef.current) clearTimeout(flashTimeoutRef.current);\n },\n [],\n );\n\n const handleValidationIssueClick = React.useCallback(\n (index: number, issue: ValidationIssue) => {\n onValidationIssueClickRef.current?.(index, issue);\n const raw = rawGraphDataRef.current;\n if (!raw?.graphspec || !raw.analysis) return;\n const targetId = resolveIssueTargetNodeId(\n issue,\n raw.graphspec,\n raw.childToCtrl,\n foldedRef.current,\n new Set(nodesRef.current.map((n) => n.id)),\n initialDataRef.current?._standIns,\n );\n if (!targetId) return;\n void reactFlowRef.current?.fitView({\n nodes: [{ id: targetId }],\n duration: 500,\n padding: 0.4,\n });\n if (flashTimeoutRef.current) clearTimeout(flashTimeoutRef.current);\n setNodes((nds) =>\n nds.map((n) => {\n const base = stripFlash(n.className);\n if (n.id === targetId) {\n return {\n ...n,\n className: base ? `${base} node-validation-flash` : \"node-validation-flash\",\n };\n }\n return base === n.className ? n : { ...n, className: base };\n }),\n );\n flashTimeoutRef.current = setTimeout(() => {\n setNodes((nds) =>\n nds.map((n) => {\n const base = stripFlash(n.className);\n return base === n.className ? n : { ...n, className: base };\n }),\n );\n }, 1800);\n },\n [setNodes],\n );\n\n // Re-layout when direction or layout config changes\n React.useEffect(() => {\n if (!initialDataRef.current) return;\n let cancelled = false;\n\n void (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 GRAPH_STYLES[data._graphStyle].layout ?? 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 graphspec: data._graphspec,\n graphStyle: data._graphStyle,\n };\n const withControllers = frameLayout(\n data._graphStyle,\n relayouted,\n data._graphspec,\n data._analysis,\n );\n setNodes(decorateNodes(withControllers.nodes));\n setEdges(toAppEdges(withControllers.edges));\n setTimeout(() => {\n if (!cancelled && reactFlowRef.current) {\n void 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 const cache = layoutCacheRef.current;\n const data = initialDataRef.current;\n // Mid-swap guard: the cache still holds the previous graphspec's (or\n // style's) layout until the async layout lands; the in-flight build will\n // repaint anyway.\n if (!cache || !data || !cacheMatchesData()) return;\n const withControllers = frameLayout(cache.graphStyle, cache, data._graphspec, data._analysis);\n setNodes(decorateNodes(withControllers.nodes));\n setEdges(toAppEdges(withControllers.edges));\n }, [showControllers, expandedControllers, toggleCollapse, toggleFold, decorateNodes]);\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 // A style or edge-type switch redraws the same spec, and keeps what the\n // reader opened and folded; only a new spec starts afresh.\n const sameSpec = rawGraphDataRef.current?.graphspec === graphspec;\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 if (!sameSpec) {\n setExpandedControllers(new Set());\n expandedRef.current = new Set();\n }\n\n const style = graphStyleRef.current;\n const pipeline = GRAPH_STYLE_PIPELINES[style];\n const { graphData, analysis } = buildGraph(graphspec, edgeType);\n rawGraphDataRef.current = {\n nodes: graphData.nodes,\n edges: graphData.edges,\n analysis,\n graphspec,\n childToCtrl: analysis ? buildChildToControllerMap(graphspec, analysis) : {},\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 // The host's fold mode on a new spec, or the folds already there on a\n // switch less the previous style's own, plus whatever this style folds\n // that the reader has not opened.\n if (!sameSpec) readerOpenedRef.current = new Set();\n let seedSet = new Set<string>();\n const styleDefaults = new Set<string>();\n if (analysis) {\n const kept = sameSpec\n ? [...foldedRef.current].filter((id) => !styleDefaultFoldsRef.current.has(id))\n : [...seedFoldedControllers(foldModeRef.current, analysis.controllerNodeIds)];\n seedSet = new Set(kept);\n for (const id of pipeline.defaultFolds(graphspec, analysis)) {\n if (seedSet.has(id) || readerOpenedRef.current.has(id)) continue;\n styleDefaults.add(id);\n seedSet.add(id);\n }\n }\n styleDefaultFoldsRef.current = styleDefaults;\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 // Mirror the mount-time guarantee: a folded graph must have showControllers\n // on, otherwise the toolbar's expand-all button is hidden and the user has\n // no global path to unfold. Needed at graphspec-swap time too — the\n // useState initializer above only runs on the first render.\n // Only a style whose folds are undone from controller frames needs them.\n if (\n seedSet.size > 0 &&\n GRAPH_STYLES[style].capabilities.controllerFrameToggle &&\n !showControllersRef.current\n ) {\n setShowControllers(true);\n showControllersRef.current = true;\n }\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 const projected = pipeline.project({\n graphspec,\n nodes: folded.nodes,\n edges: folded.edges,\n analysis: folded.analysis,\n rawAnalysis: analysis,\n });\n\n initialDataRef.current = {\n nodes: projected.nodes,\n edges: projected.edges,\n _analysis: projected.analysis,\n _graphspec: graphspec,\n _graphStyle: style,\n ...(projected.standIns ? { _standIns: projected.standIns } : {}),\n };\n\n void (async () => {\n try {\n const currentDirection = directionRef.current;\n const currentLayoutConfig = GRAPH_STYLES[style].layout ?? layoutConfigRef.current;\n const needsLayout = projected.nodes.some(\n (n) => !n.position || (n.position.x === 0 && n.position.y === 0),\n );\n const layouted = needsLayout\n ? await getLayoutedElements(\n projected.nodes,\n projected.edges,\n currentDirection,\n currentLayoutConfig,\n graphspec,\n projected.analysis,\n )\n : {\n nodes: projected.nodes,\n edges: projected.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 graphspec,\n graphStyle: style,\n };\n const withControllers = frameLayout(style, layouted, graphspec, projected.analysis);\n\n setNodes(decorateNodes(withControllers.nodes));\n setEdges(toAppEdges(withControllers.edges));\n\n // Fit view after render, then apply zoom/pan overrides\n setTimeout(() => {\n if (!cancelled && reactFlowRef.current) {\n void reactFlowRef.current.fitView({ padding: 0.1 });\n if (initialZoomRef.current !== undefined && initialZoomRef.current !== null) {\n void reactFlowRef.current.zoomTo(initialZoomRef.current);\n }\n if (panToTopRef.current) {\n const vp = reactFlowRef.current.getViewport();\n void 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 // A style switch rebuilds like an edge-type change: the same spec, drawn anew.\n }, [graphspec, edgeType, graphStyle]);\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 style = graphStyleRef.current;\n const folded = applyFolds(\n { nodes: raw.nodes, edges: raw.edges },\n currentAnalysis,\n currentGraphspec,\n foldedControllers,\n toggleFold,\n );\n const projected = GRAPH_STYLE_PIPELINES[style].project({\n graphspec: currentGraphspec,\n nodes: folded.nodes,\n edges: folded.edges,\n analysis: folded.analysis,\n rawAnalysis: currentAnalysis,\n });\n initialDataRef.current = {\n nodes: projected.nodes,\n edges: projected.edges,\n _analysis: projected.analysis,\n _graphspec: currentGraphspec,\n _graphStyle: style,\n ...(projected.standIns ? { _standIns: projected.standIns } : {}),\n };\n\n void (async () => {\n try {\n const layouted = await getLayoutedElements(\n projected.nodes,\n projected.edges,\n directionRef.current,\n GRAPH_STYLES[style].layout ?? layoutConfigRef.current,\n currentGraphspec,\n projected.analysis,\n );\n if (cancelled) return;\n layoutCacheRef.current = {\n nodes: layouted.nodes,\n edges: layouted.edges,\n controllerPositions: layouted.controllerPositions,\n graphspec: currentGraphspec,\n graphStyle: style,\n };\n const withControllers = frameLayout(style, layouted, currentGraphspec, projected.analysis);\n setNodes(decorateNodes(withControllers.nodes));\n setEdges(toAppEdges(withControllers.edges));\n setTimeout(() => {\n if (!cancelled && reactFlowRef.current) {\n void 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 const cache = layoutCacheRef.current;\n const data = initialDataRef.current;\n // Mid-swap guard — see the layoutCacheRef.graphspec doc comment.\n if (!cache || !data || !cacheMatchesData()) return;\n const withControllers = frameLayout(cache.graphStyle, cache, data._graphspec, data._analysis);\n setNodes(decorateNodes(withControllers.nodes));\n setEdges(toAppEdges(withControllers.edges));\n }, [statusMap, decorateNodes]);\n\n // Re-stamp validation decorations when the issues change (reuses cached\n // layout — a verdict flip must never re-run ELK or reset the viewport).\n React.useEffect(() => {\n const cache = layoutCacheRef.current;\n const data = initialDataRef.current;\n // Mid-swap guard: when graphspec and validationIssues change in the same\n // commit (a host delivering a new file plus its known issues at once), the\n // cache still holds the OLD graphspec's nodes until the async layout lands\n // — rebuilding from it against the new spec would render garbage. The\n // in-flight graphspec build stamps the fresh issues itself via\n // decorateNodes, so skipping here loses nothing.\n if (!cache || !data || !cacheMatchesData()) return;\n const withControllers = frameLayout(cache.graphStyle, cache, data._graphspec, data._analysis);\n setNodes(decorateNodes(withControllers.nodes));\n // validationWidgetAvailable: badge clickability must follow widget\n // visibility (validationState / hideToolbar flips re-stamp the handler).\n }, [validationIssues, validationWidgetAvailable, decorateNodes]);\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 // A binding card names the path it binds, not a pipe, so there is no pipe to navigate to.\n if ((nodeData.isController || nodeData.isPipe) && nodeData.pipeType !== BINDING_STEP_TYPE) {\n const code = nodeData.pipeCode || nodeData.labelText;\n if (code && onNavigateToPipe) {\n onNavigateToPipe(code, nodeRunStatus(nodeData));\n }\n } else if (nodeData.isStuff && onStuffNodeClick && graphspec) {\n const found = findStuffByDigest(graphspec, stuffDigestFromId(node.id));\n if (found) onStuffNodeClick(found.item);\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 found = findStuffByDigest(graphspec, stuffDigestFromId(node.id));\n setDetailSelection({\n kind: \"stuff\",\n nodeId: node.id,\n nodeData,\n stuffData: found?.item,\n producerPipeRef: found?.producerPipeRef,\n consumer: found?.consumer,\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 card's GraphSpecNode for the detail panel — by node id,\n // since a pipe code does not name one node: two invocations of a pipe share\n // it, and so do two bindings of one path. A pipe card, a controller group and\n // a folded controller's card all carry their spec node's id.\n const selectedSpecNode =\n detailSelection?.kind === \"pipe\" && graphspec\n ? graphspec.nodes.find((n) => n.id === detailSelection.nodeId)\n : undefined;\n\n const detailOpen = detailSelection !== null || conceptOverride !== null;\n\n // Controlled + reactive: resolved on every render (no local state) so a new\n // `toolbarPosition` prop or `config.toolbarPosition` propagates immediately.\n const effectiveToolbarPosition = resolveToolbarPosition(\n toolbarPositionProp,\n config.toolbarPosition,\n );\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 // Fold-all and expand-all, where the style supports them; a style whose folds\n // are undone from controller frames offers them only while those are shown.\n const foldControlsAvailable =\n styleCapabilities.foldAll && (!styleCapabilities.controllerFrameToggle || showControllers);\n const foldAllProps = React.useMemo(() => {\n if (!foldControlsAvailable || !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: () => {\n markReaderFolds(allControllerIds, true);\n setFoldedControllers(new Set(allControllerIds));\n },\n onExpandAll: () => {\n markReaderFolds(allControllerIds, false);\n setFoldedControllers(new Set());\n },\n foldAllDisabled: foldedControllers.size === allControllerIds.size,\n expandAllDisabled: foldedControllers.size === 0,\n };\n }, [foldControlsAvailable, allControllerIds, foldedControllers, markReaderFolds]);\n\n const styleMenuOptions = React.useMemo(() => resolveStyleMenu(styleMenu), [styleMenu]);\n\n return (\n <div\n ref={containerRef}\n className={`react-flow-container react-flow-container--theme-${resolvedTheme} react-flow-container--mode-${mode}`}\n >\n <ReactFlow\n nodes={nodes}\n edges={edges}\n nodeTypes={nodeTypes}\n edgeTypes={edgeTypes}\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 {!hideToolbar && (\n <GraphToolbar\n direction={direction}\n onDirectionChange={setDirection}\n showControllers={showControllers}\n onShowControllersChange={\n styleCapabilities.controllerFrameToggle ? setShowControllers : undefined\n }\n graphStyle={graphStyle}\n styleMenuOptions={styleMenuOptions}\n onGraphStyleChange={setGraphStyle}\n onZoomIn={() => {\n void reactFlowRef.current?.zoomIn();\n }}\n onZoomOut={() => {\n void reactFlowRef.current?.zoomOut();\n }}\n onFitView={() => {\n void reactFlowRef.current?.fitView({ padding: 0.1 });\n }}\n onFoldAll={foldAllProps.onFoldAll}\n onExpandAll={foldAllProps.onExpandAll}\n foldAllDisabled={foldAllProps.foldAllDisabled}\n expandAllDisabled={foldAllProps.expandAllDisabled}\n themeMode={showThemeToggle ? mode : undefined}\n onThemeModeChange={showThemeToggle ? setMode : undefined}\n rightOffset={detailOpen ? panelWidth : 0}\n position={effectiveToolbarPosition}\n validationState={validationState}\n validationIssues={validationIssues}\n // Always the wrapped handler: it optionally calls the host's\n // source-jump and, independently, pans/flashes to the issue's target\n // node — a built-in that works without a host handler, so rows stay\n // interactive whether or not the host wired `onValidationIssueClick`.\n onValidationIssueClick={handleValidationIssueClick}\n validationOpen={validationOpen}\n onValidationOpenChange={setValidationOpen}\n />\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 nodeId={detailSelection.nodeId}\n stuffData={detailSelection.stuffData}\n producerPipeRef={detailSelection.producerPipeRef}\n consumer={detailSelection.consumer}\n graphspec={graphspec}\n theme={resolvedTheme}\n artifacts={graph}\n resolveUrl={resolveUrl}\n resolveShareUrl={resolveShareUrl}\n saveFiles={saveFiles}\n downloads={downloads}\n />\n ) : null}\n {renderDetailExtra &&\n detailSelection &&\n !conceptOverride &&\n renderDetailExtra(detailSelection.nodeId, detailSelection.nodeData)}\n </DetailPanel>\n </div>\n );\n}\n","/**\n * Resolve the host environment's color scheme to a binary `GraphTheme`.\n *\n * In a browser this follows `prefers-color-scheme` live. Non-browser hosts (a\n * VS Code webview, where `prefers-color-scheme` is historically flaky) stay\n * authoritative by injecting `systemTheme` — the hook then returns it verbatim\n * and re-renders are driven by the host updating that value.\n *\n * Keeping the `matchMedia` logic in a hook (not inline in GraphViewer) mirrors\n * how the standalone isolated it for testing, and lets the pure\n * `detectSystemTheme` seam be unit-tested without rendering.\n */\nimport React from \"react\";\nimport { GRAPH_THEME, type GraphTheme } from \"@graph/types\";\n\nconst PREFERS_DARK_QUERY = \"(prefers-color-scheme: dark)\";\n\n/** Map a `prefers-color-scheme: dark` match result to a resolved theme. */\nexport function prefersDarkToTheme(prefersDark: boolean): GraphTheme {\n return prefersDark ? GRAPH_THEME.DARK : GRAPH_THEME.LIGHT;\n}\n\n/**\n * Read the environment's current color scheme once. SSR / no-`matchMedia` safe:\n * defaults to `dark` when `window.matchMedia` is unavailable. Exported so\n * non-React callers (e.g. the standalone adapter's initial body-palette paint,\n * before any `onThemeChange` fires) can resolve `system` the same way the hook does.\n */\nexport function detectSystemTheme(): GraphTheme {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") {\n return GRAPH_THEME.DARK;\n }\n return prefersDarkToTheme(window.matchMedia(PREFERS_DARK_QUERY).matches);\n}\n\n/**\n * Subscribe to `prefers-color-scheme` changes, invoking `onChange` on each flip.\n * Returns an unsubscribe. SSR / no-`matchMedia` safe: returns a no-op.\n *\n * Older WebKit, some Electron builds, and certain VS Code webview hosts expose\n * a `MediaQueryList` with only the legacy `addListener`/`removeListener` API.\n * Calling `addEventListener` unconditionally throws there — and because this\n * runs inside the `useSyncExternalStore` subscribe during render, the throw\n * crashes the whole GraphViewer (blank graph) on exactly the webview host\n * class the `systemTheme` prop exists to support. Prefer the modern API, fall\n * back to the legacy one (mirrors the deleted standalone `pageTheme.ts`).\n *\n * Exported as a pure seam so the modern/legacy/SSR branches can be unit-tested\n * in a node env (no renderer) — see `__tests__/useSystemTheme.test.ts`.\n */\nexport function subscribeToSystemTheme(onChange: () => void): () => void {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") {\n return () => {};\n }\n const mql = window.matchMedia(PREFERS_DARK_QUERY);\n if (typeof mql.addEventListener === \"function\") {\n mql.addEventListener(\"change\", onChange);\n return () => mql.removeEventListener(\"change\", onChange);\n }\n mql.addListener(onChange);\n return () => mql.removeListener(onChange);\n}\n\n/** The `useSyncExternalStore` triple `useSystemTheme` drives. */\nexport interface SystemThemeStore {\n subscribe: (onChange: () => void) => () => void;\n getSnapshot: () => GraphTheme;\n getServerSnapshot: () => GraphTheme;\n}\n\n/**\n * Build the `useSyncExternalStore` triple for a given `injected` value.\n *\n * - `injected` set → host owns detection: `subscribe` is a no-op (no live\n * `matchMedia` listener is ever registered) and both snapshots return\n * `injected`. Spending an OS listener + per-render `detectSystemTheme` on a\n * result we'd discard is pure waste — and wrong to keep alive on the very\n * webview hosts where `prefers-color-scheme` is unreliable.\n * - otherwise → subscribe to `prefers-color-scheme` live; the server snapshot\n * falls back to `dark` (see `docs/theming.md` → \"SSR\").\n *\n * Pure + exported so the injected-skip path is unit-testable without a renderer.\n */\nexport function systemThemeStore(injected?: GraphTheme): SystemThemeStore {\n if (injected !== undefined) {\n return {\n subscribe: () => () => {},\n getSnapshot: () => injected,\n getServerSnapshot: () => injected,\n };\n }\n return {\n subscribe: subscribeToSystemTheme,\n getSnapshot: detectSystemTheme,\n getServerSnapshot: () => GRAPH_THEME.DARK,\n };\n}\n\n/**\n * Resolved environment theme.\n *\n * - `injected` set → return it (host owns detection; host re-renders drive\n * updates). No live `matchMedia` subscription is registered.\n * - otherwise → subscribe to `prefers-color-scheme` and re-render on `change`.\n *\n * Uses `useSyncExternalStore` so the subscription is concurrent-safe. The hook\n * is always called (rules-of-hooks); only the `systemThemeStore` triple branches\n * on `injected`, memoized so the `subscribe` reference stays stable across\n * renders (no re-subscribe churn). SSR with no injected value falls back to\n * `dark` via the server snapshot — see `docs/theming.md` → \"SSR\" for the\n * consequence and the recommended `theme` / `systemTheme` pinning.\n */\nexport function useSystemTheme(injected?: GraphTheme): GraphTheme {\n const store = React.useMemo(() => systemThemeStore(injected), [injected]);\n return React.useSyncExternalStore(store.subscribe, store.getSnapshot, store.getServerSnapshot);\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport {\n buildResultField,\n getPipeInputForm,\n getPipeIOContract,\n getPipeOutputForm,\n type InputForm,\n type OutputForm,\n type PipeIOContracts,\n type RunField,\n type SaveFiles,\n} from \"@pipelex/mthds-form\";\nimport {\n JsonView,\n ResultEnvProvider,\n StuffViewer,\n useFieldStrings,\n type DownloadDisplay,\n type ResolveShareUrl,\n type ResolveUrl,\n} from \"@pipelex/mthds-form/react\";\nimport { parsePipeRef } from \"@graph/pipeRefs\";\nimport type { ConceptInfo, GraphSpecNodeIoItem, GraphTheme } from \"@graph/types\";\n\n/**\n * The graph's stuff panel — the replacement for `StuffViewer`.\n *\n * ## What changed, and why it is not a reskin\n *\n * `StuffViewer` had three tabs — HTML, JSON, Pretty — and that was an admission:\n * a `GraphSpec` states a concept and a payload, and nothing about what the\n * payload IS, so the only honest thing it could do was hand the reader three\n * renderings and let them pick. It sniffed for URLs, guessed MIME types from\n * file extensions, and ran any `data_html` through DOMPurify because the markup\n * was model output going into the host's own document.\n *\n * None of that guessing is necessary, because the standard answers the question\n * in an artifact built for it. `output_form` gives a pipe's result ONE\n * descriptor node — kind, concept identity, refinement chain, nested fields in\n * authored order — and the output half of `pipe_io_contracts` gives the\n * payload's JSON Schema beside it, naming the property the content model wraps\n * the value under. `buildResultField` pairs them into a `RunField`, and\n * `StuffViewer` lays that out without ever inspecting the value: a table for a\n * list of records, a gallery for images, a sandboxed frame for markup, a\n * two-column grid for a structure. The JSON view survives as one of the panel's\n * two, because a receipt is worth having; \"Pretty\" and \"HTML\" do not, because\n * they were two guesses at a question now answered.\n *\n * ## What it needs from the host, and why\n *\n * The artifacts a run's results (or a `/validate` call) return beside the graph\n * spec, keyed by `pipe_ref`. The join is the producing pipe: the graph hands\n * over `producerPipeRef` (see `stuffLookup.ts`), and `output_form` plus the\n * output half of the contract are looked up by it. That join only holds when\n * the artifacts and the graph come from the same source, which is why\n * `GraphViewer` takes them as one `graph` object (`GraphArtifacts`).\n *\n * ## The method's own inputs, which no pipe produced\n *\n * They have no `producerPipeRef`, so no output descriptor describes them — and\n * showing nothing for the top of every graph is not acceptable, because a\n * method's arguments are as much a part of what happened as its results. What\n * DOES describe them is the CONSUMING pipe's `input_form` entry for the slot\n * they arrive in: the same field, seen from the other side. So `inputForm` is\n * an optional third artifact, and when it is supplied the panel falls back to\n * it.\n *\n * **Only on the `single` arm, and that is a correctness boundary rather than a\n * conservative default.** An input's `json_schema` describes what a CALLER\n * SENDS, so a plural slot's is a bare array; a stuff's payload is what the\n * runtime HOLDS, which for a plural value is a `ListContent {items}` envelope.\n * The two disagree exactly where the standard says they do, and rendering a\n * plural input against its caller-side schema would unwrap by a property that\n * is not there. On the single arm the two are byte-identical by construction —\n * both are `render_stuff_spec`'s output — so the fallback is exact there and\n * declines everywhere else.\n *\n * ## Stored files\n *\n * It does not resolve `pipelex-storage://` URIs itself. A host that can passes\n * `resolveUrl`, which is installed as the kernel's `ResultEnvProvider` so the\n * kernel's own file arms paint the file; without one, the panel paints whatever\n * `public_url` the payload carries.\n *\n * ## Saving\n *\n * The kernel's Download control and its per-file download buttons save through\n * the browser tab unless a host says otherwise. A host whose view runs in a\n * sandboxed frame, where the tab's object URL, clicked link and popup are all\n * refused, passes `saveFiles` to deliver the files through its own bridge, and\n * `downloads` to choose which of those controls are drawn. Both go on the same\n * provider as `resolveUrl`, because the kernel's provider replaces an outer\n * one rather than merging with it: set around the graph instead, they would\n * never reach a panel that installs its own.\n */\nexport interface StuffResultRendererOptions {\n /**\n * `pipe_io_contracts` from the same source as the `producerPipeRef` and\n * `consumer` below: the run, or the validate report, whose graph they were\n * read from. Inside `GraphViewer` that pairing is guaranteed by its single\n * `graph` prop; a host using this panel on its own owns it.\n */\n pipeIoContracts: PipeIOContracts;\n /** `output_form` from that SAME source. */\n outputForm: OutputForm;\n /**\n * `input_form`, optional. Supplying it is what lets a method's own INPUTS\n * render as described fields rather than as nothing: they have no producing\n * pipe, so the consuming pipe's descriptor for their slot is what names them.\n */\n inputForm?: InputForm;\n}\n\nexport interface StuffResultPanelProps extends StuffResultRendererOptions {\n /** The data item as the spec holds it. */\n stuff: GraphSpecNodeIoItem;\n /** Its concept, resolved against the spec's concept table, when it has one. */\n concept?: ConceptInfo;\n /**\n * `domain.code` of the pipe that PRODUCED it — the key both output artifacts\n * are keyed by. Absent for a method's own inputs, which no pipe produced.\n */\n producerPipeRef?: string;\n /**\n * The first pipe that CONSUMES it, and the slot it arrives in — the fallback\n * identity for those method inputs.\n */\n consumer?: { pipeRef: string; slotName: string };\n /** The viewer's resolved theme, so the panel matches the chrome it sits in. */\n theme?: GraphTheme;\n /**\n * Turns the runtime's own `pipelex-storage://…` reference into something a\n * browser can fetch.\n *\n * Supply it and the panel paints files through it; omit it and the panel\n * falls back to whatever `public_url` the payload carries. On the hosted\n * platform that fallback is a PRESIGNED S3 URL with an hour's life, baked\n * into the stored result — so a run opened the next morning shows broken\n * images, and the URL answers `403` in a way that reads as a permissions\n * problem rather than an expiry. A resolver is what makes a result durable.\n */\n resolveUrl?: ResolveUrl;\n /**\n * Mints a URL that works OUTSIDE this page — what the copy control hands over.\n * A display URL may sit behind the host's session; a shared one carries its\n * own credential.\n */\n resolveShareUrl?: ResolveShareUrl;\n /**\n * Delivers the files a download hands over, for a host that cannot save\n * through the browser tab. Without one, the kernel saves in the tab.\n */\n saveFiles?: SaveFiles;\n /**\n * Which download controls are drawn: the whole-result Download and each\n * file's own button, set independently. Both are drawn by default.\n */\n downloads?: DownloadDisplay;\n}\n\nexport function StuffResultPanel({\n pipeIoContracts,\n outputForm,\n inputForm,\n stuff,\n producerPipeRef,\n consumer,\n resolveUrl,\n resolveShareUrl,\n saveFiles,\n downloads,\n}: StuffResultPanelProps) {\n const field = React.useMemo(\n () =>\n fromProducer(pipeIoContracts, outputForm, producerPipeRef) ??\n fromConsumer(pipeIoContracts, inputForm, consumer),\n [pipeIoContracts, outputForm, inputForm, producerPipeRef, consumer],\n );\n\n if (field) {\n // The STUFF's name, not the descriptor's. `build_output_form` names every\n // pipe's root node `output` - correct in the artifact, where the descriptor\n // describes an output SLOT with no name of its own, and wrong on screen,\n // where the reader has just clicked a node called `report_pages` and every\n // other surface calls it that. The graph is the one that knows, so the\n // graph is the one that says.\n const panel = <StuffViewer field={field} value={stuff.data} name={stuff.name} />;\n // Installed only when the host said something, so a host that wraps the\n // whole graph in its own provider still reaches a panel given nothing.\n return resolveUrl || resolveShareUrl || saveFiles || downloads ? (\n <ResultEnvProvider\n resolveUrl={resolveUrl}\n resolveShareUrl={resolveShareUrl}\n saveFiles={saveFiles}\n downloads={downloads}\n >\n {panel}\n </ResultEnvProvider>\n ) : (\n panel\n );\n }\n\n // No descriptor, but there IS a value. Show it, and say why it is not laid\n // out.\n //\n // Returning null here was the first behaviour and it was wrong in the way\n // that matters: a reader looking at a finished run saw a schema table, no\n // data tab, and no reason — indistinguishable from a broken view. The two\n // artifacts are opt-in `views` on `/validate` and an engine that predates\n // them simply omits them, so \"the server has not got them yet\" is an ordinary\n // state a host will be in, not an edge case.\n //\n // This is not `StuffViewer` coming back. That offered three renderings as a\n // CHOICE because it could not tell what the value was; this is one labelled\n // fallback that names its own cause and disappears the moment the descriptor\n // arrives.\n return stuff.data === undefined || stuff.data === null ? null : (\n <UndescribedValue value={stuff.data} />\n );\n}\n\nfunction UndescribedValue({ value }: { value: unknown }) {\n const s = useFieldStrings();\n return (\n <div className=\"space-y-2\">\n <p className=\"text-[12px] text-muted-foreground\">{s.resultUndescribed}</p>\n <JsonView value={value} />\n </div>\n );\n}\n\n/** The normal case: the pipe that resolved to this value describes it. */\nfunction fromProducer(\n contracts: PipeIOContracts,\n outputForm: OutputForm,\n producerPipeRef: string | undefined,\n): RunField | null {\n if (!producerPipeRef) return null;\n const parsed = parsePipeRef(producerPipeRef);\n if (!parsed?.domainPath) return null;\n const descriptor = getPipeOutputForm(outputForm, parsed.domainPath, parsed.pipeCode);\n const contract = getPipeIOContract(contracts, parsed.domainPath, parsed.pipeCode);\n // Both or neither, the same rule the input side follows: the descriptor says\n // what the result IS and the schema says what shape it arrives in, and a\n // renderer given one of the two would be guessing the other.\n if (!descriptor || !contract) return null;\n return buildResultField(descriptor, contract.output.json_schema);\n}\n\n/**\n * The fallback for a method's own input: the pipe that READS it describes it.\n *\n * Single-valued slots only. See the component's note — a plural input's schema\n * is the caller-side bare array, and the payload is a `ListContent` envelope, so\n * the fallback would unwrap by a property that is not there.\n */\nfunction fromConsumer(\n contracts: PipeIOContracts,\n inputForm: InputForm | undefined,\n consumer: { pipeRef: string; slotName: string } | undefined,\n): RunField | null {\n if (!inputForm || !consumer) return null;\n const parsed = parsePipeRef(consumer.pipeRef);\n if (!parsed?.domainPath) return null;\n const descriptor = getPipeInputForm(inputForm, parsed.domainPath, parsed.pipeCode);\n const contract = getPipeIOContract(contracts, parsed.domainPath, parsed.pipeCode);\n if (!descriptor || !contract) return null;\n const slot = contract.inputs[consumer.slotName];\n if (!slot || slot.multiplicity !== \"single\") return null;\n const node = descriptor.fields.find(\n (candidate: { name: string }) => candidate.name === consumer.slotName,\n );\n if (!node) return null;\n // Wrapped into the OUTPUT descriptor's shape, which is what `buildResultField`\n // takes. That is not a cheat: the two descriptors' nodes are the same\n // recursive vocabulary, and the wrapper's only job is to say \"one field, and\n // here it is\". The pipe-slot facts the input node also carries (`presence`,\n // `gating`) describe how a caller must fill it and mean nothing to a value\n // that has already arrived, so they are simply not read.\n return buildResultField({ field: node }, slot.json_schema);\n}\n","import type { InputForm, OutputForm, PipeIOContracts } from \"@pipelex/mthds-form\";\nimport type { GraphSpec } from \"@graph/types\";\n\n/**\n * A graph and the artifacts that describe its pipes, taken from ONE source.\n *\n * `GraphViewer` takes this as its single `graph` prop rather than a spec and\n * three descriptor props side by side, because the descriptors are keyed by the\n * graph's own `pipe_ref`s: the detail panel walks from a data node back to the\n * pipe that produced it and looks that pipe up in `outputForm` and\n * `pipeIoContracts`. A spec paired with another source's descriptors (a past\n * run's graph beside the current method's validate report, after the method's\n * pipes were renamed) misses every lookup, and the panel can only say that no\n * descriptor describes the value. Carrying all four in one object is what keeps\n * them from one run, or from one validate call.\n *\n * Where each source lives:\n *\n * - **A run**: its results carry `graph_spec`, `pipe_io_contracts`,\n * `output_form` and `input_form` together; `graphArtifactsFrom(results)`\n * reads them in one call.\n * - **A method that has not run** (a dry run, or a static graph built from its\n * sources): the descriptors come from the same method's validate report, the\n * one the dry graph or the static build describes.\n *\n * The descriptors are optional, and nullable as the wire carries them. Without\n * `pipeIoContracts` and `outputForm` together, the panel shows a data node's\n * structure table and no data tab, which is the honest floor for a graph whose\n * artifacts were not produced. `inputForm` is optional even beside the other\n * two: it is what lets a method's own inputs, which no pipe produced, show their\n * value through the consuming pipe's slot.\n */\nexport interface GraphArtifacts {\n /** The graph to draw: a run's `graph_spec`, a dry run's, or a static build. */\n graphSpec: GraphSpec;\n /** `pipe_io_contracts` for the pipes of THIS graph. */\n pipeIoContracts?: PipeIOContracts | null;\n /** `output_form` for the pipes of THIS graph, from the same source. */\n outputForm?: OutputForm | null;\n /** `input_form` for the pipes of THIS graph, from the same source. */\n inputForm?: InputForm | null;\n}\n\n/**\n * The four artifacts as a run's results, or a validate report, spell them on\n * the wire. `graph_spec` is `unknown` because transport layers type it that way;\n * `GraphViewer` validates it at its boundary.\n */\nexport interface GraphArtifactsSource {\n graph_spec?: unknown;\n pipe_io_contracts?: PipeIOContracts | null;\n output_form?: OutputForm | null;\n input_form?: InputForm | null;\n}\n\n/**\n * Read the graph and its descriptors out of one run's results (or one report\n * that carries all four), so a host never assembles the bundle by hand from two\n * places. Returns `null` when the source carries no graph.\n */\nexport function graphArtifactsFrom(source: GraphArtifactsSource): GraphArtifacts | null {\n if (source.graph_spec === undefined || source.graph_spec === null) return null;\n return {\n graphSpec: source.graph_spec as GraphSpec,\n pipeIoContracts: source.pipe_io_contracts ?? null,\n outputForm: source.output_form ?? null,\n inputForm: source.input_form ?? null,\n };\n}\n\n/** The descriptors the detail panel renders a value from, once they are usable. */\nexport interface ResultDescriptors {\n pipeIoContracts: PipeIOContracts;\n outputForm: OutputForm;\n inputForm?: InputForm;\n}\n\n/**\n * The descriptors a graph's detail panel can render from, or `null`.\n *\n * Both `pipeIoContracts` and `outputForm`, or neither: the contract names the\n * payload's shape and the descriptor says what the result IS, so a panel given\n * one of the two would be guessing the other. `inputForm` rides along when the\n * other two are there.\n */\nexport function resultDescriptors(graph: GraphArtifacts | null): ResultDescriptors | null {\n const pipeIoContracts = graph?.pipeIoContracts;\n const outputForm = graph?.outputForm;\n if (!pipeIoContracts || !outputForm) return null;\n const inputForm = graph?.inputForm;\n return inputForm ? { pipeIoContracts, outputForm, inputForm } : { pipeIoContracts, outputForm };\n}\n","import React from \"react\";\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 <div className=\"detail-panel-content\">\n {/* Inside the scroll flow ON PURPOSE: the close button belongs to the\n top of the content and scrolls away with it — closing the panel\n means going back up. Do not pin it to the panel. */}\n <div className=\"detail-panel-close-row\">\n <button className=\"detail-panel-close\" onClick={onClose} aria-label=\"Close panel\">\n x\n </button>\n </div>\n {children}\n </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 {\n GraphSpecModelUsage,\n GraphSpecNode,\n NodePipeType,\n PipeBlueprintUnion,\n GraphSpec,\n} from \"@graph/types\";\nimport { isBindingNode, isDryGraphSpec, isStaticGraphSpec, multiplicitySuffix } from \"@graph/types\";\nimport { getPipeBlueprint } from \"@graph/graphAnalysis\";\nimport {\n formatDuration,\n KV,\n BindingStepSection,\n PipeLLMSection,\n PipeImgGenSection,\n PipeExtractSection,\n PipeSearchSection,\n PipeStructureSection,\n PipeComposeSection,\n PipeConditionSection,\n PipeSequenceSection,\n PipeParallelSection,\n PipeBatchSection,\n UsageCostInline,\n UsageDetails,\n shouldDumpExecutionData,\n} from \"./sections\";\n\n// ─── Badge / Status config ─────────────────────────────────────────────\n\nconst PIPE_TYPE_BADGES: Record<NodePipeType, string> = {\n PipeLLM: \"LLM\",\n PipeExtract: \"Extract\",\n PipeCompose: \"Compose\",\n PipeImgGen: \"ImgGen\",\n PipeSearch: \"Search\",\n PipeFunc: \"Func\",\n PipeStructure: \"Structure\",\n PipeJudge: \"Judge\",\n PipeDocGen: \"DocGen\",\n PipeSignature: \"Signature\",\n PipeSequence: \"Seq\",\n PipeParallel: \"Par\",\n PipeCondition: \"Cond\",\n PipeBatch: \"Batch\",\n BindingStep: \"Binding\",\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 canceled: \"#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;\n const isController = CONTROLLER_TYPES.has(pipeType);\n // A binding step runs no pipe, so the registry holds no blueprint for it: its\n // own section says what it binds, and no \"Blueprint not available\" is shown.\n const isBinding = isBindingNode(node);\n const isStatic = isStaticGraphSpec(spec);\n const showsGeneratedData = !isStatic && !isDryGraphSpec(spec);\n const badge = PIPE_TYPE_BADGES[pipeType];\n const status = node.status;\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 (isBinding || !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;\n }\n return undefined;\n }, [isBinding, node.pipe_code, spec]);\n\n const [usageExpanded, setUsageExpanded] = React.useState(false);\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}\n </span>\n </div>\n\n {/* Status + Duration + Cost — three facts about the same run, on one\n line. Cost is gated on showsGeneratedData, i.e. a real run: a dry run\n executes nothing, so its usage counts are simulated and stating a\n price (even \"none\") would answer a question that does not apply. */}\n {!isStatic && (\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 {showsGeneratedData && node.usage && (\n <UsageCostInline\n usage={node.usage}\n isController={isController}\n expanded={usageExpanded}\n onToggle={() => setUsageExpanded((value) => !value)}\n />\n )}\n </div>\n )}\n\n {showsGeneratedData && node.usage && usageExpanded && (\n <UsageDetails usage={node.usage} isController={isController} />\n )}\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}</span>\n {input.concept && (\n <span className=\"detail-io-concept\">\n {input.concept + multiplicitySuffix(input.multiplicity)}\n </span>\n )}\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}</span>\n {output.concept && (\n <span className=\"detail-io-concept\">\n {output.concept + multiplicitySuffix(output.multiplicity)}\n </span>\n )}\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 {/* What a binding step binds — structural, so shown in every mode */}\n {isBinding && <BindingStepSection node={node} />}\n\n {/* Blueprint-specific sections */}\n {blueprint && (\n <BlueprintSection\n blueprint={blueprint}\n executionData={showsGeneratedData ? node.execution_data : undefined}\n modelsRan={showsGeneratedData ? node.usage?.by_model : undefined}\n // Model resolution is NOT gated on showsGeneratedData, unlike every other\n // execution_data field. Resolving `@default-general` to `claude-4.6-sonnet`\n // is a deterministic deck lookup, not a measurement of a run — a dry spec\n // carries it too, and hiding it there left the Model row showing an alias\n // with nothing under it.\n modelHandles={node.execution_data}\n />\n )}\n\n {/* Execution data (runtime-resolved values) — a binding's is its section above */}\n {showsGeneratedData &&\n !isBinding &&\n node.execution_data &&\n Object.keys(node.execution_data).length > 0 && (\n <ExecutionDataSection\n executionData={node.execution_data}\n pipeType={pipeType}\n hasBlueprint={!!blueprint}\n />\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 {showsGeneratedData && 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 && !isBinding && (\n <div className=\"detail-not-available\">Blueprint not available</div>\n )}\n </>\n );\n}\n\n// ─── Blueprint dispatch ─────────────────────────────────────────────────────\n\nfunction BlueprintSection({\n blueprint,\n executionData,\n modelsRan,\n modelHandles,\n}: {\n blueprint: PipeBlueprintUnion;\n executionData?: Record<string, unknown>;\n /** Models that actually ran on this node — see ModelRows in ./sections/shared. */\n modelsRan?: GraphSpecModelUsage[];\n /** execution_data, ungated: the deck-resolved model handle is available in dry specs too. */\n modelHandles?: Record<string, unknown>;\n}) {\n switch (blueprint.type) {\n case \"PipeLLM\":\n return (\n <PipeLLMSection\n blueprint={blueprint}\n executionData={executionData}\n modelsRan={modelsRan}\n modelHandles={modelHandles}\n />\n );\n case \"PipeImgGen\":\n return (\n <PipeImgGenSection\n blueprint={blueprint}\n executionData={executionData}\n modelsRan={modelsRan}\n modelHandles={modelHandles}\n />\n );\n case \"PipeCompose\":\n return <PipeComposeSection blueprint={blueprint} executionData={executionData} />;\n case \"PipeExtract\":\n return (\n <PipeExtractSection\n blueprint={blueprint}\n modelsRan={modelsRan}\n modelHandles={modelHandles}\n />\n );\n case \"PipeSearch\":\n return (\n <PipeSearchSection\n blueprint={blueprint}\n executionData={executionData}\n modelsRan={modelsRan}\n modelHandles={modelHandles}\n />\n );\n case \"PipeStructure\":\n return (\n <PipeStructureSection\n blueprint={blueprint}\n executionData={executionData}\n modelsRan={modelsRan}\n modelHandles={modelHandles}\n />\n );\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 case \"PipeSignature\":\n return (\n <div className=\"detail-not-available\">\n Signature stub — declared but not yet implemented.\n </div>\n );\n default:\n // Defensive: a blueprint whose `type` the renderer doesn't know yet\n // (runtime ahead of this library) degrades to no extra section.\n return null;\n }\n}\n\n// ─── Execution data dispatch ────────────────────────────────────────────────\n\nfunction ExecutionDataSection({\n executionData,\n pipeType,\n hasBlueprint,\n}: {\n executionData: Record<string, unknown>;\n pipeType: string;\n hasBlueprint: boolean;\n}) {\n // Known pipe types merge their runtime data into the blueprint section, so\n // there is nothing extra to render once that section mounted. The raw dump is\n // only shown when the blueprint failed to resolve (so runtime data isn't lost)\n // or for types without a merged section (PipeFunc, PipeSignature, unknown).\n if (!shouldDumpExecutionData(pipeType, hasBlueprint)) return null;\n return <GenericExecutionData data={executionData} />;\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\";\nimport type { GraphSpecModelUsage as ModelUsage } from \"@graph/types\";\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\n/**\n * The Model row: the resolution chain, top to bottom.\n *\n * A model reaches an LLM call through up to three rungs, and which ones are\n * distinct depends on the run:\n *\n * authored what the .mthds says `@default-general`, or a preset `$writing-factual`\n * handle execution_data.resolved_model — the LLMSetting's model at capture time.\n * Confusingly named: in a LIVE run the alias has already been resolved by\n * the time it is captured, so this reads `claude-4.6-sonnet`; in a DRY run\n * nothing resolves it and it stays `@default-general`.\n * ran usage.by_model — the model that actually served the call (LIVE only).\n *\n * Rendering only the last known rung hides the alias on a live run; rendering only the\n * first hides the model. So all of them are shown, deduped, request on top. When they\n * collapse to one value there is one line and nothing to explain.\n *\n * A node that used several models (a PipeLLM's text pass and object pass resolve\n * separately) lists each with its call count.\n */\nexport function ModelRows({\n modelsRan,\n authored,\n handle,\n label = \"Model\",\n}: {\n modelsRan?: ModelUsage[];\n /** What the method declares — the truest statement of intent. */\n authored?: string | null;\n /** execution_data.resolved_model: an alias in a dry run, usually concrete in a live one. */\n handle?: string | null;\n label?: string;\n}) {\n const ran = modelsRan ?? [];\n const ranLabels = ran.map((entry) =>\n ran.length > 1\n ? `${entry.inference_model_name} (${entry.inference_calls})`\n : entry.inference_model_name,\n );\n\n // Consecutive duplicates carry no information: an authored name that was never\n // aliased resolves to itself, and a handle already concrete equals what ran.\n const chain: string[] = [];\n for (const rung of [authored, handle, ...ranLabels]) {\n if (rung && rung !== chain[chain.length - 1]) chain.push(rung);\n }\n if (chain.length === 0) return null;\n\n return (\n <div className=\"detail-kv-row\">\n <span className=\"detail-kv-key\">{label}</span>\n <span className=\"detail-kv-value detail-model-value\">\n {chain.map((rung, index) => (\n <span key={rung} className={index === 0 ? undefined : \"detail-model-resolved\"}>\n {rung}\n </span>\n ))}\n </span>\n </div>\n );\n}\n","/**\n * Presentation rules for per-node inference usage.\n *\n * Pure, React-free, and the single place the `GraphSpecNodeUsage` invariants are\n * turned into something a human reads. The invariants themselves live on the type\n * in `types.ts`; what this module adds is the rule that a *missing* dollar is\n * never printed as a zero one, and a *partial* dollar is never printed as a\n * complete one.\n *\n * Cost is a side-panel concern only — it is never rendered on a graph card.\n */\nimport type { GraphSpecModelUsage, GraphSpecNodeUsage } from \"./types\";\n\n/**\n * Which half of a usage object a node should be read through.\n *\n * A controller runs no inference itself — its own numbers are always zero — so\n * it must read the subtree half or it reports nothing at all. An operator is a\n * leaf and reads its own.\n */\nexport type UsageScope = \"own\" | \"subtree\";\n\n/** The scoped numbers, with the own/subtree distinction already resolved away. */\nexport interface ScopedUsage {\n scope: UsageScope;\n inferenceCalls: number;\n ratedInferenceCalls: number;\n /**\n * ⚠ NOT a token count for every pipe type — do not render these.\n *\n * Extract, search and image generation are billed per request, and pipelex\n * encodes that price by putting exactly `1_000_000` in each token category:\n * rates are per-million, so `1_000_000 x rate/1e6` reproduces the per-request\n * price exactly (see `linkup_extract_worker.py`, `extract_worker_abstract.py`).\n * A one-page extract therefore reports 2,000,000 \"tokens\".\n *\n * A controller's subtree total sums those sentinels with real LLM tokens, so\n * no token figure is trustworthy at any level of a graph. `cost` is the number\n * that survives the encoding; these are carried for completeness only.\n */\n nbTokensByCategory: Record<string, number>;\n /** ⚠ See `nbTokensByCategory` — not a token count for every pipe type. */\n totalTokens: number;\n cost: number | null;\n costInput: number | null;\n costOutput: number | null;\n models: GraphSpecModelUsage[];\n}\n\nexport function scopeUsage(usage: GraphSpecNodeUsage, scope: UsageScope): ScopedUsage {\n if (scope === \"subtree\") {\n return {\n scope,\n inferenceCalls: usage.subtree_inference_calls,\n ratedInferenceCalls: usage.subtree_rated_inference_calls,\n nbTokensByCategory: usage.subtree_nb_tokens_by_category,\n totalTokens: usage.subtree_total_tokens,\n cost: usage.subtree_cost,\n costInput: usage.subtree_cost_input,\n costOutput: usage.subtree_cost_output,\n models: usage.subtree_by_model,\n };\n }\n return {\n scope,\n inferenceCalls: usage.inference_calls,\n ratedInferenceCalls: usage.rated_inference_calls,\n nbTokensByCategory: usage.nb_tokens_by_category,\n totalTokens: usage.total_tokens,\n cost: usage.cost,\n costInput: usage.cost_input,\n costOutput: usage.cost_output,\n models: usage.by_model,\n };\n}\n\n/**\n * The four states a scoped usage can be rendered in.\n *\n * `ran-nothing` and an absent usage object both render as nothing, but they are\n * distinct upstream — see invariant 1 — and the detail panel says so.\n */\nexport type UsageState = \"ran-nothing\" | \"unrated\" | \"partial\" | \"rated\";\n\nexport function usageState(scoped: ScopedUsage): UsageState {\n if (scoped.inferenceCalls === 0) return \"ran-nothing\";\n if (scoped.cost === null) return \"unrated\";\n if (scoped.ratedInferenceCalls < scoped.inferenceCalls) return \"partial\";\n return \"rated\";\n}\n\n/**\n * USD at the same 4-decimal precision the pipelex cost table uses.\n *\n * A rated call that cost nothing is a real `$0.0000` and prints as such; a cost\n * too small to show at 4 decimals prints as `<$0.0001` rather than rounding to\n * zero, because \"rounded to nothing\" and \"cost nothing\" are different claims.\n */\nexport function formatCost(cost: number): string {\n if (cost > 0 && cost < 0.0001) return \"<$0.0001\";\n return `$${cost.toFixed(4)}`;\n}\n\n/**\n * Whether this scope's token counts are real measurements.\n *\n * True only when every model that ran is token-billed. Anything else is billed per\n * request, and pipelex encodes that price as `1_000_000` tokens per category — so a\n * mixed branch (an LLM beside an extract) has a token total that silently blends a\n * measurement with a request counter, and must not be displayed either.\n */\nexport function hasRealTokenCounts(scoped: ScopedUsage): boolean {\n return scoped.models.length > 0 && scoped.models.every((entry) => entry.model_type === \"llm\");\n}\n","import React from \"react\";\nimport type { GraphSpecNodeUsage } from \"@graph/types\";\nimport {\n formatCost,\n hasRealTokenCounts,\n scopeUsage,\n usageState,\n type ScopedUsage,\n} from \"@graph/usageFormat\";\nimport { KV } from \"./shared\";\n\n/**\n * Inference cost, rendered inline beside the status and duration.\n *\n * Cost belongs with the other facts about the run itself — it succeeded, it took\n * 23.57s, it cost $0.0138 — so it shares that line and that formatting rather\n * than claiming a block of its own. Everything else about usage (call counts,\n * the node's own figures vs its branch's) is a diagnostic and lives behind the\n * chevron. Token counts are shown nowhere — see UsageColumn for why.\n *\n * The cost text is honest about the three states rather than printing a number\n * in all of them: a real price, a lower bound when only some calls were priced,\n * and nothing at all when there is no price to give.\n *\n * The state lives in the panel, not here, because the trigger sits inside the\n * status row while the body renders below it.\n */\n\n/** Which half of the usage a node reports: a controller has only its branch. */\nexport function usageHeadlineScope(usage: GraphSpecNodeUsage, isController: boolean): ScopedUsage {\n return scopeUsage(usage, isController ? \"subtree\" : \"own\");\n}\n\nfunction costText(scoped: ScopedUsage): string | null {\n const state = usageState(scoped);\n // No inference, or nothing priced: there is no cost to state, and a \"0\" or a\n // \"—\" would each imply something. Say nothing.\n if (state === \"ran-nothing\" || state === \"unrated\") return null;\n const cost = formatCost(scoped.cost ?? 0);\n return state === \"partial\" ? `≥ ${cost}` : cost;\n}\n\nfunction costTitle(scoped: ScopedUsage, isController: boolean): string {\n const scopeWord = isController ? \"This pipe and everything below it\" : \"This pipe\";\n const state = usageState(scoped);\n if (state === \"partial\") {\n return `${scopeWord}: only ${scoped.ratedInferenceCalls} of ${scoped.inferenceCalls} calls were priced, so this is a lower bound. Click for details.`;\n }\n return `${scopeWord}: ${scoped.inferenceCalls} inference call(s). Click for the breakdown.`;\n}\n\n/** Thin chevron, deliberately quieter than the text it sits beside. */\nfunction Chevron({ open }: { open: boolean }) {\n return (\n <svg\n className={`detail-usage-chevron ${open ? \"detail-usage-chevron--open\" : \"\"}`}\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n );\n}\n\n/**\n * The inline cost + disclosure trigger. Returns null when there is no price to\n * show, so nothing appears beside the duration on a run that cost nothing.\n */\nexport function UsageCostInline({\n usage,\n isController,\n expanded,\n onToggle,\n}: {\n usage: GraphSpecNodeUsage;\n isController: boolean;\n expanded: boolean;\n onToggle: () => void;\n}) {\n const scoped = usageHeadlineScope(usage, isController);\n const text = costText(scoped);\n if (text === null) return null;\n\n return (\n <button\n type=\"button\"\n className=\"detail-usage-inline\"\n aria-expanded={expanded}\n onClick={onToggle}\n title={costTitle(scoped, isController)}\n >\n <span className=\"detail-usage-value\">{text}</span>\n <Chevron open={expanded} />\n </button>\n );\n}\n\n/**\n * The categories that get a paired count/cost row of their own. Everything else in\n * `nb_tokens_by_category` (cached, audio, reasoning, prediction) is a detail listed\n * after — and only when non-zero, since a zero there says nothing a missing row\n * would not.\n */\nconst PAIRED_CATEGORIES = new Set([\"input\", \"output\"]);\n\nfunction extraCategories(nbTokensByCategory: Record<string, number>): [string, number][] {\n return Object.entries(nbTokensByCategory)\n .filter(([category, nbTokens]) => !PAIRED_CATEGORIES.has(category) && nbTokens > 0)\n .sort(([a], [b]) => a.localeCompare(b));\n}\n\n/**\n * One usage scope: calls, then each token count beside the cost it produced.\n *\n * The pairing is the point — input tokens next to what the input cost, output next\n * to what the output cost, totals last. Reading down the column answers \"where did\n * the money go\" without the reader holding two separate blocks in their head.\n *\n * Token rows are gated on `hasRealTokenCounts` — every model in this scope being\n * token-billed — rather than on the node's pipe type. That is the difference between\n * a heuristic and the actual discriminator: it gets a controller's branch right too,\n * showing tokens for an all-LLM branch and hiding them the moment an extract or a\n * search joins it and turns the total into a blend of measurement and request\n * counter. The costs stay in either case: a price is a price.\n */\nfunction UsageColumn({ scoped, label }: { scoped: ScopedUsage; label: string }) {\n const showsTokens = hasRealTokenCounts(scoped);\n const isPriced = scoped.cost !== null;\n const nbTokensInput = scoped.nbTokensByCategory.input ?? 0;\n const nbTokensOutput = scoped.nbTokensByCategory.output ?? 0;\n\n return (\n <div>\n <div className=\"detail-section-label\">{label}</div>\n <KV label=\"inference calls\" value={scoped.inferenceCalls} />\n <KV label=\"priced calls\" value={scoped.ratedInferenceCalls} />\n\n {showsTokens && <KV label=\"input tokens\" value={nbTokensInput.toLocaleString()} />}\n {isPriced && scoped.costInput !== null && (\n <KV label=\"input cost\" value={formatCost(scoped.costInput)} />\n )}\n\n {showsTokens && <KV label=\"output tokens\" value={nbTokensOutput.toLocaleString()} />}\n {isPriced && scoped.costOutput !== null && (\n <KV label=\"output cost\" value={formatCost(scoped.costOutput)} />\n )}\n\n {/* total_tokens, never a sum of the categories: input_cached is a subset of\n input, so summing them double-counts. */}\n {showsTokens && <KV label=\"total tokens\" value={scoped.totalTokens.toLocaleString()} />}\n <KV label=\"total cost\" value={isPriced ? formatCost(scoped.cost ?? 0) : \"not priced\"} />\n\n {showsTokens &&\n extraCategories(scoped.nbTokensByCategory).map(([category, nbTokens]) => (\n <KV key={category} label={`tokens · ${category}`} value={nbTokens.toLocaleString()} />\n ))}\n </div>\n );\n}\n\n/** The expanded diagnostics: the node's own figures, and its branch's when they differ. */\nexport function UsageDetails({\n usage,\n isController,\n}: {\n usage: GraphSpecNodeUsage;\n isController: boolean;\n}) {\n const own = scopeUsage(usage, \"own\");\n const subtree = scopeUsage(usage, \"subtree\");\n // A leaf's branch is identical to itself; repeating it is noise.\n const showsSubtree = isController || subtree.inferenceCalls !== own.inferenceCalls;\n\n return (\n <div className=\"detail-usage-details\">\n <UsageColumn scoped={own} label={isController ? \"This pipe itself\" : \"Usage\"} />\n {showsSubtree && <UsageColumn scoped={subtree} label=\"This pipe and everything below it\" />}\n </div>\n );\n}\n","import React from \"react\";\nimport type { GraphSpecModelUsage, PipeBlueprintUnion } from \"@graph/types\";\nimport { KV, ModelRows, 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 modelsRan,\n modelHandles,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeLLM\" }>;\n executionData?: Record<string, unknown>;\n /** Models that actually ran on this node; absent for a dry or static graph. */\n modelsRan?: GraphSpecModelUsage[];\n /** execution_data, ungated: the deck-resolved model handle exists in dry specs too. */\n modelHandles?: 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 = modelHandles?.resolved_model as string | undefined;\n const resolvedModelForObject = modelHandles?.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 // The authored choices, straight from the .mthds — the head of the resolution chain.\n // NOT `resolvedModel || authored`: in a live run the handle is already concrete, and\n // preferring it would hide the alias the method actually declares.\n const authoredModel = blueprint.llm_choices?.for_text;\n const authoredModelForObject = blueprint.llm_choices?.for_object;\n // A separate object pass means a second request worth naming. When it matches the\n // text pass there is one request, and the models that ran hang under that one row.\n const hasDistinctObjectRequest = Boolean(\n authoredModelForObject && authoredModelForObject !== authoredModel,\n );\n\n return (\n <>\n {/* Model — the request, with what it resolved to underneath when they differ.\n Every model that served this node is listed there, with call counts when\n there are several. They are NOT split across the two request rows: which\n pass a given model served is not recorded, and splitting them would be a\n guess presented as a fact. */}\n <ModelRows modelsRan={modelsRan} authored={authoredModel} handle={resolvedModel} />\n {hasDistinctObjectRequest && (\n <ModelRows\n authored={authoredModelForObject}\n handle={resolvedModelForObject}\n label=\"Model (object)\"\n />\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","import React from \"react\";\nimport type { GraphSpecModelUsage, PipeBlueprintUnion } from \"@graph/types\";\nimport { KV, ModelRows, PromptToggle } from \"./shared\";\n\nexport function PipeImgGenSection({\n blueprint,\n executionData,\n modelsRan,\n modelHandles,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeImgGen\" }>;\n executionData?: Record<string, unknown>;\n /** Models that actually ran on this node; absent for a dry or static graph. */\n modelsRan?: GraphSpecModelUsage[];\n /** execution_data, ungated: the deck-resolved model handle exists in dry specs too. */\n modelHandles?: Record<string, unknown>;\n}) {\n const spec = blueprint.img_gen_prompt_blueprint;\n const resolvedModel = modelHandles?.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 <ModelRows modelsRan={modelsRan} authored={blueprint.img_gen_choice} handle={resolvedModel} />\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","import React from \"react\";\nimport type { GraphSpecModelUsage, PipeBlueprintUnion } from \"@graph/types\";\nimport { KV, ModelRows } from \"./shared\";\n\nexport function PipeExtractSection({\n blueprint,\n modelsRan,\n modelHandles,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeExtract\" }>;\n /** Models that actually ran on this node; absent for a dry or static graph. */\n modelsRan?: GraphSpecModelUsage[];\n /** execution_data, ungated: the deck-resolved model handle exists in dry specs too. */\n modelHandles?: Record<string, unknown>;\n}) {\n const resolvedModel = modelHandles?.resolved_model as string | undefined;\n\n return (\n <>\n <ModelRows modelsRan={modelsRan} authored={blueprint.extract_choice} handle={resolvedModel} />\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","import React from \"react\";\nimport type { GraphSpecModelUsage, PipeBlueprintUnion } from \"@graph/types\";\nimport { KV, ModelRows, PromptToggle } from \"./shared\";\n\nexport function PipeSearchSection({\n blueprint,\n executionData,\n modelsRan,\n modelHandles,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeSearch\" }>;\n executionData?: Record<string, unknown>;\n /** Models that actually ran on this node; absent for a dry or static graph. */\n modelsRan?: GraphSpecModelUsage[];\n /** execution_data, ungated: the deck-resolved model handle exists in dry specs too. */\n modelHandles?: Record<string, unknown>;\n}) {\n const resolvedModel = modelHandles?.resolved_model as string | undefined;\n const renderedQuery = executionData?.rendered_query as string | undefined;\n\n return (\n <>\n <ModelRows modelsRan={modelsRan} authored={blueprint.search_choice} handle={resolvedModel} />\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","/**\n * Keys, in priority order, under which an inline LLM-choice object may carry its\n * model identifier. `model` is the real field on pipelex's serialized\n * `LLMSetting`; the rest are defensive fallbacks for adjacent shapes.\n */\nconst LLM_CHOICE_LABEL_KEYS = [\"model\", \"llm_handle\", \"handle\", \"llm_name\", \"name\"] as const;\n\nfunction nonEmptyString(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\n/**\n * Derive a human-readable model label from a pipe's `llm_choice`, which may be a\n * plain string handle or an inline LLM setting object (serialized pipelex\n * `LLMSetting`, keyed by `model`). Returns `undefined` when no label can be\n * derived — null, empty, or an unrecognized object — so callers can fall back to\n * the runtime-resolved model.\n */\nexport function labelFromLlmChoice(\n choice: string | Record<string, unknown> | null | undefined,\n): string | undefined {\n if (typeof choice === \"string\") return nonEmptyString(choice);\n if (choice && typeof choice === \"object\") {\n for (const key of LLM_CHOICE_LABEL_KEYS) {\n const label = nonEmptyString(choice[key]);\n if (label) return label;\n }\n }\n return undefined;\n}\n","import React from \"react\";\nimport type { GraphSpecModelUsage, PipeBlueprintUnion } from \"@graph/types\";\nimport { KV, ModelRows, PromptToggle } from \"./shared\";\nimport { labelFromLlmChoice } from \"./llmChoice\";\n\n/**\n * Unified PipeStructure detail — merges blueprint config and runtime execution\n * data into a single view. Runtime values take precedence when available.\n * PipeStructure is an LLM-backed operator that turns a single Text input into a\n * structured concept.\n */\nexport function PipeStructureSection({\n blueprint,\n executionData,\n modelsRan,\n modelHandles,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeStructure\" }>;\n executionData?: Record<string, unknown>;\n /** Models that actually ran on this node; absent for a dry or static graph. */\n modelsRan?: GraphSpecModelUsage[];\n /** execution_data, ungated: the deck-resolved model handle exists in dry specs too. */\n modelHandles?: Record<string, unknown>;\n}) {\n // Runtime-resolved values (from execution_data).\n const resolvedModel = modelHandles?.resolved_model as string | undefined;\n const isMultipleOutput = executionData?.is_multiple_output as boolean | undefined;\n const renderedUser = executionData?.rendered_user_prompt as string | undefined;\n\n // The authored choice (a string handle or an inline LLMSetting object), shown as\n // the head of the resolution chain rather than as a fallback — see ModelRows.\n const authoredModel = labelFromLlmChoice(blueprint.llm_choice);\n\n return (\n <>\n <ModelRows modelsRan={modelsRan} authored={authoredModel} handle={resolvedModel} />\n <KV label=\"Text Variable\" value={blueprint.text_input_name} />\n <KV label=\"Multiple Output\" value={isMultipleOutput} />\n <KV label=\"Output Multiplicity\" value={blueprint.output_multiplicity} />\n\n {/* Rendered structuring prompt sent to the LLM. */}\n <PromptToggle label=\"Prompt\" templateText={undefined} renderedText={renderedUser} />\n </>\n );\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 // Loose `!= null`: a host that drops nulls delivers a template-mode blueprint with\n // no `construct_blueprint` key at all (see the registry types in types.ts).\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","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","import React from \"react\";\nimport type { PipeBlueprintUnion } from \"@graph/types\";\nimport { isBindingStepSpec } 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 {isBindingStepSpec(step) ? (\n // A binding step runs no pipe: it names the path it binds.\n <span className=\"detail-step-code\" title=\"Binding step\">\n from {step.from_path}\n </span>\n ) : (\n <span className=\"detail-step-code\">{step.pipe_code}</span>\n )}\n {step.output_name && (\n <span className=\"detail-io-concept\">-&gt; {step.output_name}</span>\n )}\n </div>\n ))}\n </div>\n </div>\n );\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\">-&gt; {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","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","import React from \"react\";\nimport type { GraphSpecNode } from \"@graph/types\";\nimport { KV } from \"./shared\";\n\n/**\n * What a binding step binds: the path it reads and the name it stores the value\n * under. Both are structural, so they show in every mode, a static graph\n * included.\n *\n * pipelex records them as the node's `execution_data` (`from`, `result`), the\n * static builder too. The node itself says as much when that record is absent:\n * its `pipe_code` is the `from` path, and its one output, when it bound a value,\n * carries the `result` name.\n */\nexport function BindingStepSection({ node }: { node: GraphSpecNode }) {\n const executionData = node.execution_data ?? {};\n const fromPath = typeof executionData.from === \"string\" ? executionData.from : node.pipe_code;\n const result =\n typeof executionData.result === \"string\" ? executionData.result : node.io.outputs[0]?.name;\n return (\n <div>\n <div className=\"detail-section-label\">Binding</div>\n <KV label=\"From\" value={fromPath} />\n <KV label=\"Result\" value={result} />\n </div>\n );\n}\n","/**\n * Pipe types whose runtime `execution_data` is merged into their blueprint\n * section (`Pipe*Section`). When the blueprint resolves, the section already\n * renders the runtime values, so the dedicated execution-data dump is\n * suppressed to avoid duplication. Every type with a `Pipe*Section` renderer is\n * listed here; `PipeFunc` (no section) and `PipeSignature` (stub) are not.\n */\nexport const MERGED_EXECUTION_DATA_TYPES = new Set<string>([\n \"PipeLLM\",\n \"PipeImgGen\",\n \"PipeExtract\",\n \"PipeSearch\",\n \"PipeStructure\",\n \"PipeCompose\",\n \"PipeSequence\",\n \"PipeParallel\",\n \"PipeCondition\",\n \"PipeBatch\",\n]);\n\n/**\n * Decide whether to render the raw execution-data dump (`GenericExecutionData`).\n *\n * For a merged type we only dump when the blueprint failed to resolve — otherwise\n * its runtime values would be silently dropped, since the per-type section never\n * mounts (it is gated on the blueprint). For any other type (`PipeFunc`,\n * `PipeSignature`, or a future/unknown type) there is no merged section, so the\n * dump is always shown.\n */\nexport function shouldDumpExecutionData(pipeType: string, hasBlueprint: boolean): boolean {\n if (MERGED_EXECUTION_DATA_TYPES.has(pipeType)) return !hasBlueprint;\n return true;\n}\n","import React from \"react\";\nimport type { ConceptInfo, GraphSpecNodeIoItem } from \"@graph/types\";\nimport { isPluralMultiplicity, multiplicitySuffix } from \"@graph/types\";\n\n// ─── Props ──────────────────────────────────────────────────────────────\n\nexport interface ConceptDetailPanelProps {\n concept: ConceptInfo;\n /** The data item for this concept instance, as the `GraphSpec` holds it. */\n ioData?: GraphSpecNodeIoItem;\n /** Whether this is a dry run (schema only, no real data). */\n isDryRun?: boolean;\n /**\n * Renders the data half. `GraphViewer` supplies it as a `StuffResultPanel`,\n * the form kernel's descriptor-driven result view, when the host's `graph`\n * carries `pipeIoContracts` and `outputForm`; see `docs/stuff-result-panel.md`.\n *\n * Without it — or when it returns nothing for this item — the panel shows the\n * structure table alone and no tabs, which is what a viewer that has not been\n * given a renderer honestly has to offer.\n */\n renderData?: () => React.ReactNode;\n /**\n * Identity of the selected node/instance (e.g. the graph node id). Drives\n * the Data/Structure tab reset: a new `instanceKey` remounts the body so\n * the Data tab is selected again. Without it, two nodes sharing the same\n * concept AND the same stuff name/digest (typical for batch branches) would\n * keep the previous node's tab selection.\n */\n instanceKey?: string;\n}\n\n// ─── Component ──────────────────────────────────────────────────────────\n\nexport function ConceptDetailPanel({\n concept,\n ioData,\n isDryRun,\n renderData,\n instanceKey,\n}: ConceptDetailPanelProps) {\n // The concept describes one item; the io item says how many a stuff holds.\n const multiplicity = ioData?.multiplicity;\n return (\n <>\n {/* Header */}\n <div className=\"detail-header\">\n <span className=\"detail-concept-code\">\n {concept.code + multiplicitySuffix(multiplicity)}\n </span>\n <span className=\"detail-concept-domain\">{concept.domain_code}</span>\n </div>\n\n {/* Plurality, stated before the description so \"A document\" reads as one item of the list */}\n {isPluralMultiplicity(multiplicity) && (\n <div className=\"detail-multiplicity\">\n {multiplicity === true\n ? `A variable-length list of ${concept.code} items`\n : `A fixed-length list of exactly ${multiplicity as number} ${concept.code} items`}\n </div>\n )}\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 <ConceptBody\n key={\n instanceKey ??\n `${concept.code}:${ioData && \"digest\" in ioData ? ioData.digest : (ioData?.name ?? \"\")}`\n }\n concept={concept}\n ioData={ioData}\n isDryRun={isDryRun}\n renderData={renderData}\n />\n </>\n );\n}\n\n/**\n * Structure + data sections. When instance data exists, the two are split\n * into \"Data\" / \"Structure\" tabs with Data shown by default — the schema\n * table is reference material, not something to scroll past on every click.\n * Without data (dry run / unexecuted), the structure renders directly.\n */\nfunction ConceptBody({ concept, ioData, isDryRun, renderData }: ConceptDetailPanelProps) {\n // The data tab exists only when something can actually fill it. Three\n // conditions, and the third is the new one: an item, a real run behind it,\n // and a renderer that produced something for it. A tab that opens onto an\n // empty pane is worse than no tab, because it reads as data that failed to\n // load rather than as a viewer that was never given a way to show it.\n const dataView = ioData && !isDryRun ? renderData?.() : undefined;\n const hasData = Boolean(dataView);\n const [activeTab, setActiveTab] = React.useState<TabId>(hasData ? \"data\" : \"structure\");\n const baseId = React.useId();\n const tabId = (tab: TabId) => `${baseId}-tab-${tab}`;\n const panelId = (tab: TabId) => `${baseId}-tabpanel-${tab}`;\n\n const structure = concept.json_schema ? (\n <div>\n <div className=\"detail-section-label\">Structure</div>\n <SchemaTable schema={concept.json_schema} />\n </div>\n ) : (\n <div className=\"detail-not-available\">Schema not available</div>\n );\n\n if (!hasData) return structure;\n\n // ARIA tabs keyboard pattern: arrows move between the two tabs (and\n // activate, per \"selection follows focus\"), Home/End jump to first/last.\n const onTabKeyDown = (event: React.KeyboardEvent) => {\n let next: TabId;\n switch (event.key) {\n case \"ArrowLeft\":\n case \"ArrowRight\":\n next = activeTab === \"data\" ? \"structure\" : \"data\";\n break;\n case \"Home\":\n next = \"data\";\n break;\n case \"End\":\n next = \"structure\";\n break;\n default:\n return;\n }\n event.preventDefault();\n setActiveTab(next);\n document.getElementById(tabId(next))?.focus();\n };\n\n const renderTab = (tab: TabId, label: string) => (\n <button\n type=\"button\"\n role=\"tab\"\n id={tabId(tab)}\n aria-selected={activeTab === tab}\n aria-controls={panelId(tab)}\n tabIndex={activeTab === tab ? 0 : -1}\n className={`detail-tab ${activeTab === tab ? \"detail-tab--active\" : \"\"}`}\n onClick={() => setActiveTab(tab)}\n onKeyDown={onTabKeyDown}\n >\n {label}\n </button>\n );\n\n return (\n <>\n <div className=\"detail-tabs\" role=\"tablist\" aria-label=\"Concept views\">\n {renderTab(\"data\", \"Data\")}\n {renderTab(\"structure\", \"Structure\")}\n </div>\n <div role=\"tabpanel\" id={panelId(activeTab)} aria-labelledby={tabId(activeTab)}>\n {activeTab === \"data\" ? dataView : structure}\n </div>\n </>\n );\n}\n\ntype TabId = \"data\" | \"structure\";\n\n// ─── Schema table renderer ──────────────────────────────────────────────\n\nfunction SchemaTable({ schema }: { schema: Record<string, unknown> }) {\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\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 {fields.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 (typeof schema.type === \"string\") return schema.type;\n if (Array.isArray(schema.type)) return schema.type.join(\" | \");\n if (schema.anyOf) return \"union\";\n if (schema.allOf) return \"all\";\n if (typeof schema.$ref === \"string\") {\n const ref = schema.$ref;\n return ref.split(\"/\").pop() ?? \"(unresolved type)\";\n }\n return \"(unresolved type)\";\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 { EdgeRoute, 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 * A route the layout computed travels in `data.route`, where the routed edge\n * component reads it (see `RoutedEdgeData`).\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 ...(e.route ? { data: { route: e.route } satisfies RoutedEdgeData } : {}),\n }));\n}\n\n/** What a routed edge carries in its ReactFlow `data`. */\nexport interface RoutedEdgeData extends Record<string, unknown> {\n route?: EdgeRoute;\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 { Panel, type PanelPosition } from \"@xyflow/react\";\nimport {\n GRAPH_DIRECTION,\n GRAPH_THEME_MODE,\n VALIDATION_STATE,\n toolbarOrientation,\n toolbarSide,\n type GraphDirection,\n type GraphStyleId,\n type GraphThemeMode,\n type ToolbarPosition,\n type ValidationIssue,\n type ValidationState,\n} from \"@graph/types\";\nimport { ValidationPanel, validationLabel, validationPanelPlacement } from \"./ValidationPanel\";\nimport { StyleMenu } from \"./StyleMenu\";\nimport { usePopoverDismiss } from \"./usePopoverDismiss\";\n\n/**\n * ReactFlow's default `<Panel>` margin (`.react-flow__panel { margin: 15px }`).\n * Its center-anchor rules hardcode a `translate(-15px)` that cancels exactly\n * this margin, so we let ReactFlow own the base margin and only *add* to it for\n * the detail-panel dodge — never override the `margin` shorthand (see below).\n */\nconst REACTFLOW_PANEL_MARGIN = 15;\n\n// Guarantees our public `ToolbarPosition` enum stays a strict subset of\n// ReactFlow's `PanelPosition`, so every value passes straight to `<Panel>`.\n// This assertion belongs in the React layer — `types.ts` stays React-free and\n// must never import `PanelPosition`.\ntype _AssertToolbarPositionIsPanelPosition = ToolbarPosition extends PanelPosition ? true : never;\nconst _toolbarPositionCompat: _AssertToolbarPositionIsPanelPosition = true;\nvoid _toolbarPositionCompat;\n\nexport interface GraphToolbarProps {\n direction: GraphDirection;\n onDirectionChange: (direction: GraphDirection) => void;\n showControllers: boolean;\n /**\n * Toggle handler for the controller frames. The toggle renders only when this\n * is set: a style that decides its own frames leaves it unset.\n */\n onShowControllersChange?: (showControllers: boolean) => void;\n /** The active graph style, shown on the style menu's button. */\n graphStyle?: GraphStyleId;\n /**\n * The styles the menu offers, in order. The menu renders when this holds at\n * least two styles and `graphStyle` and `onGraphStyleChange` are set.\n */\n styleMenuOptions?: readonly GraphStyleId[];\n /** Style change handler, called with the style chosen in the menu. */\n onGraphStyleChange?: (style: GraphStyleId) => 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 /** Current theme mode. Renders the theme toggle when both this and `onThemeModeChange` are set. */\n themeMode?: GraphThemeMode;\n /** Theme mode change handler. Renders the theme toggle when both this and `themeMode` are set. */\n onThemeModeChange?: (mode: GraphThemeMode) => void;\n /** Pixel offset from the right edge (e.g. detail panel width when open). */\n rightOffset?: number;\n /**\n * State of the validation widget. Renders the widget (as the toolbar's first\n * section) only when set — `undefined` (the default) hides it entirely.\n */\n validationState?: ValidationState;\n /** Issues listed in the validation dropdown; the badge shows their count. */\n validationIssues?: ValidationIssue[];\n /** Issue row-click handler; the host typically navigates to the issue's source. */\n onValidationIssueClick?: (index: number, issue: ValidationIssue) => void;\n /**\n * Controlled open state of the validation dropdown. GraphViewer owns it so\n * node badges can open the panel; the toolbar still handles the toggle\n * button and outside-click/Escape dismissal through `onValidationOpenChange`.\n */\n validationOpen?: boolean;\n /** Open-state change requests (toggle click, outside click, Escape). */\n onValidationOpenChange?: (open: boolean) => void;\n /**\n * Anchor for the toolbar. The value is forwarded to a ReactFlow\n * `<Panel position=…>`; orientation (row vs column) is derived from it via\n * {@link toolbarOrientation}. Required — `GraphViewer` always resolves it from\n * the prop/config/default chain (see `resolveToolbarPosition`).\n */\n position: ToolbarPosition;\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\nconst SUN_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 <circle cx=\"12\" cy=\"12\" r=\"4\" />\n <line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"4\" />\n <line x1=\"12\" y1=\"20\" x2=\"12\" y2=\"22\" />\n <line x1=\"4.93\" y1=\"4.93\" x2=\"6.34\" y2=\"6.34\" />\n <line x1=\"17.66\" y1=\"17.66\" x2=\"19.07\" y2=\"19.07\" />\n <line x1=\"2\" y1=\"12\" x2=\"4\" y2=\"12\" />\n <line x1=\"20\" y1=\"12\" x2=\"22\" y2=\"12\" />\n <line x1=\"4.93\" y1=\"19.07\" x2=\"6.34\" y2=\"17.66\" />\n <line x1=\"17.66\" y1=\"6.34\" x2=\"19.07\" y2=\"4.93\" />\n </svg>\n);\n\nconst MOON_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=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" />\n </svg>\n);\n\n/** `system` mode — a monitor glyph reading as \"follow the system\". */\nconst MONITOR_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=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\" />\n <line x1=\"8\" y1=\"21\" x2=\"16\" y2=\"21\" />\n <line x1=\"12\" y1=\"17\" x2=\"12\" y2=\"21\" />\n </svg>\n);\n\n/** `validating` — a three-quarter arc, spun by CSS. */\nconst SPINNER_ICON = (\n <svg\n className=\"graph-toolbar-validation-spin\"\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=\"M21 12a9 9 0 1 1-6.219-8.56\" />\n </svg>\n);\n\nconst CHECK_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=\"20 6 9 17 4 12\" />\n </svg>\n);\n\nconst X_CIRCLE_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 <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\" />\n <line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\" />\n </svg>\n);\n\nconst ALERT_TRIANGLE_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=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z\" />\n <line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\" />\n <line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\" />\n </svg>\n);\n\n/** `unvalidated` — an information mark: notes from reading, not a verdict. */\nconst INFO_CIRCLE_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 <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\" />\n <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\" />\n </svg>\n);\n\n/** The icon shown for a validation state. Pure, unit-testable. */\nexport function validationIcon(state: ValidationState): React.ReactElement {\n switch (state) {\n case VALIDATION_STATE.VALIDATING:\n return SPINNER_ICON;\n case VALIDATION_STATE.VALID:\n return CHECK_ICON;\n case VALIDATION_STATE.INVALID:\n return X_CIRCLE_ICON;\n case VALIDATION_STATE.ERROR:\n return ALERT_TRIANGLE_ICON;\n case VALIDATION_STATE.UNVALIDATED:\n return INFO_CIRCLE_ICON;\n default: {\n const _exhaustive: never = state;\n return _exhaustive;\n }\n }\n}\n\n// ─── Theme-mode toggle: pure cycle + presentation helpers ───────────────────\n// Exported so the cycle order and per-state labels/icons are unit-testable\n// without rendering. Order: system → light → dark → system.\n\nconst THEME_MODE_CYCLE: readonly GraphThemeMode[] = [\n GRAPH_THEME_MODE.SYSTEM,\n GRAPH_THEME_MODE.LIGHT,\n GRAPH_THEME_MODE.DARK,\n];\n\n/** Next mode in the system → light → dark → system cycle. */\nexport function nextThemeMode(current: GraphThemeMode): GraphThemeMode {\n const idx = THEME_MODE_CYCLE.indexOf(current);\n return THEME_MODE_CYCLE[(idx + 1) % THEME_MODE_CYCLE.length];\n}\n\n/** The icon shown for the current mode (represents the state, not the next action). */\nexport function themeModeIcon(mode: GraphThemeMode): React.ReactElement {\n if (mode === GRAPH_THEME_MODE.LIGHT) return SUN_ICON;\n if (mode === GRAPH_THEME_MODE.DARK) return MOON_ICON;\n return MONITOR_ICON;\n}\n\n/** Accessible label naming the current mode and the one a click switches to. */\nexport function themeModeLabel(mode: GraphThemeMode): string {\n const names: Record<GraphThemeMode, string> = {\n [GRAPH_THEME_MODE.SYSTEM]: \"system\",\n [GRAPH_THEME_MODE.LIGHT]: \"light\",\n [GRAPH_THEME_MODE.DARK]: \"dark\",\n };\n const next = nextThemeMode(mode);\n return `Theme: ${names[mode]} — switch to ${names[next]}`;\n}\n\nexport function GraphToolbar({\n direction,\n onDirectionChange,\n showControllers,\n onShowControllersChange,\n graphStyle,\n styleMenuOptions = [],\n onGraphStyleChange,\n onZoomIn,\n onZoomOut,\n onFitView,\n onFoldAll,\n onExpandAll,\n foldAllDisabled = false,\n expandAllDisabled = false,\n themeMode,\n onThemeModeChange,\n rightOffset = 0,\n position,\n validationState,\n validationIssues = [],\n onValidationIssueClick,\n validationOpen = false,\n onValidationOpenChange,\n}: GraphToolbarProps) {\n const themeToggleEnabled = themeMode !== undefined && onThemeModeChange !== undefined;\n const orientation = toolbarOrientation(position);\n\n // The dropdown's open state is controlled by GraphViewer (so node badges can\n // open the panel too); the toolbar owns the toggle button and the\n // outside-click/Escape dismissal, reported through onValidationOpenChange.\n const setValidationOpen = onValidationOpenChange ?? (() => {});\n const setValidationOpenRef = React.useRef(setValidationOpen);\n setValidationOpenRef.current = setValidationOpen;\n const validationRef = React.useRef<HTMLDivElement | null>(null);\n // useId, not a constant: several viewers can coexist on one page (Storybook grids).\n const validationPanelId = React.useId();\n // The widget can be hidden (validationState undefined) while GraphToolbar stays\n // mounted; drop the open state so re-enabling doesn't resurrect the dropdown.\n React.useEffect(() => {\n if (validationState === undefined) setValidationOpenRef.current(false);\n }, [validationState]);\n usePopoverDismiss(validationOpen, validationRef, () => setValidationOpenRef.current(false));\n const styleMenuEnabled =\n graphStyle !== undefined && onGraphStyleChange !== undefined && styleMenuOptions.length >= 2;\n // ReactFlow's <Panel> owns all base positioning: the anchor, its default 15px\n // margin, and the center-anchor transforms calibrated to cancel exactly that\n // margin. We deliberately do NOT set the `margin` shorthand here —\n // - overriding it (e.g. to 8px) leaves ReactFlow's hardcoded -15px center\n // compensation in place, mis-centering every center anchor; and\n // - mixing an inline `margin` shorthand with a conditional `marginRight`\n // longhand defeats React's style reconciliation — clearing the longhand\n // can't restore the shorthand, so the bar stays stuck at the wrong offset\n // once the panel closes.\n // The only override is the detail-panel dodge: the panel overlays the right\n // edge, so right-anchored bars shift left by its width. Expressed as\n // `marginRight` alone (base margin + width); when the panel closes the inline\n // value is dropped and the gap falls cleanly back to the stylesheet's margin.\n const dodgesDetailPanel = toolbarSide(position) === \"right\" && rightOffset > 0;\n const panelStyle: React.CSSProperties | undefined = dodgesDetailPanel\n ? { marginRight: REACTFLOW_PANEL_MARGIN + rightOffset }\n : undefined;\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 <Panel position={position} className=\"graph-toolbar-panel\" style={panelStyle}>\n <div className={`graph-toolbar graph-toolbar--${orientation}`}>\n {validationState !== undefined && (\n <>\n <div className=\"graph-toolbar-validation\" ref={validationRef}>\n <button\n type=\"button\"\n className={`graph-toolbar-btn graph-toolbar-validation-btn graph-toolbar-validation-btn--${validationState}`}\n onClick={() => setValidationOpen(!validationOpen)}\n title={validationLabel(validationState, validationIssues.length)}\n aria-label={validationLabel(validationState, validationIssues.length)}\n aria-expanded={validationOpen}\n aria-haspopup=\"true\"\n aria-controls={validationPanelId}\n >\n {validationIcon(validationState)}\n {validationIssues.length > 0 && (\n <span className=\"graph-toolbar-validation-badge\">\n {validationIssues.length > 99 ? \"99+\" : validationIssues.length}\n </span>\n )}\n </button>\n {validationOpen && (\n <ValidationPanel\n id={validationPanelId}\n state={validationState}\n issues={validationIssues}\n onIssueClick={onValidationIssueClick}\n placement={validationPanelPlacement(position)}\n />\n )}\n </div>\n <div className=\"graph-toolbar-separator\" />\n </>\n )}\n\n {styleMenuEnabled && (\n <>\n <StyleMenu\n value={graphStyle}\n options={styleMenuOptions}\n onChange={onGraphStyleChange}\n placement={validationPanelPlacement(position)}\n />\n <div className=\"graph-toolbar-separator\" />\n </>\n )}\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 {foldAllSection && <div className=\"graph-toolbar-separator\" />}\n\n {onShowControllersChange && (\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\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 {(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\n {themeToggleEnabled && (\n <>\n <div className=\"graph-toolbar-separator\" />\n <button\n type=\"button\"\n className=\"graph-toolbar-btn\"\n onClick={() => onThemeModeChange(nextThemeMode(themeMode))}\n title={themeModeLabel(themeMode)}\n aria-label={themeModeLabel(themeMode)}\n >\n {themeModeIcon(themeMode)}\n </button>\n </>\n )}\n </div>\n </Panel>\n );\n}\n","import React from \"react\";\nimport {\n TOOLBAR_POSITION,\n VALIDATION_STATE,\n type ToolbarPosition,\n type ValidationIssue,\n type ValidationState,\n} from \"@graph/types\";\n\n/**\n * Human label for a validation state + issue count. Used as the widget button's\n * title/aria-label and as the panel header. Pure, unit-testable.\n */\nexport function validationLabel(state: ValidationState, issueCount: number): string {\n const issues = issueCount === 1 ? \"1 issue\" : `${issueCount} issues`;\n switch (state) {\n case VALIDATION_STATE.VALIDATING:\n return issueCount > 0 ? `Validating method… — ${issues}` : \"Validating method…\";\n case VALIDATION_STATE.VALID:\n return issueCount > 0 ? `Method is valid — ${issues}` : \"Method is valid\";\n case VALIDATION_STATE.INVALID:\n return `Method is invalid — ${issues}`;\n case VALIDATION_STATE.ERROR:\n return \"Validation could not run\";\n case VALIDATION_STATE.UNVALIDATED:\n return issueCount > 0\n ? `Not validated — ${issues} found reading the source`\n : \"Not validated\";\n default: {\n const _exhaustive: never = state;\n return _exhaustive;\n }\n }\n}\n\n/**\n * How the dropdown opens relative to the validation button, derived from the\n * toolbar anchor so the panel always unfolds toward the graph, never off-screen:\n * `down-*`/`up-*` for horizontal bars (top vs bottom anchors), aligned to the\n * button's `start` (left) or `end` (right) edge; `side-end`/`side-start` for the\n * vertical bars, opening away from the hugged edge.\n */\nexport type ValidationPanelPlacement =\n | \"down-start\"\n | \"down-end\"\n | \"up-start\"\n | \"up-end\"\n | \"side-start\"\n | \"side-end\";\n\n/** Derive the dropdown placement from the toolbar anchor. Pure, unit-testable. */\nexport function validationPanelPlacement(position: ToolbarPosition): ValidationPanelPlacement {\n switch (position) {\n case TOOLBAR_POSITION.TOP_LEFT:\n case TOOLBAR_POSITION.TOP_CENTER:\n return \"down-start\";\n case TOOLBAR_POSITION.TOP_RIGHT:\n return \"down-end\";\n case TOOLBAR_POSITION.BOTTOM_LEFT:\n case TOOLBAR_POSITION.BOTTOM_CENTER:\n return \"up-start\";\n case TOOLBAR_POSITION.BOTTOM_RIGHT:\n return \"up-end\";\n case TOOLBAR_POSITION.CENTER_LEFT:\n return \"side-end\";\n case TOOLBAR_POSITION.CENTER_RIGHT:\n return \"side-start\";\n default: {\n const _exhaustive: never = position;\n return _exhaustive;\n }\n }\n}\n\n/** Fallback body text when the host supplied no issues for the current state. */\nexport function validationEmptyText(state: ValidationState): string {\n switch (state) {\n case VALIDATION_STATE.VALIDATING:\n return \"Validating…\";\n case VALIDATION_STATE.VALID:\n return \"No issues found.\";\n case VALIDATION_STATE.INVALID:\n return \"No details available.\";\n case VALIDATION_STATE.ERROR:\n return \"Validation could not run.\";\n case VALIDATION_STATE.UNVALIDATED:\n return \"Nothing found reading the source. The method has not been validated.\";\n default: {\n const _exhaustive: never = state;\n return _exhaustive;\n }\n }\n}\n\nexport interface ValidationPanelProps {\n state: ValidationState;\n issues: ValidationIssue[];\n /** Row-click handler; rows render as buttons only when this is set. */\n onIssueClick?: (index: number, issue: ValidationIssue) => void;\n placement: ValidationPanelPlacement;\n /** Id of the panel root, referenced by the toolbar button's aria-controls. */\n id?: string;\n}\n\n/**\n * The dropdown listing validation issues, opened from the toolbar's validation\n * widget. Purely presentational: the host owns the issue list and what a row\n * click does (typically: navigate to the issue's source location).\n */\nexport function ValidationPanel({\n state,\n issues,\n onIssueClick,\n placement,\n id,\n}: ValidationPanelProps) {\n return (\n <div\n id={id}\n className={`graph-validation-panel graph-validation-panel--${placement}`}\n role=\"region\"\n aria-label=\"Validation issues\"\n >\n <div className=\"graph-validation-panel-header\">{validationLabel(state, issues.length)}</div>\n {/* Explicit role=\"list\": list-style:none strips implicit list semantics in Safari. */}\n {issues.length === 0 ? (\n <div className=\"graph-validation-empty\">{validationEmptyText(state)}</div>\n ) : (\n <ul className=\"graph-validation-issues\" role=\"list\">\n {issues.map((issue, index) => {\n const clickable = onIssueClick !== undefined;\n const meta = (issue.context || issue.file) && (\n <div className=\"graph-validation-issue-meta\">\n {issue.context && (\n <span className=\"graph-validation-issue-context\">{issue.context}</span>\n )}\n {issue.file && <span className=\"graph-validation-issue-file\">{issue.file}</span>}\n </div>\n );\n // Button semantics go on an inner body element, not the <li> itself,\n // so each row keeps its listitem role for assistive tech.\n return (\n <li\n key={index}\n className={\n `graph-validation-issue graph-validation-issue--${issue.severity}` +\n (clickable ? \" graph-validation-issue--clickable\" : \"\")\n }\n >\n <div\n className=\"graph-validation-issue-body\"\n role={clickable ? \"button\" : undefined}\n tabIndex={clickable ? 0 : undefined}\n onClick={clickable ? () => onIssueClick(index, issue) : undefined}\n onKeyDown={\n clickable\n ? (event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onIssueClick(index, issue);\n }\n }\n : undefined\n }\n >\n {meta}\n <div className=\"graph-validation-issue-message\">{issue.message}</div>\n {issue.suggestedFix && (\n <div className=\"graph-validation-issue-fix\">{issue.suggestedFix}</div>\n )}\n </div>\n </li>\n );\n })}\n </ul>\n )}\n </div>\n );\n}\n","import React from \"react\";\nimport { GRAPH_STYLE, type GraphStyleId } from \"@graph/types\";\nimport { GRAPH_STYLES } from \"@graph/styles/graphStyles\";\nimport type { ValidationPanelPlacement } from \"./ValidationPanel\";\nimport { usePopoverDismiss } from \"./usePopoverDismiss\";\n\nconst ICON_PROPS = {\n viewBox: \"0 0 24 24\",\n width: 14,\n height: 14,\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\" as const,\n strokeLinejoin: \"round\" as const,\n};\n\n/**\n * Each style's icon, on the toolbar button (the current style) and in its menu\n * row. Keyed by `GraphStyleId`, so a new style does not compile without one.\n */\nconst STYLE_ICONS: Record<GraphStyleId, React.ReactElement> = {\n // Cards with their rows: every pipe with its slots.\n [GRAPH_STYLE.DETAILED]: (\n <svg {...ICON_PROPS}>\n <rect x=\"3\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\" />\n <rect x=\"3\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\" />\n <line x1=\"14\" y1=\"4\" x2=\"21\" y2=\"4\" />\n <line x1=\"14\" y1=\"9\" x2=\"21\" y2=\"9\" />\n <line x1=\"14\" y1=\"15\" x2=\"21\" y2=\"15\" />\n <line x1=\"14\" y1=\"20\" x2=\"21\" y2=\"20\" />\n </svg>\n ),\n // Two steps and the arrow between them: a flowchart.\n [GRAPH_STYLE.SIMPLE]: (\n <svg {...ICON_PROPS}>\n <rect x=\"3\" y=\"3\" width=\"8\" height=\"8\" rx=\"2\" />\n <path d=\"M7 11v4a2 2 0 0 0 2 2h4\" />\n <rect x=\"13\" y=\"13\" width=\"8\" height=\"8\" rx=\"2\" />\n </svg>\n ),\n};\n\nconst CHECK_ICON = (\n <svg {...ICON_PROPS}>\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n);\n\n/** The icon of a style. Pure, unit-testable. */\nexport function graphStyleIcon(style: GraphStyleId): React.ReactElement {\n return STYLE_ICONS[style];\n}\n\n/** Accessible label of the menu button: the current style, and what the button does. */\nexport function styleMenuLabel(style: GraphStyleId): string {\n return `Graph style: ${GRAPH_STYLES[style].name} — choose how the graph is drawn`;\n}\n\nexport interface StyleMenuProps {\n /** The active style, shown on the button and checked in the list. */\n value: GraphStyleId;\n /** The styles offered, in order. */\n options: readonly GraphStyleId[];\n onChange: (style: GraphStyleId) => void;\n /** Where the list opens, from the toolbar's anchor — the validation dropdown's vocabulary. */\n placement: ValidationPanelPlacement;\n}\n\n/**\n * The toolbar's style menu: a button showing the current style's icon, opening\n * a list of radio items, each with its icon, name and one-line description, and\n * a check on the current one. A list rather than a two-state toggle, because\n * the registry is built for more than two styles. Keyboard: arrows, Home and\n * End move, Enter or Space choose, Escape closes and returns to the button.\n */\nexport function StyleMenu({ value, options, onChange, placement }: StyleMenuProps) {\n const [open, setOpen] = React.useState(false);\n const [activeIndex, setActiveIndex] = React.useState(0);\n const wrapperRef = React.useRef<HTMLDivElement | null>(null);\n const buttonRef = React.useRef<HTMLButtonElement | null>(null);\n const itemRefs = React.useRef<(HTMLButtonElement | null)[]>([]);\n // useId, not a constant: several viewers can coexist on one page.\n const menuId = React.useId();\n\n usePopoverDismiss(open, wrapperRef, (reason) => {\n setOpen(false);\n if (reason === \"escape\") buttonRef.current?.focus();\n });\n\n // Opening moves focus to the checked item, as a radio menu does.\n React.useEffect(() => {\n if (!open) return;\n const index = Math.max(0, options.indexOf(value));\n setActiveIndex(index);\n itemRefs.current[index]?.focus();\n // Only on opening: choosing a style closes the menu anyway.\n }, [open]);\n\n const focusItem = (index: number) => {\n const count = options.length;\n const next = ((index % count) + count) % count;\n setActiveIndex(next);\n itemRefs.current[next]?.focus();\n };\n\n const onMenuKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n switch (event.key) {\n case \"ArrowDown\":\n event.preventDefault();\n focusItem(activeIndex + 1);\n break;\n case \"ArrowUp\":\n event.preventDefault();\n focusItem(activeIndex - 1);\n break;\n case \"Home\":\n event.preventDefault();\n focusItem(0);\n break;\n case \"End\":\n event.preventDefault();\n focusItem(options.length - 1);\n break;\n case \"Tab\":\n setOpen(false);\n break;\n default:\n break;\n }\n };\n\n const choose = (style: GraphStyleId) => {\n setOpen(false);\n buttonRef.current?.focus();\n if (style !== value) onChange(style);\n };\n\n const label = styleMenuLabel(value);\n return (\n <div className=\"graph-toolbar-style\" ref={wrapperRef}>\n <button\n ref={buttonRef}\n type=\"button\"\n className={`graph-toolbar-btn${open ? \" graph-toolbar-btn--open\" : \"\"}`}\n onClick={() => setOpen(!open)}\n onKeyDown={(event) => {\n if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n setOpen(true);\n }\n }}\n title={label}\n aria-label={label}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-controls={open ? menuId : undefined}\n >\n {graphStyleIcon(value)}\n </button>\n {open && (\n <div\n id={menuId}\n role=\"menu\"\n aria-label=\"Graph style\"\n className={`graph-style-menu graph-style-menu--${placement}`}\n onKeyDown={onMenuKeyDown}\n >\n {options.map((style, index) => {\n const descriptor = GRAPH_STYLES[style];\n const checked = style === value;\n return (\n <button\n key={style}\n ref={(el) => {\n itemRefs.current[index] = el;\n }}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={checked}\n tabIndex={index === activeIndex ? 0 : -1}\n className={`graph-style-menu-item${checked ? \" graph-style-menu-item--checked\" : \"\"}`}\n onClick={() => choose(style)}\n >\n <span className=\"graph-style-menu-icon\" aria-hidden=\"true\">\n {graphStyleIcon(style)}\n </span>\n <span className=\"graph-style-menu-text\">\n <span className=\"graph-style-menu-name\">{descriptor.name}</span>\n <span className=\"graph-style-menu-description\">{descriptor.description}</span>\n </span>\n <span className=\"graph-style-menu-check\" aria-hidden=\"true\">\n {checked ? CHECK_ICON : null}\n </span>\n </button>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n","import React from \"react\";\n\n/** Why an open popover asked to close: a press outside it, or the Escape key. */\nexport type PopoverDismissReason = \"outside\" | \"escape\";\n\n/**\n * Close a toolbar popover (the validation dropdown, the style menu) on a press\n * outside its wrapper or on Escape, while it is open. The listeners live on the\n * document only while `open` is true. `onDismiss` may change between renders\n * without re-registering them.\n *\n * The press is heard in the capture phase: the graph's pane handles its own\n * presses for panning and stops them there, so a listener waiting for them to\n * bubble to the document never hears a press on the canvas, the most common\n * place to click away from a popover.\n */\nexport function usePopoverDismiss(\n open: boolean,\n wrapperRef: React.RefObject<HTMLElement | null>,\n onDismiss: (reason: PopoverDismissReason) => void,\n): void {\n const onDismissRef = React.useRef(onDismiss);\n onDismissRef.current = onDismiss;\n React.useEffect(() => {\n if (!open) return;\n const onPointerDown = (event: PointerEvent) => {\n const wrapper = wrapperRef.current;\n if (wrapper && event.target instanceof Node && !wrapper.contains(event.target)) {\n onDismissRef.current(\"outside\");\n }\n };\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") onDismissRef.current(\"escape\");\n };\n document.addEventListener(\"pointerdown\", onPointerDown, true);\n document.addEventListener(\"keydown\", onKeyDown);\n return () => {\n document.removeEventListener(\"pointerdown\", onPointerDown, true);\n document.removeEventListener(\"keydown\", onKeyDown);\n };\n }, [open, wrapperRef]);\n}\n","import React from \"react\";\nimport type { NodeValidationSummary } from \"@graph/types\";\n\n/**\n * Corner count badge for a node's validation decoration, shared by pipe cards\n * and controller groups. The tooltip lists every issue's message (and `Fix: …`\n * line). Renders a button when `onClick` is set (opens the validation panel),\n * a plain span otherwise.\n */\nexport function NodeValidationBadge({\n validation,\n onClick,\n}: {\n validation: NodeValidationSummary;\n onClick?: () => void;\n}) {\n const label = `${validation.count} validation ${validation.count === 1 ? \"issue\" : \"issues\"}`;\n const tooltip = validation.lines.join(\"\\n\");\n const className = `node-validation-badge node-validation-badge--${validation.severity}`;\n const text = validation.count > 99 ? \"99+\" : String(validation.count);\n if (!onClick) {\n return (\n <span className={className} title={tooltip} aria-label={label}>\n {text}\n </span>\n );\n }\n return (\n <button\n type=\"button\"\n className={className}\n title={tooltip}\n aria-label={`${label} — open validation panel`}\n onClick={(e) => {\n e.stopPropagation();\n onClick();\n }}\n >\n {text}\n </button>\n );\n}\n\n/** Ring modifier class for a decorated node root (empty string when undecorated). */\nexport function validationRingClass(validation: NodeValidationSummary | undefined): string {\n return validation ? ` node-validation-ring--${validation.severity}` : \"\";\n}\n","import React from \"react\";\nimport type { FoldToggleOptions, NodeValidationSummary, PipeControllerType } from \"@graph/types\";\nimport { MAX_VISIBLE_CONTROLLER_CHILDREN } from \"@graph/graphControllers\";\nimport { NodeValidationBadge, validationRingClass } from \"../NodeValidationBadge\";\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 validation?: NodeValidationSummary;\n onValidationBadgeClick?: () => 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}${validationRingClass(data.validation)}`}>\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 {data.validation && (\n <NodeValidationBadge validation={data.validation} onClick={data.onValidationBadgeClick} />\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 { NodePipeType, PipeCardData, PipeControllerType, PipeStatus } from \"./pipeCardTypes\";\nimport { BINDING_STEP_TYPE } from \"@graph/types\";\nimport { NodeValidationBadge, validationRingClass } from \"../NodeValidationBadge\";\n\n// ─── Pipe type badge labels ──────────────────────────────────────────────\n\nconst PIPE_TYPE_BADGES: Record<NodePipeType, string> = {\n PipeLLM: \"LLM\",\n PipeExtract: \"Extract\",\n PipeCompose: \"Compose\",\n PipeImgGen: \"ImgGen\",\n PipeSearch: \"Search\",\n PipeFunc: \"Func\",\n PipeStructure: \"Structure\",\n PipeJudge: \"Judge\",\n PipeDocGen: \"DocGen\",\n PipeSignature: \"Signature\",\n PipeSequence: \"Sequence\",\n PipeParallel: \"Parallel\",\n PipeCondition: \"Condition\",\n PipeBatch: \"Batch\",\n BindingStep: \"Binding\",\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: NodePipeType): 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 canceled: { color: \"#6272a4\", label: \"Canceled\" },\n};\n\nconst MAX_VISIBLE_INPUTS = 4;\n\nfunction getBadge(pipeType: NodePipeType): 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];\n const isRunning = data.status === \"running\";\n const isController = isControllerType(data.pipeType);\n const isSignature = data.pipeType === \"PipeSignature\";\n // A binding step runs no pipe: its card names the path it binds, and reads as data plumbing.\n const isBinding = data.pipeType === BINDING_STEP_TYPE;\n const isStatic = data.graphMode === \"static\";\n const outcome = isStatic ? data.tags?.outcome : undefined;\n const batchMultiplicity = isStatic ? data.tags?.batch_multiplicity : undefined;\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 signatureClass = isSignature ? \" pipe-card--signature\" : \"\";\n const bindingClass = isBinding ? \" pipe-card--binding\" : \"\";\n const staticClass = isStatic ? \" pipe-card--static\" : \"\";\n const badgeClass = isController\n ? \"pipe-card-badge pipe-card-badge--controller\"\n : isSignature\n ? \"pipe-card-badge pipe-card-badge--signature\"\n : isBinding\n ? \"pipe-card-badge pipe-card-badge--binding\"\n : \"pipe-card-badge\";\n\n const ringClass = validationRingClass(data.validation);\n\n return (\n <div\n className={`pipe-card ${dirClass}${controllerClass}${signatureClass}${bindingClass}${staticClass}${ringClass}`}\n >\n {/* Header: badge + pipe code + status + (optional) expand + validation */}\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 {!isStatic && (\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 )}\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 {data.validation && (\n <NodeValidationBadge validation={data.validation} onClick={data.onValidationBadgeClick} />\n )}\n </div>\n\n {(outcome || batchMultiplicity) && (\n <div className=\"pipe-card-annotations\">\n {outcome && (\n <span className=\"pipe-card-annotation pipe-card-annotation--outcome\">\n outcome: {outcome}\n </span>\n )}\n {batchMultiplicity && (\n <span className=\"pipe-card-annotation pipe-card-annotation--batch\">\n {batchMultiplicity}\n </span>\n )}\n </div>\n )}\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 { NodePipeType } from \"./pipeCardTypes\";\nimport type { PipeCardBaseProps } from \"./PipeCardBase\";\nimport { PipeCardBase } from \"./PipeCardBase\";\n\n/**\n * Registry mapping pipe type → card component, the binding step included.\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<NodePipeType, ComponentType<PipeCardBaseProps>> = {\n PipeLLM: PipeCardBase,\n PipeExtract: PipeCardBase,\n PipeCompose: PipeCardBase,\n PipeImgGen: PipeCardBase,\n PipeSearch: PipeCardBase,\n PipeFunc: PipeCardBase,\n PipeStructure: PipeCardBase,\n PipeJudge: PipeCardBase,\n PipeDocGen: PipeCardBase,\n PipeSignature: PipeCardBase,\n PipeSequence: PipeCardBase,\n PipeParallel: PipeCardBase,\n PipeCondition: PipeCardBase,\n PipeBatch: PipeCardBase,\n BindingStep: PipeCardBase,\n};\n\nexport function getPipeCardComponent(pipeType: NodePipeType): ComponentType<PipeCardBaseProps> {\n return PIPE_CARD_REGISTRY[pipeType];\n}\n","import React from \"react\";\nimport { Handle, Position } from \"@xyflow/react\";\nimport type {\n GraphNodeData,\n NodeValidationSummary,\n PipeStatus,\n SimpleNodePayload,\n StepCategory,\n} from \"@graph/types\";\nimport {\n NODE_TYPE_SIMPLE_DECISION,\n NODE_TYPE_SIMPLE_FRAME,\n NODE_TYPE_SIMPLE_STEP,\n NODE_TYPE_SIMPLE_TERMINAL,\n} from \"@graph/types\";\nimport { STEP_CATEGORY_WORDS } from \"@graph/styles/simpleStyle\";\nimport { NodeValidationBadge, validationRingClass } from \"../../nodes/NodeValidationBadge\";\n\n// ─── Icons ──────────────────────────────────────────────────────────────────\n\nconst ICON_PROPS = {\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\" as const,\n strokeLinejoin: \"round\" as const,\n \"aria-hidden\": true,\n};\n\nfunction Icon({ size = 13, children }: { size?: number; children: React.ReactNode }) {\n return (\n <svg {...ICON_PROPS} width={size} height={size}>\n {children}\n </svg>\n );\n}\n\n/** Each category's icon. Keyed by `StepCategory`, so a new category does not compile without one. */\nconst CATEGORY_ICONS: Record<StepCategory, React.ReactNode> = {\n ai: (\n <>\n <path d=\"M9.94 15.5a2 2 0 0 0-1.44-1.44l-6.13-1.58a.5.5 0 0 1 0-.96L8.5 9.94A2 2 0 0 0 9.94 8.5l1.58-6.14a.5.5 0 0 1 .96 0l1.58 6.14a2 2 0 0 0 1.44 1.44l6.14 1.58a.5.5 0 0 1 0 .96l-6.14 1.58a2 2 0 0 0-1.44 1.44l-1.58 6.13a.5.5 0 0 1-.96 0z\" />\n <path d=\"M20 3v4\" />\n <path d=\"M22 5h-4\" />\n </>\n ),\n extract: (\n <>\n <path d=\"M3 7V5a2 2 0 0 1 2-2h2\" />\n <path d=\"M17 3h2a2 2 0 0 1 2 2v2\" />\n <path d=\"M21 17v2a2 2 0 0 1-2 2h-2\" />\n <path d=\"M7 21H5a2 2 0 0 1-2-2v-2\" />\n <path d=\"M7 8h8\" />\n <path d=\"M7 12h10\" />\n <path d=\"M7 16h6\" />\n </>\n ),\n image: (\n <>\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" />\n <circle cx=\"9\" cy=\"9\" r=\"2\" />\n <path d=\"m21 15-3.09-3.09a2 2 0 0 0-2.82 0L6 21\" />\n </>\n ),\n search: (\n <>\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <path d=\"m21 21-4.3-4.3\" />\n </>\n ),\n code: (\n <>\n <polyline points=\"16 18 22 12 16 6\" />\n <polyline points=\"8 6 2 12 8 18\" />\n </>\n ),\n template: (\n <>\n <path d=\"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\" />\n <path d=\"M14 2v4a2 2 0 0 0 2 2h4\" />\n <path d=\"M16 13H8\" />\n <path d=\"M16 17H8\" />\n </>\n ),\n document: (\n <>\n <path d=\"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\" />\n <path d=\"M14 2v4a2 2 0 0 0 2 2h4\" />\n <path d=\"M12 18v-6\" />\n <path d=\"m9 15 3 3 3-3\" />\n </>\n ),\n judge: (\n <>\n <path d=\"m16 16 3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1Z\" />\n <path d=\"m2 16 3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1Z\" />\n <path d=\"M7 21h10\" />\n <path d=\"M12 3v18\" />\n <path d=\"M3 7h2c2 0 5-1 7-2 2 1 5 2 7 2h2\" />\n </>\n ),\n planned: <circle cx=\"12\" cy=\"12\" r=\"9\" strokeDasharray=\"3 3\" />,\n steps: (\n <>\n <path d=\"m12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83Z\" />\n <path d=\"m22 17.65-9.17 4.16a2 2 0 0 1-1.66 0L2 17.65\" />\n <path d=\"m22 12.65-9.17 4.16a2 2 0 0 1-1.66 0L2 12.65\" />\n </>\n ),\n parallel: (\n <>\n <path d=\"M16 3h5v5\" />\n <path d=\"M8 3H3v5\" />\n <path d=\"M12 22v-8.3a4 4 0 0 0-1.17-2.87L3 3\" />\n <path d=\"m15 9 6-6\" />\n </>\n ),\n decision: <path d=\"M12 2 22 12 12 22 2 12Z\" />,\n repeat: (\n <>\n <path d=\"m17 2 4 4-4 4\" />\n <path d=\"M3 11v-1a4 4 0 0 1 4-4h14\" />\n <path d=\"m7 22-4-4 4-4\" />\n <path d=\"M21 13v1a4 4 0 0 1-4 4H3\" />\n </>\n ),\n pick: (\n <>\n <polyline points=\"15 10 20 15 15 20\" />\n <path d=\"M4 4v7a4 4 0 0 0 4 4h12\" />\n </>\n ),\n};\n\nconst EXPAND_ICON = (\n <Icon size={12}>\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 </Icon>\n);\n\nconst COLLAPSE_ICON = (\n <Icon size={12}>\n <polyline points=\"4 14 10 14 10 20\" />\n <polyline points=\"20 10 14 10 14 4\" />\n <line x1=\"14\" y1=\"10\" x2=\"21\" y2=\"3\" />\n <line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\" />\n </Icon>\n);\n\n// ─── Run status ─────────────────────────────────────────────────────────────\n\nconst STATUS_LABELS: Record<PipeStatus, string> = {\n succeeded: \"Done\",\n failed: \"Failed\",\n running: \"Running\",\n scheduled: \"Waiting\",\n skipped: \"Skipped\",\n canceled: \"Canceled\",\n};\n\nconst STATUS_ICONS: Record<PipeStatus, React.ReactNode> = {\n succeeded: <polyline points=\"20 6 9 17 4 12\" />,\n failed: (\n <>\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </>\n ),\n running: <path d=\"M21 12a9 9 0 1 1-6.22-8.56\" />,\n scheduled: <circle cx=\"12\" cy=\"12\" r=\"8\" />,\n skipped: <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />,\n canceled: <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />,\n};\n\n/** The run status mark a step shows once the method has run; nothing in a static graph. */\nfunction StatusMark({ status, graphMode }: { status: PipeStatus; graphMode?: string }) {\n if (graphMode === \"static\") return null;\n return (\n <span\n className={`simple-status simple-status--${status}`}\n title={STATUS_LABELS[status]}\n aria-label={STATUS_LABELS[status]}\n >\n <Icon size={11}>{STATUS_ICONS[status]}</Icon>\n </span>\n );\n}\n\n// ─── Shared wrapper pieces ──────────────────────────────────────────────────\n\ninterface SimpleRFNodeProps {\n data: GraphNodeData;\n sourcePosition?: Position;\n targetPosition?: Position;\n}\n\nfunction Handles({\n sourcePosition = Position.Right,\n targetPosition = Position.Left,\n children,\n}: {\n sourcePosition?: Position;\n targetPosition?: Position;\n children: React.ReactNode;\n}) {\n return (\n <>\n <Handle type=\"target\" position={targetPosition} className=\"simple-handle\" />\n {children}\n <Handle type=\"source\" position={sourcePosition} className=\"simple-handle\" />\n </>\n );\n}\n\nfunction ValidationMark({\n validation,\n onClick,\n}: {\n validation?: NodeValidationSummary;\n onClick?: () => void;\n}) {\n return validation ? <NodeValidationBadge validation={validation} onClick={onClick} /> : null;\n}\n\nfunction payloadOf<K extends SimpleNodePayload[\"kind\"]>(\n data: GraphNodeData,\n kinds: readonly K[],\n): Extract<SimpleNodePayload, { kind: K }> | null {\n const simple = data.simple;\n if (!simple || !(kinds as readonly string[]).includes(simple.kind)) return null;\n return simple as Extract<SimpleNodePayload, { kind: K }>;\n}\n\n// ─── Step ───────────────────────────────────────────────────────────────────\n\n/** A step: what the pipe does, in its author's words, with a plain category word. */\nexport function SimpleStepNode({ data, sourcePosition, targetPosition }: SimpleRFNodeProps) {\n const step = payloadOf(data, [\"step\"] as const);\n if (!step) return null;\n const statusClass = step.graphMode !== \"static\" ? ` simple-step--${step.status}` : \"\";\n return (\n <Handles sourcePosition={sourcePosition} targetPosition={targetPosition}>\n <div\n className={`simple-step simple-step--${step.category}${statusClass}${validationRingClass(data.validation)}`}\n >\n <div className=\"simple-step-header\">\n <span className=\"simple-step-category\">\n <Icon>{CATEGORY_ICONS[step.category]}</Icon>\n {STEP_CATEGORY_WORDS[step.category]}\n </span>\n <StatusMark status={step.status} graphMode={step.graphMode} />\n <ValidationMark validation={data.validation} onClick={data.onValidationBadgeClick} />\n </div>\n <div className=\"simple-step-title\" title={step.title}>\n {step.title}\n </div>\n {step.forEach && (\n <span className=\"simple-step-foreach\">\n <Icon size={11}>{CATEGORY_ICONS.repeat}</Icon>\n {step.forEach}\n </span>\n )}\n {step.innerStepCount !== undefined && (\n <button\n type=\"button\"\n className=\"simple-step-open\"\n title=\"Show the steps inside (alt/option: only this one)\"\n onClick={(event) => {\n event.stopPropagation();\n step.onExpand?.({ soloMode: event.altKey });\n }}\n disabled={!step.onExpand}\n >\n {EXPAND_ICON}\n {step.innerStepCount === 1 ? \"1 step inside\" : `${step.innerStepCount} steps inside`}\n </button>\n )}\n </div>\n </Handles>\n );\n}\n\n// ─── Input and output ───────────────────────────────────────────────────────\n\n/** The document shape's outline: a page whose foot is a wave. Stretched to the node. */\nconst DOCUMENT_PATH = \"M1 1 H99 V84 C80 98 62 74 44 86 C28 96 14 96 1 88 Z\";\n\nfunction DocumentShape({ className }: { className: string }) {\n return (\n <svg className={className} viewBox=\"0 0 100 100\" preserveAspectRatio=\"none\" aria-hidden=\"true\">\n <path d={DOCUMENT_PATH} vectorEffect=\"non-scaling-stroke\" />\n </svg>\n );\n}\n\n/** A method input or final output: a document, stacked when it is a list. */\nexport function SimpleTerminalNode({ data, sourcePosition, targetPosition }: SimpleRFNodeProps) {\n const terminal = payloadOf(data, [\"input\", \"output\"] as const);\n if (!terminal) return null;\n return (\n <Handles sourcePosition={sourcePosition} targetPosition={targetPosition}>\n <div\n className={`simple-terminal simple-terminal--${terminal.kind}${terminal.isList ? \" simple-terminal--list\" : \"\"}`}\n >\n {terminal.isList && (\n <>\n <DocumentShape className=\"simple-terminal-shape simple-terminal-shape--back2\" />\n <DocumentShape className=\"simple-terminal-shape simple-terminal-shape--back1\" />\n </>\n )}\n <DocumentShape className=\"simple-terminal-shape\" />\n <div className=\"simple-terminal-text\">\n <span className=\"simple-terminal-title\" title={terminal.title}>\n {terminal.title}\n </span>\n {terminal.subtitle && (\n <span className=\"simple-terminal-subtitle\">{terminal.subtitle}</span>\n )}\n </div>\n </div>\n </Handles>\n );\n}\n\n// ─── Decision ───────────────────────────────────────────────────────────────\n\n/** A decision: a diamond carrying what the condition decides; its arrows carry the outcomes. */\nexport function SimpleDecisionNode({ data, sourcePosition, targetPosition }: SimpleRFNodeProps) {\n const decision = payloadOf(data, [\"decision\"] as const);\n if (!decision) return null;\n const statusClass = decision.graphMode !== \"static\" ? ` simple-decision--${decision.status}` : \"\";\n return (\n <Handles sourcePosition={sourcePosition} targetPosition={targetPosition}>\n <div className={`simple-decision${statusClass}${validationRingClass(data.validation)}`}>\n <svg\n className=\"simple-decision-shape\"\n viewBox=\"0 0 100 100\"\n preserveAspectRatio=\"none\"\n aria-hidden=\"true\"\n >\n <path d=\"M50 1 L99 50 L50 99 L1 50 Z\" vectorEffect=\"non-scaling-stroke\" />\n </svg>\n <div className=\"simple-decision-text\" title={decision.title}>\n {decision.title}\n </div>\n <div className=\"simple-decision-marks\">\n <StatusMark status={decision.status} graphMode={decision.graphMode} />\n <ValidationMark validation={data.validation} onClick={data.onValidationBadgeClick} />\n </div>\n </div>\n </Handles>\n );\n}\n\n// ─── \"For each\" frame ───────────────────────────────────────────────────────\n\n/** A batch whose branch has several steps: a light frame saying \"for each\", with a stack behind it. */\nexport function SimpleFrameNode({ data }: { data: GraphNodeData }) {\n const frame = payloadOf(data, [\"frame\"] as const);\n if (!frame) return null;\n return (\n <div className={`simple-frame${validationRingClass(data.validation)}`}>\n <div className=\"simple-frame-header\">\n <span className=\"simple-frame-title\">\n <Icon size={12}>{CATEGORY_ICONS.repeat}</Icon>\n {frame.title}\n </span>\n <StatusMark status={frame.status} graphMode={frame.graphMode} />\n <ValidationMark validation={data.validation} onClick={data.onValidationBadgeClick} />\n {frame.onFold && (\n <button\n type=\"button\"\n className=\"simple-frame-fold\"\n title=\"Fold into one step (alt/option: only this one)\"\n aria-label=\"Fold into one step\"\n onClick={(event) => {\n event.stopPropagation();\n frame.onFold?.({ soloMode: event.altKey });\n }}\n >\n {COLLAPSE_ICON}\n </button>\n )}\n </div>\n </div>\n );\n}\n\n// Stable reference — registered once in GraphViewer's module-level node types.\nexport const simpleNodeTypes = {\n [NODE_TYPE_SIMPLE_STEP]: SimpleStepNode,\n [NODE_TYPE_SIMPLE_TERMINAL]: SimpleTerminalNode,\n [NODE_TYPE_SIMPLE_DECISION]: SimpleDecisionNode,\n [NODE_TYPE_SIMPLE_FRAME]: SimpleFrameNode,\n};\n","import { BaseEdge, getSmoothStepPath } from \"@xyflow/react\";\nimport type { Edge, EdgeProps } from \"@xyflow/react\";\nimport { fitRoute, roundedPolylinePath, routeLabelCenter } from \"@graph/edgeRoutes\";\nimport type { RoutedEdgeData } from \"@graph/react/rfTypes\";\n\n/**\n * An edge drawn along the route the layout computed (`EDGE_TYPE_ROUTED`), so\n * it bends around the nodes in its way instead of crossing them, with its\n * label in the box the layout reserved. Once a node is dragged away from where\n * the layout put it, the route no longer meets its handles, and the edge falls\n * back to a rounded step between them.\n */\nexport function RoutedEdge({\n id,\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourcePosition,\n targetPosition,\n data,\n label,\n labelStyle,\n labelShowBg,\n labelBgStyle,\n labelBgPadding,\n labelBgBorderRadius,\n style,\n markerEnd,\n markerStart,\n interactionWidth,\n}: EdgeProps<Edge<RoutedEdgeData>>) {\n const route = data?.route;\n const fitted = route\n ? fitRoute(route.points, { x: sourceX, y: sourceY }, { x: targetX, y: targetY })\n : null;\n\n let path: string;\n let labelX: number;\n let labelY: number;\n if (route && fitted) {\n path = roundedPolylinePath(fitted);\n ({ x: labelX, y: labelY } = routeLabelCenter(route, fitted));\n } else {\n [path, labelX, labelY] = getSmoothStepPath({\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourcePosition,\n targetPosition,\n borderRadius: 8,\n });\n }\n\n return (\n <BaseEdge\n id={id}\n path={path}\n labelX={labelX}\n labelY={labelY}\n label={label}\n labelStyle={labelStyle}\n labelShowBg={labelShowBg}\n labelBgStyle={labelBgStyle}\n labelBgPadding={labelBgPadding}\n labelBgBorderRadius={labelBgBorderRadius}\n style={style}\n markerEnd={markerEnd}\n markerStart={markerStart}\n interactionWidth={interactionWidth}\n />\n );\n}\n"],"mappings":"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","names":["React","React","React","jsx","jsxs","React","React","jsx","jsxs","jsx","jsxs","jsx","jsxs","Fragment","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","jsx","jsxs","Fragment","jsx","jsxs","React","_a","_b","React","Fragment","jsx","jsxs","React","_a","jsx","jsxs","React","jsx","jsxs","React","React","jsx","jsxs","CHECK_ICON","React","Fragment","jsx","jsxs","jsxs","jsx","CHECK_ICON","React","Fragment","jsx","jsx","jsxs","_a","useState","jsx","jsxs","PIPE_TYPE_BADGES","useState","_a","Fragment","jsx","jsxs","Handle","Position","Fragment","jsx","jsxs","ICON_PROPS","EXPAND_ICON","COLLAPSE_ICON","Position","Handle","jsx","Fragment","jsx","jsxs","React","_a","_b","nodes","_c","graphspec"]}
1
+ {"version":3,"sources":["../../../src/graph/react/index.ts","../../../src/graph/react/viewer/GraphViewer.tsx","../../../src/graph/react/viewer/useSystemTheme.ts","../../../src/graph/react/detail/StuffResultPanel.tsx","../../../src/graph/react/viewer/graphArtifacts.ts","../../../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/usageFormat.ts","../../../src/graph/react/detail/sections/UsageSection.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/llmChoice.ts","../../../src/graph/react/detail/sections/PipeStructureDetail.tsx","../../../src/graph/react/detail/sections/PipeComposeDetail.tsx","../../../src/graph/react/detail/sections/PipeDocGenDetail.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/sections/BindingStepDetail.tsx","../../../src/graph/react/detail/sections/executionData.ts","../../../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/viewer/ValidationPanel.tsx","../../../src/graph/react/viewer/StyleMenu.tsx","../../../src/graph/react/viewer/usePopoverDismiss.ts","../../../src/graph/react/nodes/NodeValidationBadge.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","../../../src/graph/react/styles/simple/SimpleNodes.tsx","../../../src/graph/react/edges/RoutedEdge.tsx"],"sourcesContent":["\"use client\";\n\n// The graph's stylesheets are imported here and nowhere else. A component\n// importing its own would be bundled into a `dist/graph/react/index.css` that\n// nothing loads, beside the copy this import keeps (`make smoke-pack` checks).\nimport \"./graph-core.css\";\nimport \"./detail/DetailPanel.css\";\nimport \"./viewer/GraphToolbar.css\";\nimport \"./styles/simple/SimpleStyle.css\";\n// No form kernel stylesheet is imported here, on purpose. The detail panel\n// renders kernel controls (`StuffResultPanel` is the kernel's result view), and\n// the host styles those in the way its kind of host needs: a host with\n// Tailwind 4 compiles the kernel's classes itself, with\n// `@import \"@pipelex/mthds-ui/tailwind.css\"` in place of the `@source` line of\n// the kernel's documented setup, and a host without Tailwind imports\n// `@pipelex/mthds-ui/form-kernel.css` once. The README's \"Styling the form\n// controls\" section is the host's side of it.\n//\n// Do not put an import back. v0.20.0 made the kernel's sheet this entry's job\n// because Tailwind 3 hosts kept forgetting a content glob into node_modules and\n// silently lost the classes only the kernel uses; v0.21.0 wrapped the sheet in\n// a cascade layer after the raw copy beat the host's own responsive variants.\n// Neither arrangement works. The sheet is a complete Tailwind build, and in a\n// Tailwind 4 host its preflight belongs below the host's base while its\n// utilities belong above the host's base and below the host's utilities, which\n// one `@import … layer()` cannot express: appended, the layer outranked every\n// variant the host wrote; named first, the host's preflight stripped the\n// kernel's utilities. In a host without Tailwind, the preflight reset every\n// browser default on the page the moment a graph mounted.\n// `docs/run-form-panel.md` has the full account.\n\n// Viewer\nexport { GraphViewer, applyStatusOverrides } from \"./viewer/GraphViewer\";\nexport type { GraphViewerProps } from \"./viewer/GraphViewer\";\n// The one object GraphViewer draws: a graph and the descriptors from its source.\nexport { graphArtifactsFrom, resultDescriptors } from \"./viewer/graphArtifacts\";\nexport type {\n GraphArtifacts,\n GraphArtifactsSource,\n ResultDescriptors,\n} from \"./viewer/graphArtifacts\";\nexport { renderLabel, hydrateLabels } from \"./viewer/renderLabel\";\n// Validation widget — the panel + its pure helpers (the widget itself is part\n// of GraphToolbar and enabled via GraphViewer's `validationState` prop).\nexport {\n ValidationPanel,\n validationLabel,\n validationPanelPlacement,\n} from \"./viewer/ValidationPanel\";\nexport type { ValidationPanelPlacement, ValidationPanelProps } from \"./viewer/ValidationPanel\";\n// System-theme detection — for hosts that drive `system` from their own\n// environment signal (e.g. a VS Code webview) or need the browser default.\nexport { useSystemTheme, detectSystemTheme } from \"./viewer/useSystemTheme\";\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// The graph's data panel, rendered from the standard's own artifacts. Exported\n// for a host that wants the same view outside the graph.\nexport { StuffResultPanel } from \"./detail/StuffResultPanel\";\nexport type { StuffResultPanelProps, StuffResultRendererOptions } from \"./detail/StuffResultPanel\";\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 GraphSpecNodeIoItem,\n DataflowAnalysis,\n FoldMode,\n FoldToggleOptions,\n GraphStyleId,\n GraphTheme,\n GraphThemeMode,\n PipeStatus,\n ConceptInfo,\n ToolbarPosition,\n ValidationIssue,\n ValidationState,\n} from \"@graph/types\";\nimport {\n BINDING_STEP_TYPE,\n stuffDigestFromId,\n EDGE_TYPE,\n EDGE_TYPE_ROUTED,\n FOLD_MODE,\n GRAPH_SPEC_MODE,\n GRAPH_DIRECTION,\n GRAPH_THEME_MODE,\n graphSpecMode,\n} from \"@graph/types\";\nimport { useSystemTheme } from \"./useSystemTheme\";\nimport { buildChildToControllerMap, resolveConceptRef } from \"@graph/graphAnalysis\";\nimport {\n applyValidationDecorations,\n buildValidationDecorations,\n resolveIssueTargetNodeId,\n} from \"@graph/graphValidation\";\nimport { findStuffByDigest } from \"@graph/stuffLookup\";\nimport type { SaveFiles } from \"@pipelex/mthds-form\";\nimport type { DownloadDisplay, ResolveShareUrl, ResolveUrl } from \"@pipelex/mthds-form/react\";\nimport { StuffResultPanel } from \"../detail/StuffResultPanel\";\nimport { resultDescriptors, type GraphArtifacts } from \"./graphArtifacts\";\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 { validateGraphSpec } from \"@graph/validateGraphSpec\";\nimport { applyFolds, findCousinControllers } from \"@graph/graphFolds\";\nimport { getLayoutedElements } from \"@graph/graphLayout\";\nimport type { ControllerRect } from \"@graph/graphControllers\";\nimport { DEFAULT_GRAPH_CONFIG, getPaletteForTheme } from \"@graph/graphConfig\";\nimport { GRAPH_STYLES, resolveGraphStyle, resolveStyleMenu } from \"@graph/styles/graphStyles\";\nimport { GRAPH_STYLE_PIPELINES } from \"@graph/styles/stylePipelines\";\nimport { hydrateLabels } from \"./renderLabel\";\nimport { GraphToolbar } from \"./GraphToolbar\";\nimport { controllerNodeTypes } from \"../nodes/controller/ControllerGroupNode\";\nimport { PipeCardRFNode } from \"../nodes/pipe/PipeCardNode\";\nimport { simpleNodeTypes } from \"../styles/simple/SimpleNodes\";\nimport { RoutedEdge } from \"../edges/RoutedEdge\";\n\n// Stable reference — must be declared outside the component to avoid ReactFlow\n// re-mounts. Every style's node components are registered once, here.\nconst nodeTypes = {\n ...controllerNodeTypes,\n pipeCard: PipeCardRFNode,\n ...simpleNodeTypes,\n};\n\n// Likewise for edge components: the built-in curves, plus the edge drawn along\n// the layout's route, for the styles that ask the layout to route edges.\nconst edgeTypes = { [EDGE_TYPE_ROUTED]: RoutedEdge };\n\nexport interface GraphViewerProps {\n /**\n * The graph to draw, together with the artifacts that describe its pipes —\n * all four from ONE source: a run's results, or a method's validate report\n * beside the dry or static graph of that same method. `null` draws nothing.\n *\n * One object rather than a spec prop and three descriptor props, because the\n * detail panel looks a data node's descriptor up by the `pipe_ref` of the pipe\n * that produced it IN THIS GRAPH. A graph paired with another source's\n * descriptors misses every lookup. See `GraphArtifacts`.\n *\n * Without `pipeIoContracts` and `outputForm`, the panel still works: it shows\n * the concept's structure table and no data tab, which is the honest floor\n * for a graph whose artifacts the host does not hold.\n */\n graph: GraphArtifacts | 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 /**\n * Theme *mode*: `dark | light | system`. Reactive: passing it as a prop drives\n * the active mode, and clearing it back to `undefined` hands control back to\n * `config.theme` (or the default `system`). Users can also cycle it via the\n * built-in toolbar button (unless `showThemeToggle` is `false`).\n *\n * `system` resolves to the environment theme — the browser's\n * `prefers-color-scheme`, or `systemTheme` when injected.\n *\n * Defaults to `config.theme` or `\"system\"`.\n */\n theme?: GraphThemeMode;\n /**\n * Anchor for the built-in toolbar. Controlled + reactive: pass a new value to\n * move it, and the viewer reacts immediately. This library does NOT persist the\n * value — the host owns it (read its own state, change it by passing a new prop).\n *\n * Orientation (horizontal row vs vertical column) is derived from the position,\n * not configured separately: only `center-left` / `center-right` render a\n * vertical bar; the four corners plus `top-center` / `bottom-center` are\n * horizontal.\n *\n * Precedence: this prop → `config.toolbarPosition` → `\"top-right\"`.\n */\n toolbarPosition?: ToolbarPosition;\n /**\n * The style the graph is drawn in: `detailed` (every pipe with its inputs,\n * outputs and settings) or `simple` (the method's steps in plain words).\n * Reactive, like `theme`: passing it drives the active style, and clearing it\n * back to `undefined` hands control to `config.graphStyle`, then the default\n * `detailed`. The toolbar's style menu, when shown, changes it too. A value\n * naming no registered style is treated as unset. This library persists\n * nothing: the host keeps the choice, reported by `onGraphStyleChange`.\n */\n graphStyle?: GraphStyleId;\n /**\n * Called whenever the style changes — from the menu, or from a prop or config\n * update — so the host can persist it. Not called on mount.\n */\n onGraphStyleChange?: (style: GraphStyleId) => void;\n /**\n * Show a style menu in the toolbar. Opt-in: `true` offers every registered\n * style in registry order, a list offers those styles in that order, and the\n * default offers no menu, for a host that fixes the style for its audience.\n * A menu needs two styles to choose between.\n */\n styleMenu?: boolean | readonly GraphStyleId[];\n /**\n * Host-injected environment theme, authoritative when set. Forwarded to the\n * `system` resolver so non-browser hosts (e.g. VS Code webviews, where\n * `prefers-color-scheme` is unreliable) can drive `system` from their own\n * detection. When omitted, `system` follows the browser's `prefers-color-scheme`.\n */\n systemTheme?: GraphTheme;\n /**\n * Whether to render the theme toggle button in the built-in toolbar.\n * Defaults to `true`. Set to `false` to hide it (useful when the host app\n * fully controls `theme` from the outside).\n */\n showThemeToggle?: boolean;\n /**\n * Called whenever the theme changes — from the built-in toggle, from external\n * prop / config updates, or when `system` re-resolves because the environment\n * changed. Receives both the selected `mode` (for persistence) and the\n * `resolvedTheme` (for keeping page chrome outside the container in sync).\n */\n onThemeChange?: (mode: GraphThemeMode, resolvedTheme: GraphTheme) => void;\n onNavigateToPipe?: (pipeCode: string, status?: PipeStatus) => void;\n onStuffNodeClick?: (stuff: GraphSpecNodeIoItem) => void;\n onReactFlowInit?: (instance: AppRFInstance) => void;\n /**\n * Layer 2 execution state: pipe_code → current status. Updates node status dots in real-time.\n * A binding card is never matched: its `pipeCode` is the path it binds, not a pipe's code.\n */\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 * Turns the runtime's own `pipelex-storage://…` reference into a URL a\n * browser can fetch, so files in a result actually paint.\n *\n * Without it the panel falls back to whatever `public_url` the payload\n * carries — which on the hosted platform is a PRESIGNED URL with an hour's\n * life, baked into the stored result. Yesterday's run then shows broken\n * images, and the URL answers `403` in a way that reads as a permissions\n * problem rather than an expiry. A resolver is what makes a stored result\n * durable, so supply one if your storage has an authenticated read path.\n */\n resolveUrl?: ResolveUrl;\n /**\n * Mints a URL that works OUTSIDE this page, for the copy control.\n *\n * Distinct from `resolveUrl` because the two answers genuinely differ: a\n * display URL may be a path behind the host's own session — which is what\n * lets a strict `img-src 'self'` stand — and that URL is useless to whoever\n * pastes it. A shared one carries its own credential and is minted per click,\n * since it starts expiring the moment it exists.\n */\n resolveShareUrl?: ResolveShareUrl;\n /**\n * Delivers the files the result panel's downloads hand over: its Download\n * control and each file's own button.\n *\n * Without it the kernel saves them in the browser tab, through an object URL\n * and a clicked link. A host whose view runs in a sandboxed frame is refused\n * both, so its downloads fail without a word unless it supplies this, handing\n * the planned files to its own bridge. It goes on the panel's provider beside\n * `resolveUrl`, which replaces an outer provider rather than merging with it,\n * so a `saveFiles` set around the graph does not reach the panel.\n */\n saveFiles?: SaveFiles;\n /**\n * Which of the result panel's download controls are drawn: the whole-result\n * Download (`result`) and each file's own button (`files`, which also takes\n * the kinds that carry one). Both are drawn by default.\n */\n downloads?: DownloadDisplay;\n /**\n * State of the toolbar's validation widget. The widget renders only when this\n * is set — `undefined` (the default) disables the feature entirely. Reactive:\n * a host typically drives `validating → valid | invalid | error` as its\n * validator progresses, without re-mounting the viewer.\n */\n validationState?: ValidationState;\n /**\n * Issues listed in the validation widget's dropdown (the badge shows their\n * count). Presentation-only — the host decides which issues to surface per\n * state (validator errors, static-analysis diagnostics, or a mix; see\n * `staticDiagnosticsToValidationIssues` in `@pipelex/mthds-ui/static-graph`).\n */\n validationIssues?: ValidationIssue[];\n /**\n * Called when an issue row is clicked, with the row's index in\n * `validationIssues`. Wire this to source navigation in the host.\n */\n onValidationIssueClick?: (index: number, issue: ValidationIssue) => void;\n}\n\n/** Stuff node detail: concept structure, plus whatever the host renders for its data. */\nfunction StuffNodeDetail({\n nodeId,\n stuffData,\n producerPipeRef,\n consumer,\n graphspec,\n artifacts,\n theme,\n resolveUrl,\n resolveShareUrl,\n saveFiles,\n downloads,\n}: {\n /** Selected graph node id — identity for per-node panel state (tab reset). */\n nodeId: string;\n stuffData: GraphSpecNodeIoItem;\n producerPipeRef?: string;\n consumer?: { pipeRef: string; slotName: string };\n graphspec: GraphSpec | null;\n /** The descriptors that came with `graphspec`, in the same `graph` object. */\n artifacts: GraphArtifacts | null;\n theme: GraphTheme;\n resolveUrl?: ResolveUrl;\n resolveShareUrl?: ResolveShareUrl;\n saveFiles?: SaveFiles;\n downloads?: DownloadDisplay;\n}) {\n const conceptInfo =\n stuffData.concept && graphspec ? resolveConceptRef(graphspec, stuffData.concept) : undefined;\n const isDryRun = graphSpecMode(graphspec) === GRAPH_SPEC_MODE.DRY;\n\n // Built here rather than inside `ConceptDetailPanel` so both branches below\n // render the SAME panel: a stuff with no concept in the spec is still a stuff\n // whose value can be shown, and it is exactly the case the old fallback\n // treated as second-class.\n //\n // Both artifacts or neither. The contract names the payload's shape and the\n // descriptor says what the result IS, so a panel given one of the two would be\n // guessing the other — which is the whole failure `output_form` exists to end.\n const descriptors = resultDescriptors(artifacts);\n const renderData = descriptors\n ? () => (\n <StuffResultPanel\n {...descriptors}\n stuff={stuffData}\n {...(conceptInfo ? { concept: conceptInfo } : {})}\n {...(producerPipeRef ? { producerPipeRef } : {})}\n {...(consumer ? { consumer } : {})}\n {...(resolveUrl ? { resolveUrl } : {})}\n {...(resolveShareUrl ? { resolveShareUrl } : {})}\n {...(saveFiles ? { saveFiles } : {})}\n {...(downloads ? { downloads } : {})}\n theme={theme}\n />\n )\n : undefined;\n\n if (conceptInfo) {\n return (\n <ConceptDetailPanel\n concept={conceptInfo}\n ioData={stuffData}\n isDryRun={isDryRun}\n instanceKey={nodeId}\n renderData={renderData}\n />\n );\n }\n if (isDryRun) return <div className=\"detail-not-available\">Dry run data hidden</div>;\n // No concept in the spec, so there is no structure to show and no tabs to\n // choose between — just the data, if anything can render it.\n return <>{renderData?.() ?? <div className=\"detail-not-available\">No data</div>}</>;\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\n/**\n * Resolve the externally-driven theme *mode* from `(themeProp, config.theme,\n * default)`. Pure function so the reactivity contract is unit-testable without\n * React.\n *\n * Contract — must hold for every transition (regression-tested in\n * `__tests__/themeResolution.test.ts`):\n * - `themeProp` wins when set\n * - falls back to `config.theme` when `themeProp` is undefined (so a host can\n * hand theme control back to config after passing it as a prop)\n * - falls back to the library default (`system`) when neither is set\n * - a `themeProp` transition controlled→undefined→same-prior-value still\n * round-trips through the config fallback rather than silently re-using\n * the previous prop value\n */\nexport function resolveExternalThemeMode(\n themeProp: GraphThemeMode | undefined,\n configTheme: GraphThemeMode | undefined,\n): GraphThemeMode {\n return themeProp ?? configTheme ?? DEFAULT_GRAPH_CONFIG.theme ?? GRAPH_THEME_MODE.SYSTEM;\n}\n\n/**\n * Collapse a theme mode + the detected environment theme into the binary\n * `GraphTheme` that drives the palette and container class. `system` follows the\n * environment; `dark`/`light` are returned as-is. Pure + exported for testing.\n */\nexport function resolveActiveTheme(mode: GraphThemeMode, systemTheme: GraphTheme): GraphTheme {\n return mode === GRAPH_THEME_MODE.SYSTEM ? systemTheme : mode;\n}\n\n/**\n * Resolve the toolbar anchor from `(positionProp, config.toolbarPosition,\n * default)`. Pure + exported so the controlled/reactive precedence is\n * unit-testable without React. Mirrors `resolveExternalThemeMode`:\n * - the `toolbarPosition` prop wins when set,\n * - falls back to `config.toolbarPosition` when the prop is undefined,\n * - falls back to the library default (`top-right`) when neither is set.\n */\nexport function resolveToolbarPosition(\n positionProp: ToolbarPosition | undefined,\n configPosition: ToolbarPosition | undefined,\n): ToolbarPosition {\n // `DEFAULT_GRAPH_CONFIG.toolbarPosition` is the single source of the library\n // default (typed non-optional), so the chain needs no extra literal floor.\n return positionProp ?? configPosition ?? DEFAULT_GRAPH_CONFIG.toolbarPosition;\n}\n\n/** Remove the transient flash class (undefined when nothing else remains). */\nfunction stripFlash(className: string | undefined): string | undefined {\n return className?.replace(/\\s*\\bnode-validation-flash\\b/, \"\") || undefined;\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/**\n * The run status a node shows, whatever the style: a card's, or a simple-style\n * step's, decision's or frame's. Undefined for data and for a node without one.\n */\nexport function nodeRunStatus(data: AppNode[\"data\"]): PipeStatus | undefined {\n const simple = data.simple;\n if (simple) return \"status\" in simple ? simple.status : undefined;\n return data.pipeCardData?.status;\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 if (node.data.graphMode === \"static\" || node.data.pipeCardData?.graphMode === \"static\") {\n return node;\n }\n // A binding card's `pipeCode` is its `from` path, which a pipe may share\n // (`from = \"summary\"` beside a pipe coded `summary`): no status keyed by\n // pipe code is about it.\n if (node.data.pipeType === BINDING_STEP_TYPE) return node;\n const pipeCode = node.data.pipeCode;\n if (!pipeCode || !Object.hasOwn(statusMap, pipeCode)) return node;\n const newStatus = statusMap[pipeCode];\n const simple = node.data.simple;\n // The simple style's steps, decisions and frames carry a status; its inputs and outputs do not.\n const simpleWithStatus = simple && \"status\" in simple ? simple : undefined;\n if (nodeRunStatus(node.data) === 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 simple: simpleWithStatus ? { ...simpleWithStatus, status: newStatus } : simple,\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?: GraphSpecNodeIoItem;\n /** `domain.code` of the pipe that produced the stuff, when one did. */\n producerPipeRef?: string;\n /** The first pipe reading it, for the method inputs no pipe produced. */\n consumer?: { pipeRef: string; slotName: string };\n}\n\nexport function GraphViewer(props: GraphViewerProps) {\n const {\n graph,\n config = DEFAULT_GRAPH_CONFIG,\n initialDirection,\n initialShowControllers,\n initialFoldMode,\n hideToolbar = false,\n theme: themeProp,\n graphStyle: graphStyleProp,\n onGraphStyleChange,\n styleMenu,\n toolbarPosition: toolbarPositionProp,\n systemTheme: systemThemeProp,\n showThemeToggle = true,\n onThemeChange,\n onNavigateToPipe,\n onStuffNodeClick,\n onReactFlowInit,\n statusMap,\n onNodeSelect,\n onPaneClick,\n renderDetailExtra,\n resolveUrl,\n resolveShareUrl,\n saveFiles,\n downloads,\n validationState,\n validationIssues,\n onValidationIssueClick,\n } = props;\n\n // The spec is read out of the `graph` bundle and memoized on ITS identity,\n // not the wrapper's: a host writing `graph={{ graphSpec, … }}` inline hands\n // over a new wrapper every render, and keying the build on that would re-run\n // the ELK layout on every parent render.\n const graphspecProp = graph?.graphSpec ?? null;\n\n // Single boundary validator for the React render path — mirrors the standalone\n // adapter (src/standalone/adapter.ts). Memoized on prop identity so it runs\n // once per spec; validateGraphSpec normalizes io in place and is idempotent.\n const graphspec = React.useMemo(\n () => (graphspecProp === null ? null : validateGraphSpec(graphspecProp)),\n [graphspecProp],\n );\n\n const [direction, setDirection] = React.useState<GraphDirection>(\n () =>\n initialDirection ?? config.direction ?? DEFAULT_GRAPH_CONFIG.direction ?? GRAPH_DIRECTION.TB,\n );\n\n // Resolve the externally-driven mode on every render so prop AND config\n // changes both propagate (regression for PR-41 review comments: prop\n // clearing must fall back through config, and config.theme changes must\n // not stay stale). `resolveExternalThemeMode` is exported + unit-tested.\n const externalMode = resolveExternalThemeMode(themeProp, config.theme);\n const [mode, setMode] = React.useState<GraphThemeMode>(externalMode);\n const prevExternalModeRef = React.useRef<GraphThemeMode>(externalMode);\n React.useEffect(() => {\n if (externalMode !== prevExternalModeRef.current) {\n prevExternalModeRef.current = externalMode;\n setMode(externalMode);\n }\n }, [externalMode]);\n\n // Resolve `system` to a binary theme via the environment. `systemThemeProp`,\n // when set, is authoritative (host owns detection); otherwise this follows\n // the browser's `prefers-color-scheme` live.\n const systemTheme = useSystemTheme(systemThemeProp);\n const resolvedTheme = resolveActiveTheme(mode, systemTheme);\n\n // Notify the host whenever the mode OR the resolved theme changes. Covers\n // internal toggle clicks, external prop/config updates, and `system`\n // re-resolving on an environment change — all from one place — and stays\n // correct even if the host re-renders for unrelated reasons. Reports both so\n // chrome-sync uses `resolvedTheme` while persistence uses `mode`.\n const onThemeChangeRef = React.useRef(onThemeChange);\n onThemeChangeRef.current = onThemeChange;\n const prevReportedRef = React.useRef<{ mode: GraphThemeMode; resolvedTheme: GraphTheme }>({\n mode,\n resolvedTheme,\n });\n React.useEffect(() => {\n const prev = prevReportedRef.current;\n if (prev.mode !== mode || prev.resolvedTheme !== resolvedTheme) {\n prevReportedRef.current = { mode, resolvedTheme };\n onThemeChangeRef.current?.(mode, resolvedTheme);\n }\n }, [mode, resolvedTheme]);\n\n // The style follows the same controlled + reactive contract as the theme\n // mode: resolved from (prop, config, default) on every render, adopted when\n // that resolution changes, and changeable from the toolbar menu in between.\n const externalStyle = resolveGraphStyle(graphStyleProp, config.graphStyle);\n const [graphStyle, setGraphStyle] = React.useState<GraphStyleId>(externalStyle);\n const prevExternalStyleRef = React.useRef<GraphStyleId>(externalStyle);\n React.useEffect(() => {\n if (externalStyle !== prevExternalStyleRef.current) {\n prevExternalStyleRef.current = externalStyle;\n setGraphStyle(externalStyle);\n }\n }, [externalStyle]);\n const onGraphStyleChangeRef = React.useRef(onGraphStyleChange);\n onGraphStyleChangeRef.current = onGraphStyleChange;\n const prevReportedStyleRef = React.useRef<GraphStyleId>(graphStyle);\n React.useEffect(() => {\n if (prevReportedStyleRef.current !== graphStyle) {\n prevReportedStyleRef.current = graphStyle;\n onGraphStyleChangeRef.current?.(graphStyle);\n }\n }, [graphStyle]);\n const graphStyleRef = React.useRef(graphStyle);\n graphStyleRef.current = graphStyle;\n const styleCapabilities = GRAPH_STYLES[graphStyle].capabilities;\n\n const effectiveFoldMode: FoldMode =\n initialFoldMode ?? config.foldMode ?? DEFAULT_GRAPH_CONFIG.foldMode ?? FOLD_MODE.EXPANDED;\n\n // Folded mode requires showControllers — without it the toolbar's expand-all\n // button is hidden and the user has no global path to unfold the graph.\n const [showControllers, setShowControllers] = React.useState<boolean>(() => {\n if (effectiveFoldMode === FOLD_MODE.FOLDED) return true;\n return (\n initialShowControllers ??\n config.showControllers ??\n DEFAULT_GRAPH_CONFIG.showControllers ??\n false\n );\n });\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 // Theme-derived palette is the base; explicit `config.paletteColors` wins per-key.\n React.useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n const themePalette = getPaletteForTheme(resolvedTheme);\n const overrides = config.paletteColors;\n const palette = overrides ? { ...themePalette, ...overrides } : themePalette;\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, resolvedTheme]);\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 /** The style these nodes were projected for. */\n _graphStyle: GraphStyleId;\n /** What the style draws for each spec node it does not draw. */\n _standIns?: ReadonlyMap<string, string>;\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 /** Containment map derived once per graphspec (pure in graphspec+analysis). */\n childToCtrl: Record<string, string>;\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 /**\n * The graphspec these layouted nodes belong to. Cache-reuse effects must\n * skip when this is not the graphspec in `initialDataRef` — on a graphspec\n * swap the cache is only refreshed after the async layout resolves, and\n * rebuilding controllers from old nodes against the new spec would render\n * garbage (or throw on the id mismatch).\n */\n graphspec: GraphSpec | null;\n /**\n * The style these layouted nodes were drawn in. The same guard as\n * `graphspec`, for a style switch: until the new style's layout resolves,\n * the cache holds the previous style's nodes, and framing them with the new\n * style's pass would render garbage.\n */\n graphStyle: GraphStyleId;\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 // The folds the current style added on its own, as opposed to the host's fold\n // mode and the reader's: a style switch swaps these and keeps the others.\n // Once the reader folds or opens a controller, the choice is theirs, and a\n // controller they opened stays open whatever a later style folds by itself.\n const styleDefaultFoldsRef = React.useRef<Set<string>>(new Set());\n const readerOpenedRef = React.useRef<Set<string>>(new Set());\n const markReaderFolds = React.useCallback((ids: Iterable<string>, folded: boolean) => {\n for (const id of ids) {\n styleDefaultFoldsRef.current.delete(id);\n if (folded) readerOpenedRef.current.delete(id);\n else readerOpenedRef.current.add(id);\n }\n }, []);\n\n const toggleFold = React.useCallback(\n (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 markReaderFolds(targets, shouldFold);\n return next;\n });\n },\n [markReaderFolds],\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 const validationIssuesRef = React.useRef(validationIssues);\n validationIssuesRef.current = validationIssues;\n const selectedNodeIdRef = React.useRef<string | null>(null);\n selectedNodeIdRef.current = detailSelection?.nodeId ?? null;\n\n // Validation dropdown open state — owned here (not in GraphToolbar) so node\n // badges can open the panel too. The toolbar reports toggle/dismiss requests\n // through onValidationOpenChange.\n const [validationOpen, setValidationOpen] = React.useState(false);\n const openValidationPanel = React.useCallback(() => setValidationOpen(true), []);\n // Badges only get a click handler while the panel can actually appear —\n // otherwise they'd render as buttons whose click has no visible effect.\n const validationWidgetAvailable = validationState !== undefined && !hideToolbar;\n const validationWidgetAvailableRef = React.useRef(validationWidgetAvailable);\n validationWidgetAvailableRef.current = validationWidgetAvailable;\n\n // Final per-render node pass, shared by every setNodes site: hydrate labels,\n // apply execution-status overrides, then stamp validation decorations derived\n // from the CURRENT issues + fold state (folded controllers roll up their\n // hidden descendants' issues). Reads refs only, so the callback is stable.\n const decorateNodes = React.useCallback(\n (nodes: GraphNode[]): AppNode[] => {\n const raw = rawGraphDataRef.current;\n const decorations = buildValidationDecorations(\n validationIssuesRef.current,\n raw?.graphspec ?? null,\n raw?.childToCtrl ?? {},\n foldedRef.current,\n initialDataRef.current?._standIns,\n );\n const decorated = applyValidationDecorations(\n applyStatusOverrides(toAppNodes(hydrateLabels(nodes)), statusMapRef.current),\n decorations,\n validationWidgetAvailableRef.current ? openValidationPanel : undefined,\n );\n // The node open in the detail panel stays selected through a rebuild —\n // a style switch, a re-layout — since a node drawn in every style keeps\n // its spec id. One the new style does not draw stays open, unselected.\n const selectedId = selectedNodeIdRef.current;\n return selectedId\n ? decorated.map((n) => (n.id === selectedId ? { ...n, selected: true } : n))\n : decorated;\n },\n [openValidationPanel],\n );\n\n // The style's frame pass over a laid-out graph: the one place the viewer\n // wraps nodes in frames, shared by every path that re-renders from a layout.\n // Takes the style the layout was drawn in, never the current one, so a path\n // reusing a cached layout frames it the way it was projected.\n const frameLayout = React.useCallback(\n (\n style: GraphStyleId,\n layout: {\n nodes: GraphNode[];\n edges: GraphEdge[];\n controllerPositions?: Record<string, ControllerRect>;\n },\n graphspec: GraphSpec | null,\n analysis: DataflowAnalysis | null,\n ) =>\n GRAPH_STYLE_PIPELINES[style].frame({\n nodes: cloneCachedNodes(layout.nodes),\n edges: layout.edges,\n graphspec,\n analysis,\n controllerPositions: layout.controllerPositions,\n showControllers: showControllersRef.current,\n expandedControllers: expandedRef.current,\n onToggleCollapse: toggleCollapseRef.current,\n onToggleFold: toggleFoldRef.current,\n }),\n [],\n );\n\n /** Whether the layout cache holds the nodes `initialDataRef` was projected to. */\n const cacheMatchesData = (): boolean => {\n const cache = layoutCacheRef.current;\n const data = initialDataRef.current;\n return (\n cache !== null &&\n data !== null &&\n cache.graphspec === data._graphspec &&\n cache.graphStyle === data._graphStyle\n );\n };\n\n // Panel row click → host source-jump AND graph pan/flash to the target node\n // (when the issue targets one). The flash is a transient class on the\n // ReactFlow node wrapper; it is dropped on the next full node rebuild, which\n // is fine — it only needs to outlive its CSS animation.\n const nodesRef = React.useRef<AppNode[]>([]);\n nodesRef.current = nodes;\n const onValidationIssueClickRef = React.useRef(onValidationIssueClick);\n onValidationIssueClickRef.current = onValidationIssueClick;\n const flashTimeoutRef = React.useRef<ReturnType<typeof setTimeout> | null>(null);\n React.useEffect(\n () => () => {\n if (flashTimeoutRef.current) clearTimeout(flashTimeoutRef.current);\n },\n [],\n );\n\n const handleValidationIssueClick = React.useCallback(\n (index: number, issue: ValidationIssue) => {\n onValidationIssueClickRef.current?.(index, issue);\n const raw = rawGraphDataRef.current;\n if (!raw?.graphspec || !raw.analysis) return;\n const targetId = resolveIssueTargetNodeId(\n issue,\n raw.graphspec,\n raw.childToCtrl,\n foldedRef.current,\n new Set(nodesRef.current.map((n) => n.id)),\n initialDataRef.current?._standIns,\n );\n if (!targetId) return;\n void reactFlowRef.current?.fitView({\n nodes: [{ id: targetId }],\n duration: 500,\n padding: 0.4,\n });\n if (flashTimeoutRef.current) clearTimeout(flashTimeoutRef.current);\n setNodes((nds) =>\n nds.map((n) => {\n const base = stripFlash(n.className);\n if (n.id === targetId) {\n return {\n ...n,\n className: base ? `${base} node-validation-flash` : \"node-validation-flash\",\n };\n }\n return base === n.className ? n : { ...n, className: base };\n }),\n );\n flashTimeoutRef.current = setTimeout(() => {\n setNodes((nds) =>\n nds.map((n) => {\n const base = stripFlash(n.className);\n return base === n.className ? n : { ...n, className: base };\n }),\n );\n }, 1800);\n },\n [setNodes],\n );\n\n // Re-layout when direction or layout config changes\n React.useEffect(() => {\n if (!initialDataRef.current) return;\n let cancelled = false;\n\n void (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 GRAPH_STYLES[data._graphStyle].layout ?? 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 graphspec: data._graphspec,\n graphStyle: data._graphStyle,\n };\n const withControllers = frameLayout(\n data._graphStyle,\n relayouted,\n data._graphspec,\n data._analysis,\n );\n setNodes(decorateNodes(withControllers.nodes));\n setEdges(toAppEdges(withControllers.edges));\n setTimeout(() => {\n if (!cancelled && reactFlowRef.current) {\n void 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 const cache = layoutCacheRef.current;\n const data = initialDataRef.current;\n // Mid-swap guard: the cache still holds the previous graphspec's (or\n // style's) layout until the async layout lands; the in-flight build will\n // repaint anyway.\n if (!cache || !data || !cacheMatchesData()) return;\n const withControllers = frameLayout(cache.graphStyle, cache, data._graphspec, data._analysis);\n setNodes(decorateNodes(withControllers.nodes));\n setEdges(toAppEdges(withControllers.edges));\n }, [showControllers, expandedControllers, toggleCollapse, toggleFold, decorateNodes]);\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 // A style or edge-type switch redraws the same spec, and keeps what the\n // reader opened and folded; only a new spec starts afresh.\n const sameSpec = rawGraphDataRef.current?.graphspec === graphspec;\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 if (!sameSpec) {\n setExpandedControllers(new Set());\n expandedRef.current = new Set();\n }\n\n const style = graphStyleRef.current;\n const pipeline = GRAPH_STYLE_PIPELINES[style];\n const { graphData, analysis } = buildGraph(graphspec, edgeType);\n rawGraphDataRef.current = {\n nodes: graphData.nodes,\n edges: graphData.edges,\n analysis,\n graphspec,\n childToCtrl: analysis ? buildChildToControllerMap(graphspec, analysis) : {},\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 // The host's fold mode on a new spec, or the folds already there on a\n // switch less the previous style's own, plus whatever this style folds\n // that the reader has not opened.\n if (!sameSpec) readerOpenedRef.current = new Set();\n let seedSet = new Set<string>();\n const styleDefaults = new Set<string>();\n if (analysis) {\n const kept = sameSpec\n ? [...foldedRef.current].filter((id) => !styleDefaultFoldsRef.current.has(id))\n : [...seedFoldedControllers(foldModeRef.current, analysis.controllerNodeIds)];\n seedSet = new Set(kept);\n for (const id of pipeline.defaultFolds(graphspec, analysis)) {\n if (seedSet.has(id) || readerOpenedRef.current.has(id)) continue;\n styleDefaults.add(id);\n seedSet.add(id);\n }\n }\n styleDefaultFoldsRef.current = styleDefaults;\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 // Mirror the mount-time guarantee: a folded graph must have showControllers\n // on, otherwise the toolbar's expand-all button is hidden and the user has\n // no global path to unfold. Needed at graphspec-swap time too — the\n // useState initializer above only runs on the first render.\n // Only a style whose folds are undone from controller frames needs them.\n if (\n seedSet.size > 0 &&\n GRAPH_STYLES[style].capabilities.controllerFrameToggle &&\n !showControllersRef.current\n ) {\n setShowControllers(true);\n showControllersRef.current = true;\n }\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 const projected = pipeline.project({\n graphspec,\n nodes: folded.nodes,\n edges: folded.edges,\n analysis: folded.analysis,\n rawAnalysis: analysis,\n });\n\n initialDataRef.current = {\n nodes: projected.nodes,\n edges: projected.edges,\n _analysis: projected.analysis,\n _graphspec: graphspec,\n _graphStyle: style,\n ...(projected.standIns ? { _standIns: projected.standIns } : {}),\n };\n\n void (async () => {\n try {\n const currentDirection = directionRef.current;\n const currentLayoutConfig = GRAPH_STYLES[style].layout ?? layoutConfigRef.current;\n const needsLayout = projected.nodes.some(\n (n) => !n.position || (n.position.x === 0 && n.position.y === 0),\n );\n const layouted = needsLayout\n ? await getLayoutedElements(\n projected.nodes,\n projected.edges,\n currentDirection,\n currentLayoutConfig,\n graphspec,\n projected.analysis,\n )\n : {\n nodes: projected.nodes,\n edges: projected.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 graphspec,\n graphStyle: style,\n };\n const withControllers = frameLayout(style, layouted, graphspec, projected.analysis);\n\n setNodes(decorateNodes(withControllers.nodes));\n setEdges(toAppEdges(withControllers.edges));\n\n // Fit view after render, then apply zoom/pan overrides\n setTimeout(() => {\n if (!cancelled && reactFlowRef.current) {\n void reactFlowRef.current.fitView({ padding: 0.1 });\n if (initialZoomRef.current !== undefined && initialZoomRef.current !== null) {\n void reactFlowRef.current.zoomTo(initialZoomRef.current);\n }\n if (panToTopRef.current) {\n const vp = reactFlowRef.current.getViewport();\n void 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 // A style switch rebuilds like an edge-type change: the same spec, drawn anew.\n }, [graphspec, edgeType, graphStyle]);\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 style = graphStyleRef.current;\n const folded = applyFolds(\n { nodes: raw.nodes, edges: raw.edges },\n currentAnalysis,\n currentGraphspec,\n foldedControllers,\n toggleFold,\n );\n const projected = GRAPH_STYLE_PIPELINES[style].project({\n graphspec: currentGraphspec,\n nodes: folded.nodes,\n edges: folded.edges,\n analysis: folded.analysis,\n rawAnalysis: currentAnalysis,\n });\n initialDataRef.current = {\n nodes: projected.nodes,\n edges: projected.edges,\n _analysis: projected.analysis,\n _graphspec: currentGraphspec,\n _graphStyle: style,\n ...(projected.standIns ? { _standIns: projected.standIns } : {}),\n };\n\n void (async () => {\n try {\n const layouted = await getLayoutedElements(\n projected.nodes,\n projected.edges,\n directionRef.current,\n GRAPH_STYLES[style].layout ?? layoutConfigRef.current,\n currentGraphspec,\n projected.analysis,\n );\n if (cancelled) return;\n layoutCacheRef.current = {\n nodes: layouted.nodes,\n edges: layouted.edges,\n controllerPositions: layouted.controllerPositions,\n graphspec: currentGraphspec,\n graphStyle: style,\n };\n const withControllers = frameLayout(style, layouted, currentGraphspec, projected.analysis);\n setNodes(decorateNodes(withControllers.nodes));\n setEdges(toAppEdges(withControllers.edges));\n setTimeout(() => {\n if (!cancelled && reactFlowRef.current) {\n void 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 const cache = layoutCacheRef.current;\n const data = initialDataRef.current;\n // Mid-swap guard — see the layoutCacheRef.graphspec doc comment.\n if (!cache || !data || !cacheMatchesData()) return;\n const withControllers = frameLayout(cache.graphStyle, cache, data._graphspec, data._analysis);\n setNodes(decorateNodes(withControllers.nodes));\n setEdges(toAppEdges(withControllers.edges));\n }, [statusMap, decorateNodes]);\n\n // Re-stamp validation decorations when the issues change (reuses cached\n // layout — a verdict flip must never re-run ELK or reset the viewport).\n React.useEffect(() => {\n const cache = layoutCacheRef.current;\n const data = initialDataRef.current;\n // Mid-swap guard: when graphspec and validationIssues change in the same\n // commit (a host delivering a new file plus its known issues at once), the\n // cache still holds the OLD graphspec's nodes until the async layout lands\n // — rebuilding from it against the new spec would render garbage. The\n // in-flight graphspec build stamps the fresh issues itself via\n // decorateNodes, so skipping here loses nothing.\n if (!cache || !data || !cacheMatchesData()) return;\n const withControllers = frameLayout(cache.graphStyle, cache, data._graphspec, data._analysis);\n setNodes(decorateNodes(withControllers.nodes));\n // validationWidgetAvailable: badge clickability must follow widget\n // visibility (validationState / hideToolbar flips re-stamp the handler).\n }, [validationIssues, validationWidgetAvailable, decorateNodes]);\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 // A binding card names the path it binds, not a pipe, so there is no pipe to navigate to.\n if ((nodeData.isController || nodeData.isPipe) && nodeData.pipeType !== BINDING_STEP_TYPE) {\n const code = nodeData.pipeCode || nodeData.labelText;\n if (code && onNavigateToPipe) {\n onNavigateToPipe(code, nodeRunStatus(nodeData));\n }\n } else if (nodeData.isStuff && onStuffNodeClick && graphspec) {\n const found = findStuffByDigest(graphspec, stuffDigestFromId(node.id));\n if (found) onStuffNodeClick(found.item);\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 found = findStuffByDigest(graphspec, stuffDigestFromId(node.id));\n setDetailSelection({\n kind: \"stuff\",\n nodeId: node.id,\n nodeData,\n stuffData: found?.item,\n producerPipeRef: found?.producerPipeRef,\n consumer: found?.consumer,\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 card's GraphSpecNode for the detail panel — by node id,\n // since a pipe code does not name one node: two invocations of a pipe share\n // it, and so do two bindings of one path. A pipe card, a controller group and\n // a folded controller's card all carry their spec node's id.\n const selectedSpecNode =\n detailSelection?.kind === \"pipe\" && graphspec\n ? graphspec.nodes.find((n) => n.id === detailSelection.nodeId)\n : undefined;\n\n const detailOpen = detailSelection !== null || conceptOverride !== null;\n\n // Controlled + reactive: resolved on every render (no local state) so a new\n // `toolbarPosition` prop or `config.toolbarPosition` propagates immediately.\n const effectiveToolbarPosition = resolveToolbarPosition(\n toolbarPositionProp,\n config.toolbarPosition,\n );\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 // Fold-all and expand-all, where the style supports them; a style whose folds\n // are undone from controller frames offers them only while those are shown.\n const foldControlsAvailable =\n styleCapabilities.foldAll && (!styleCapabilities.controllerFrameToggle || showControllers);\n const foldAllProps = React.useMemo(() => {\n if (!foldControlsAvailable || !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: () => {\n markReaderFolds(allControllerIds, true);\n setFoldedControllers(new Set(allControllerIds));\n },\n onExpandAll: () => {\n markReaderFolds(allControllerIds, false);\n setFoldedControllers(new Set());\n },\n foldAllDisabled: foldedControllers.size === allControllerIds.size,\n expandAllDisabled: foldedControllers.size === 0,\n };\n }, [foldControlsAvailable, allControllerIds, foldedControllers, markReaderFolds]);\n\n const styleMenuOptions = React.useMemo(() => resolveStyleMenu(styleMenu), [styleMenu]);\n\n return (\n <div\n ref={containerRef}\n className={`react-flow-container react-flow-container--theme-${resolvedTheme} react-flow-container--mode-${mode}`}\n >\n <ReactFlow\n nodes={nodes}\n edges={edges}\n nodeTypes={nodeTypes}\n edgeTypes={edgeTypes}\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 {!hideToolbar && (\n <GraphToolbar\n direction={direction}\n onDirectionChange={setDirection}\n showControllers={showControllers}\n onShowControllersChange={\n styleCapabilities.controllerFrameToggle ? setShowControllers : undefined\n }\n graphStyle={graphStyle}\n styleMenuOptions={styleMenuOptions}\n onGraphStyleChange={setGraphStyle}\n onZoomIn={() => {\n void reactFlowRef.current?.zoomIn();\n }}\n onZoomOut={() => {\n void reactFlowRef.current?.zoomOut();\n }}\n onFitView={() => {\n void reactFlowRef.current?.fitView({ padding: 0.1 });\n }}\n onFoldAll={foldAllProps.onFoldAll}\n onExpandAll={foldAllProps.onExpandAll}\n foldAllDisabled={foldAllProps.foldAllDisabled}\n expandAllDisabled={foldAllProps.expandAllDisabled}\n themeMode={showThemeToggle ? mode : undefined}\n onThemeModeChange={showThemeToggle ? setMode : undefined}\n rightOffset={detailOpen ? panelWidth : 0}\n position={effectiveToolbarPosition}\n validationState={validationState}\n validationIssues={validationIssues}\n // Always the wrapped handler: it optionally calls the host's\n // source-jump and, independently, pans/flashes to the issue's target\n // node — a built-in that works without a host handler, so rows stay\n // interactive whether or not the host wired `onValidationIssueClick`.\n onValidationIssueClick={handleValidationIssueClick}\n validationOpen={validationOpen}\n onValidationOpenChange={setValidationOpen}\n />\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 nodeId={detailSelection.nodeId}\n stuffData={detailSelection.stuffData}\n producerPipeRef={detailSelection.producerPipeRef}\n consumer={detailSelection.consumer}\n graphspec={graphspec}\n theme={resolvedTheme}\n artifacts={graph}\n resolveUrl={resolveUrl}\n resolveShareUrl={resolveShareUrl}\n saveFiles={saveFiles}\n downloads={downloads}\n />\n ) : null}\n {renderDetailExtra &&\n detailSelection &&\n !conceptOverride &&\n renderDetailExtra(detailSelection.nodeId, detailSelection.nodeData)}\n </DetailPanel>\n </div>\n );\n}\n","/**\n * Resolve the host environment's color scheme to a binary `GraphTheme`.\n *\n * In a browser this follows `prefers-color-scheme` live. Non-browser hosts (a\n * VS Code webview, where `prefers-color-scheme` is historically flaky) stay\n * authoritative by injecting `systemTheme` — the hook then returns it verbatim\n * and re-renders are driven by the host updating that value.\n *\n * Keeping the `matchMedia` logic in a hook (not inline in GraphViewer) mirrors\n * how the standalone isolated it for testing, and lets the pure\n * `detectSystemTheme` seam be unit-tested without rendering.\n */\nimport React from \"react\";\nimport { GRAPH_THEME, type GraphTheme } from \"@graph/types\";\n\nconst PREFERS_DARK_QUERY = \"(prefers-color-scheme: dark)\";\n\n/** Map a `prefers-color-scheme: dark` match result to a resolved theme. */\nexport function prefersDarkToTheme(prefersDark: boolean): GraphTheme {\n return prefersDark ? GRAPH_THEME.DARK : GRAPH_THEME.LIGHT;\n}\n\n/**\n * Read the environment's current color scheme once. SSR / no-`matchMedia` safe:\n * defaults to `dark` when `window.matchMedia` is unavailable. Exported so\n * non-React callers (e.g. the standalone adapter's initial body-palette paint,\n * before any `onThemeChange` fires) can resolve `system` the same way the hook does.\n */\nexport function detectSystemTheme(): GraphTheme {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") {\n return GRAPH_THEME.DARK;\n }\n return prefersDarkToTheme(window.matchMedia(PREFERS_DARK_QUERY).matches);\n}\n\n/**\n * Subscribe to `prefers-color-scheme` changes, invoking `onChange` on each flip.\n * Returns an unsubscribe. SSR / no-`matchMedia` safe: returns a no-op.\n *\n * Older WebKit, some Electron builds, and certain VS Code webview hosts expose\n * a `MediaQueryList` with only the legacy `addListener`/`removeListener` API.\n * Calling `addEventListener` unconditionally throws there — and because this\n * runs inside the `useSyncExternalStore` subscribe during render, the throw\n * crashes the whole GraphViewer (blank graph) on exactly the webview host\n * class the `systemTheme` prop exists to support. Prefer the modern API, fall\n * back to the legacy one (mirrors the deleted standalone `pageTheme.ts`).\n *\n * Exported as a pure seam so the modern/legacy/SSR branches can be unit-tested\n * in a node env (no renderer) — see `__tests__/useSystemTheme.test.ts`.\n */\nexport function subscribeToSystemTheme(onChange: () => void): () => void {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") {\n return () => {};\n }\n const mql = window.matchMedia(PREFERS_DARK_QUERY);\n if (typeof mql.addEventListener === \"function\") {\n mql.addEventListener(\"change\", onChange);\n return () => mql.removeEventListener(\"change\", onChange);\n }\n mql.addListener(onChange);\n return () => mql.removeListener(onChange);\n}\n\n/** The `useSyncExternalStore` triple `useSystemTheme` drives. */\nexport interface SystemThemeStore {\n subscribe: (onChange: () => void) => () => void;\n getSnapshot: () => GraphTheme;\n getServerSnapshot: () => GraphTheme;\n}\n\n/**\n * Build the `useSyncExternalStore` triple for a given `injected` value.\n *\n * - `injected` set → host owns detection: `subscribe` is a no-op (no live\n * `matchMedia` listener is ever registered) and both snapshots return\n * `injected`. Spending an OS listener + per-render `detectSystemTheme` on a\n * result we'd discard is pure waste — and wrong to keep alive on the very\n * webview hosts where `prefers-color-scheme` is unreliable.\n * - otherwise → subscribe to `prefers-color-scheme` live; the server snapshot\n * falls back to `dark` (see `docs/theming.md` → \"SSR\").\n *\n * Pure + exported so the injected-skip path is unit-testable without a renderer.\n */\nexport function systemThemeStore(injected?: GraphTheme): SystemThemeStore {\n if (injected !== undefined) {\n return {\n subscribe: () => () => {},\n getSnapshot: () => injected,\n getServerSnapshot: () => injected,\n };\n }\n return {\n subscribe: subscribeToSystemTheme,\n getSnapshot: detectSystemTheme,\n getServerSnapshot: () => GRAPH_THEME.DARK,\n };\n}\n\n/**\n * Resolved environment theme.\n *\n * - `injected` set → return it (host owns detection; host re-renders drive\n * updates). No live `matchMedia` subscription is registered.\n * - otherwise → subscribe to `prefers-color-scheme` and re-render on `change`.\n *\n * Uses `useSyncExternalStore` so the subscription is concurrent-safe. The hook\n * is always called (rules-of-hooks); only the `systemThemeStore` triple branches\n * on `injected`, memoized so the `subscribe` reference stays stable across\n * renders (no re-subscribe churn). SSR with no injected value falls back to\n * `dark` via the server snapshot — see `docs/theming.md` → \"SSR\" for the\n * consequence and the recommended `theme` / `systemTheme` pinning.\n */\nexport function useSystemTheme(injected?: GraphTheme): GraphTheme {\n const store = React.useMemo(() => systemThemeStore(injected), [injected]);\n return React.useSyncExternalStore(store.subscribe, store.getSnapshot, store.getServerSnapshot);\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport {\n buildResultField,\n getPipeInputForm,\n getPipeIOContract,\n getPipeOutputForm,\n type InputForm,\n type OutputForm,\n type PipeIOContracts,\n type RunField,\n type SaveFiles,\n} from \"@pipelex/mthds-form\";\nimport {\n JsonView,\n ResultEnvProvider,\n StuffViewer,\n useFieldStrings,\n type DownloadDisplay,\n type ResolveShareUrl,\n type ResolveUrl,\n} from \"@pipelex/mthds-form/react\";\nimport { parsePipeRef } from \"@graph/pipeRefs\";\nimport type { ConceptInfo, GraphSpecNodeIoItem, GraphTheme } from \"@graph/types\";\n\n/**\n * The graph's stuff panel — the replacement for `StuffViewer`.\n *\n * ## What changed, and why it is not a reskin\n *\n * `StuffViewer` had three tabs — HTML, JSON, Pretty — and that was an admission:\n * a `GraphSpec` states a concept and a payload, and nothing about what the\n * payload IS, so the only honest thing it could do was hand the reader three\n * renderings and let them pick. It sniffed for URLs, guessed MIME types from\n * file extensions, and ran any `data_html` through DOMPurify because the markup\n * was model output going into the host's own document.\n *\n * None of that guessing is necessary, because the standard answers the question\n * in an artifact built for it. `output_form` gives a pipe's result ONE\n * descriptor node — kind, concept identity, refinement chain, nested fields in\n * authored order — and the output half of `pipe_io_contracts` gives the\n * payload's JSON Schema beside it, naming the property the content model wraps\n * the value under. `buildResultField` pairs them into a `RunField`, and\n * `StuffViewer` lays that out without ever inspecting the value: a table for a\n * list of records, a gallery for images, a sandboxed frame for markup, a\n * two-column grid for a structure. The JSON view survives as one of the panel's\n * two, because a receipt is worth having; \"Pretty\" and \"HTML\" do not, because\n * they were two guesses at a question now answered.\n *\n * ## What it needs from the host, and why\n *\n * The artifacts a run's results (or a `/validate` call) return beside the graph\n * spec, keyed by `pipe_ref`. The join is the producing pipe: the graph hands\n * over `producerPipeRef` (see `stuffLookup.ts`), and `output_form` plus the\n * output half of the contract are looked up by it. That join only holds when\n * the artifacts and the graph come from the same source, which is why\n * `GraphViewer` takes them as one `graph` object (`GraphArtifacts`).\n *\n * ## The method's own inputs, which no pipe produced\n *\n * They have no `producerPipeRef`, so no output descriptor describes them — and\n * showing nothing for the top of every graph is not acceptable, because a\n * method's arguments are as much a part of what happened as its results. What\n * DOES describe them is the CONSUMING pipe's `input_form` entry for the slot\n * they arrive in: the same field, seen from the other side. So `inputForm` is\n * an optional third artifact, and when it is supplied the panel falls back to\n * it.\n *\n * **Only on the `single` arm, and that is a correctness boundary rather than a\n * conservative default.** An input's `json_schema` describes what a CALLER\n * SENDS, so a plural slot's is a bare array; a stuff's payload is what the\n * runtime HOLDS, which for a plural value is a `ListContent {items}` envelope.\n * The two disagree exactly where the standard says they do, and rendering a\n * plural input against its caller-side schema would unwrap by a property that\n * is not there. On the single arm the two are byte-identical by construction —\n * both are `render_stuff_spec`'s output — so the fallback is exact there and\n * declines everywhere else.\n *\n * ## Stored files\n *\n * It does not resolve `pipelex-storage://` URIs itself. A host that can passes\n * `resolveUrl`, which is installed as the kernel's `ResultEnvProvider` so the\n * kernel's own file arms paint the file; without one, the panel paints whatever\n * `public_url` the payload carries.\n *\n * ## Saving\n *\n * The kernel's Download control and its per-file download buttons save through\n * the browser tab unless a host says otherwise. A host whose view runs in a\n * sandboxed frame, where the tab's object URL, clicked link and popup are all\n * refused, passes `saveFiles` to deliver the files through its own bridge, and\n * `downloads` to choose which of those controls are drawn. Both go on the same\n * provider as `resolveUrl`, because the kernel's provider replaces an outer\n * one rather than merging with it: set around the graph instead, they would\n * never reach a panel that installs its own.\n */\nexport interface StuffResultRendererOptions {\n /**\n * `pipe_io_contracts` from the same source as the `producerPipeRef` and\n * `consumer` below: the run, or the validate report, whose graph they were\n * read from. Inside `GraphViewer` that pairing is guaranteed by its single\n * `graph` prop; a host using this panel on its own owns it.\n */\n pipeIoContracts: PipeIOContracts;\n /** `output_form` from that SAME source. */\n outputForm: OutputForm;\n /**\n * `input_form`, optional. Supplying it is what lets a method's own INPUTS\n * render as described fields rather than as nothing: they have no producing\n * pipe, so the consuming pipe's descriptor for their slot is what names them.\n */\n inputForm?: InputForm;\n}\n\nexport interface StuffResultPanelProps extends StuffResultRendererOptions {\n /** The data item as the spec holds it. */\n stuff: GraphSpecNodeIoItem;\n /** Its concept, resolved against the spec's concept table, when it has one. */\n concept?: ConceptInfo;\n /**\n * `domain.code` of the pipe that PRODUCED it — the key both output artifacts\n * are keyed by. Absent for a method's own inputs, which no pipe produced.\n */\n producerPipeRef?: string;\n /**\n * The first pipe that CONSUMES it, and the slot it arrives in — the fallback\n * identity for those method inputs.\n */\n consumer?: { pipeRef: string; slotName: string };\n /** The viewer's resolved theme, so the panel matches the chrome it sits in. */\n theme?: GraphTheme;\n /**\n * Turns the runtime's own `pipelex-storage://…` reference into something a\n * browser can fetch.\n *\n * Supply it and the panel paints files through it; omit it and the panel\n * falls back to whatever `public_url` the payload carries. On the hosted\n * platform that fallback is a PRESIGNED S3 URL with an hour's life, baked\n * into the stored result — so a run opened the next morning shows broken\n * images, and the URL answers `403` in a way that reads as a permissions\n * problem rather than an expiry. A resolver is what makes a result durable.\n */\n resolveUrl?: ResolveUrl;\n /**\n * Mints a URL that works OUTSIDE this page — what the copy control hands over.\n * A display URL may sit behind the host's session; a shared one carries its\n * own credential.\n */\n resolveShareUrl?: ResolveShareUrl;\n /**\n * Delivers the files a download hands over, for a host that cannot save\n * through the browser tab. Without one, the kernel saves in the tab.\n */\n saveFiles?: SaveFiles;\n /**\n * Which download controls are drawn: the whole-result Download and each\n * file's own button, set independently. Both are drawn by default.\n */\n downloads?: DownloadDisplay;\n}\n\nexport function StuffResultPanel({\n pipeIoContracts,\n outputForm,\n inputForm,\n stuff,\n producerPipeRef,\n consumer,\n resolveUrl,\n resolveShareUrl,\n saveFiles,\n downloads,\n}: StuffResultPanelProps) {\n const field = React.useMemo(\n () =>\n fromProducer(pipeIoContracts, outputForm, producerPipeRef) ??\n fromConsumer(pipeIoContracts, inputForm, consumer),\n [pipeIoContracts, outputForm, inputForm, producerPipeRef, consumer],\n );\n\n if (field) {\n // The STUFF's name, not the descriptor's. `build_output_form` names every\n // pipe's root node `output` - correct in the artifact, where the descriptor\n // describes an output SLOT with no name of its own, and wrong on screen,\n // where the reader has just clicked a node called `report_pages` and every\n // other surface calls it that. The graph is the one that knows, so the\n // graph is the one that says.\n const panel = <StuffViewer field={field} value={stuff.data} name={stuff.name} />;\n // Installed only when the host said something, so a host that wraps the\n // whole graph in its own provider still reaches a panel given nothing.\n return resolveUrl || resolveShareUrl || saveFiles || downloads ? (\n <ResultEnvProvider\n resolveUrl={resolveUrl}\n resolveShareUrl={resolveShareUrl}\n saveFiles={saveFiles}\n downloads={downloads}\n >\n {panel}\n </ResultEnvProvider>\n ) : (\n panel\n );\n }\n\n // No descriptor, but there IS a value. Show it, and say why it is not laid\n // out.\n //\n // Returning null here was the first behaviour and it was wrong in the way\n // that matters: a reader looking at a finished run saw a schema table, no\n // data tab, and no reason — indistinguishable from a broken view. The two\n // artifacts are opt-in `views` on `/validate` and an engine that predates\n // them simply omits them, so \"the server has not got them yet\" is an ordinary\n // state a host will be in, not an edge case.\n //\n // This is not `StuffViewer` coming back. That offered three renderings as a\n // CHOICE because it could not tell what the value was; this is one labelled\n // fallback that names its own cause and disappears the moment the descriptor\n // arrives.\n return stuff.data === undefined || stuff.data === null ? null : (\n <UndescribedValue value={stuff.data} />\n );\n}\n\nfunction UndescribedValue({ value }: { value: unknown }) {\n const s = useFieldStrings();\n return (\n <div className=\"space-y-2\">\n <p className=\"text-[12px] text-muted-foreground\">{s.resultUndescribed}</p>\n <JsonView value={value} />\n </div>\n );\n}\n\n/** The normal case: the pipe that resolved to this value describes it. */\nfunction fromProducer(\n contracts: PipeIOContracts,\n outputForm: OutputForm,\n producerPipeRef: string | undefined,\n): RunField | null {\n if (!producerPipeRef) return null;\n const parsed = parsePipeRef(producerPipeRef);\n if (!parsed?.domainPath) return null;\n const descriptor = getPipeOutputForm(outputForm, parsed.domainPath, parsed.pipeCode);\n const contract = getPipeIOContract(contracts, parsed.domainPath, parsed.pipeCode);\n // Both or neither, the same rule the input side follows: the descriptor says\n // what the result IS and the schema says what shape it arrives in, and a\n // renderer given one of the two would be guessing the other.\n if (!descriptor || !contract) return null;\n return buildResultField(descriptor, contract.output.json_schema);\n}\n\n/**\n * The fallback for a method's own input: the pipe that READS it describes it.\n *\n * Single-valued slots only. See the component's note — a plural input's schema\n * is the caller-side bare array, and the payload is a `ListContent` envelope, so\n * the fallback would unwrap by a property that is not there.\n */\nfunction fromConsumer(\n contracts: PipeIOContracts,\n inputForm: InputForm | undefined,\n consumer: { pipeRef: string; slotName: string } | undefined,\n): RunField | null {\n if (!inputForm || !consumer) return null;\n const parsed = parsePipeRef(consumer.pipeRef);\n if (!parsed?.domainPath) return null;\n const descriptor = getPipeInputForm(inputForm, parsed.domainPath, parsed.pipeCode);\n const contract = getPipeIOContract(contracts, parsed.domainPath, parsed.pipeCode);\n if (!descriptor || !contract) return null;\n const slot = contract.inputs[consumer.slotName];\n if (!slot || slot.multiplicity !== \"single\") return null;\n const node = descriptor.fields.find(\n (candidate: { name: string }) => candidate.name === consumer.slotName,\n );\n if (!node) return null;\n // Wrapped into the OUTPUT descriptor's shape, which is what `buildResultField`\n // takes. That is not a cheat: the two descriptors' nodes are the same\n // recursive vocabulary, and the wrapper's only job is to say \"one field, and\n // here it is\". The pipe-slot facts the input node also carries (`presence`,\n // `gating`) describe how a caller must fill it and mean nothing to a value\n // that has already arrived, so they are simply not read.\n return buildResultField({ field: node }, slot.json_schema);\n}\n","import type { InputForm, OutputForm, PipeIOContracts } from \"@pipelex/mthds-form\";\nimport type { GraphSpec } from \"@graph/types\";\n\n/**\n * A graph and the artifacts that describe its pipes, taken from ONE source.\n *\n * `GraphViewer` takes this as its single `graph` prop rather than a spec and\n * three descriptor props side by side, because the descriptors are keyed by the\n * graph's own `pipe_ref`s: the detail panel walks from a data node back to the\n * pipe that produced it and looks that pipe up in `outputForm` and\n * `pipeIoContracts`. A spec paired with another source's descriptors (a past\n * run's graph beside the current method's validate report, after the method's\n * pipes were renamed) misses every lookup, and the panel can only say that no\n * descriptor describes the value. Carrying all four in one object is what keeps\n * them from one run, or from one validate call.\n *\n * Where each source lives:\n *\n * - **A run**: its results carry `graph_spec`, `pipe_io_contracts`,\n * `output_form` and `input_form` together; `graphArtifactsFrom(results)`\n * reads them in one call.\n * - **A method that has not run** (a dry run, or a static graph built from its\n * sources): the descriptors come from the same method's validate report, the\n * one the dry graph or the static build describes.\n *\n * The descriptors are optional, and nullable as the wire carries them. Without\n * `pipeIoContracts` and `outputForm` together, the panel shows a data node's\n * structure table and no data tab, which is the honest floor for a graph whose\n * artifacts were not produced. `inputForm` is optional even beside the other\n * two: it is what lets a method's own inputs, which no pipe produced, show their\n * value through the consuming pipe's slot.\n */\nexport interface GraphArtifacts {\n /** The graph to draw: a run's `graph_spec`, a dry run's, or a static build. */\n graphSpec: GraphSpec;\n /** `pipe_io_contracts` for the pipes of THIS graph. */\n pipeIoContracts?: PipeIOContracts | null;\n /** `output_form` for the pipes of THIS graph, from the same source. */\n outputForm?: OutputForm | null;\n /** `input_form` for the pipes of THIS graph, from the same source. */\n inputForm?: InputForm | null;\n}\n\n/**\n * The four artifacts as a run's results, or a validate report, spell them on\n * the wire. `graph_spec` is `unknown` because transport layers type it that way;\n * `GraphViewer` validates it at its boundary.\n */\nexport interface GraphArtifactsSource {\n graph_spec?: unknown;\n pipe_io_contracts?: PipeIOContracts | null;\n output_form?: OutputForm | null;\n input_form?: InputForm | null;\n}\n\n/**\n * Read the graph and its descriptors out of one run's results (or one report\n * that carries all four), so a host never assembles the bundle by hand from two\n * places. Returns `null` when the source carries no graph.\n */\nexport function graphArtifactsFrom(source: GraphArtifactsSource): GraphArtifacts | null {\n if (source.graph_spec === undefined || source.graph_spec === null) return null;\n return {\n graphSpec: source.graph_spec as GraphSpec,\n pipeIoContracts: source.pipe_io_contracts ?? null,\n outputForm: source.output_form ?? null,\n inputForm: source.input_form ?? null,\n };\n}\n\n/** The descriptors the detail panel renders a value from, once they are usable. */\nexport interface ResultDescriptors {\n pipeIoContracts: PipeIOContracts;\n outputForm: OutputForm;\n inputForm?: InputForm;\n}\n\n/**\n * The descriptors a graph's detail panel can render from, or `null`.\n *\n * Both `pipeIoContracts` and `outputForm`, or neither: the contract names the\n * payload's shape and the descriptor says what the result IS, so a panel given\n * one of the two would be guessing the other. `inputForm` rides along when the\n * other two are there.\n */\nexport function resultDescriptors(graph: GraphArtifacts | null): ResultDescriptors | null {\n const pipeIoContracts = graph?.pipeIoContracts;\n const outputForm = graph?.outputForm;\n if (!pipeIoContracts || !outputForm) return null;\n const inputForm = graph?.inputForm;\n return inputForm ? { pipeIoContracts, outputForm, inputForm } : { pipeIoContracts, outputForm };\n}\n","import React from \"react\";\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 <div className=\"detail-panel-content\">\n {/* Inside the scroll flow ON PURPOSE: the close button belongs to the\n top of the content and scrolls away with it — closing the panel\n means going back up. Do not pin it to the panel. */}\n <div className=\"detail-panel-close-row\">\n <button className=\"detail-panel-close\" onClick={onClose} aria-label=\"Close panel\">\n x\n </button>\n </div>\n {children}\n </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 {\n GraphSpecModelUsage,\n GraphSpecNode,\n NodePipeType,\n PipeBlueprintUnion,\n GraphSpec,\n} from \"@graph/types\";\nimport { isBindingNode, isDryGraphSpec, isStaticGraphSpec, multiplicitySuffix } from \"@graph/types\";\nimport { resolveNodeBlueprint } from \"@graph/graphAnalysis\";\nimport {\n formatDuration,\n KV,\n BindingStepSection,\n PipeLLMSection,\n PipeImgGenSection,\n PipeExtractSection,\n PipeSearchSection,\n PipeStructureSection,\n PipeComposeSection,\n PipeDocGenSection,\n PipeConditionSection,\n PipeSequenceSection,\n PipeParallelSection,\n PipeBatchSection,\n UsageCostInline,\n UsageDetails,\n dumpableExecutionData,\n shouldDumpExecutionData,\n} from \"./sections\";\n\n// ─── Badge / Status config ─────────────────────────────────────────────\n\nconst PIPE_TYPE_BADGES: Record<NodePipeType, string> = {\n PipeLLM: \"LLM\",\n PipeExtract: \"Extract\",\n PipeCompose: \"Compose\",\n PipeImgGen: \"ImgGen\",\n PipeSearch: \"Search\",\n PipeFunc: \"Func\",\n PipeStructure: \"Structure\",\n PipeJudge: \"Judge\",\n PipeDocGen: \"DocGen\",\n PipeSignature: \"Signature\",\n PipeSequence: \"Seq\",\n PipeParallel: \"Par\",\n PipeCondition: \"Cond\",\n PipeBatch: \"Batch\",\n BindingStep: \"Binding\",\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 canceled: \"#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;\n const isController = CONTROLLER_TYPES.has(pipeType);\n // A binding step runs no pipe, so the registry holds no blueprint for it: its\n // own section says what it binds, and no \"Blueprint not available\" is shown.\n const isBinding = isBindingNode(node);\n const isStatic = isStaticGraphSpec(spec);\n const showsGeneratedData = !isStatic && !isDryGraphSpec(spec);\n const badge = PIPE_TYPE_BADGES[pipeType];\n const status = node.status;\n const statusColor = STATUS_COLORS[status] ?? \"#6272a4\";\n\n // The same lookup the card makes, so the two never disagree about which pipe\n // a node runs; a binding node has none.\n const blueprint = React.useMemo(() => resolveNodeBlueprint(spec, node), [spec, node]);\n\n const [usageExpanded, setUsageExpanded] = React.useState(false);\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}\n </span>\n </div>\n\n {/* Status + Duration + Cost — three facts about the same run, on one\n line. Cost is gated on showsGeneratedData, i.e. a real run: a dry run\n executes nothing, so its usage counts are simulated and stating a\n price (even \"none\") would answer a question that does not apply. */}\n {!isStatic && (\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 {showsGeneratedData && node.usage && (\n <UsageCostInline\n usage={node.usage}\n isController={isController}\n expanded={usageExpanded}\n onToggle={() => setUsageExpanded((value) => !value)}\n />\n )}\n </div>\n )}\n\n {showsGeneratedData && node.usage && usageExpanded && (\n <UsageDetails usage={node.usage} isController={isController} />\n )}\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}</span>\n {input.concept && (\n <span className=\"detail-io-concept\">\n {input.concept + multiplicitySuffix(input.multiplicity)}\n </span>\n )}\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}</span>\n {output.concept && (\n <span className=\"detail-io-concept\">\n {output.concept + multiplicitySuffix(output.multiplicity)}\n </span>\n )}\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 {/* What a binding step binds — structural, so shown in every mode */}\n {isBinding && <BindingStepSection node={node} />}\n\n {/* Blueprint-specific sections */}\n {blueprint && (\n <BlueprintSection\n blueprint={blueprint}\n executionData={showsGeneratedData ? node.execution_data : undefined}\n modelsRan={showsGeneratedData ? node.usage?.by_model : undefined}\n // Model resolution is NOT gated on showsGeneratedData, unlike every other\n // execution_data field. Resolving `@default-general` to `claude-4.6-sonnet`\n // is a deterministic deck lookup, not a measurement of a run — a dry spec\n // carries it too, and hiding it there left the Model row showing an alias\n // with nothing under it.\n modelHandles={node.execution_data}\n />\n )}\n\n {/* Execution data (runtime-resolved values) — a binding's is its section above */}\n {showsGeneratedData &&\n !isBinding &&\n node.execution_data &&\n Object.keys(node.execution_data).length > 0 && (\n <ExecutionDataSection\n executionData={node.execution_data}\n pipeType={pipeType}\n hasBlueprint={!!blueprint}\n />\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 {showsGeneratedData && 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 && !isBinding && (\n <div className=\"detail-not-available\">Blueprint not available</div>\n )}\n </>\n );\n}\n\n// ─── Blueprint dispatch ─────────────────────────────────────────────────────\n\nfunction BlueprintSection({\n blueprint,\n executionData,\n modelsRan,\n modelHandles,\n}: {\n blueprint: PipeBlueprintUnion;\n executionData?: Record<string, unknown>;\n /** Models that actually ran on this node — see ModelRows in ./sections/shared. */\n modelsRan?: GraphSpecModelUsage[];\n /** execution_data, ungated: the deck-resolved model handle is available in dry specs too. */\n modelHandles?: Record<string, unknown>;\n}) {\n switch (blueprint.type) {\n case \"PipeLLM\":\n return (\n <PipeLLMSection\n blueprint={blueprint}\n executionData={executionData}\n modelsRan={modelsRan}\n modelHandles={modelHandles}\n />\n );\n case \"PipeImgGen\":\n return (\n <PipeImgGenSection\n blueprint={blueprint}\n executionData={executionData}\n modelsRan={modelsRan}\n modelHandles={modelHandles}\n />\n );\n case \"PipeCompose\":\n return <PipeComposeSection blueprint={blueprint} executionData={executionData} />;\n case \"PipeDocGen\":\n return (\n <PipeDocGenSection\n blueprint={blueprint}\n executionData={executionData}\n modelsRan={modelsRan}\n modelHandles={modelHandles}\n />\n );\n case \"PipeExtract\":\n return (\n <PipeExtractSection\n blueprint={blueprint}\n modelsRan={modelsRan}\n modelHandles={modelHandles}\n />\n );\n case \"PipeSearch\":\n return (\n <PipeSearchSection\n blueprint={blueprint}\n executionData={executionData}\n modelsRan={modelsRan}\n modelHandles={modelHandles}\n />\n );\n case \"PipeStructure\":\n return (\n <PipeStructureSection\n blueprint={blueprint}\n executionData={executionData}\n modelsRan={modelsRan}\n modelHandles={modelHandles}\n />\n );\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 case \"PipeJudge\":\n // No section yet: L-261004-baa62a adds one, with the verdict it answers.\n return null;\n case \"PipeSignature\":\n return (\n <div className=\"detail-not-available\">\n Signature stub — declared but not yet implemented.\n </div>\n );\n default: {\n // Exhaustive at compile time, so a pipe type added to the union without a\n // section fails here; still defensive at run time, where a blueprint whose\n // `type` this library does not know yet (runtime ahead of it) degrades to\n // no extra section.\n const _unhandled: never = blueprint;\n void _unhandled;\n return null;\n }\n }\n}\n\n// ─── Execution data dispatch ────────────────────────────────────────────────\n\nfunction ExecutionDataSection({\n executionData,\n pipeType,\n hasBlueprint,\n}: {\n executionData: Record<string, unknown>;\n pipeType: NodePipeType;\n hasBlueprint: boolean;\n}) {\n // Known pipe types merge their runtime data into the blueprint section, so\n // there is nothing extra to render once that section mounted. The raw dump is\n // only shown when the blueprint failed to resolve (so runtime data isn't lost)\n // or for types without a merged section (PipeFunc, PipeSignature, unknown).\n if (!shouldDumpExecutionData(pipeType, hasBlueprint)) return null;\n return <GenericExecutionData entries={dumpableExecutionData(pipeType, executionData)} />;\n}\n\nfunction GenericExecutionData({ entries }: { entries: [string, unknown][] }) {\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\";\nimport type { GraphSpecModelUsage as ModelUsage } from \"@graph/types\";\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\n/**\n * The Model row: the resolution chain, top to bottom.\n *\n * A model reaches an LLM call through up to three rungs, and which ones are\n * distinct depends on the run:\n *\n * authored what the .mthds says `@default-general`, or a preset `$writing-factual`\n * handle execution_data.resolved_model — the LLMSetting's model at capture time.\n * Confusingly named: in a LIVE run the alias has already been resolved by\n * the time it is captured, so this reads `claude-4.6-sonnet`; in a DRY run\n * nothing resolves it and it stays `@default-general`.\n * ran usage.by_model — the model that actually served the call (LIVE only).\n *\n * Rendering only the last known rung hides the alias on a live run; rendering only the\n * first hides the model. So all of them are shown, request on top. When they collapse to\n * one value there is one line and nothing to explain.\n *\n * A node that used several models (a PipeLLM's text pass and object pass resolve\n * separately) lists each with its call count. pipelex counts a model per model type and\n * name, since a handle names one model per type, so one name can run twice on a node:\n * as an LLM and as a judgment model. Those entries carry their model type, or the two\n * would print alike and read as one.\n */\nexport function ModelRows({\n modelsRan,\n authored,\n handle,\n label = \"Model\",\n}: {\n modelsRan?: ModelUsage[];\n /** What the method declares — the truest statement of intent. */\n authored?: string | null;\n /** execution_data.resolved_model: an alias in a dry run, usually concrete in a live one. */\n handle?: string | null;\n label?: string;\n}) {\n const ran = modelsRan ?? [];\n const nameCounts = new Map<string, number>();\n for (const entry of ran) {\n nameCounts.set(\n entry.inference_model_name,\n (nameCounts.get(entry.inference_model_name) ?? 0) + 1,\n );\n }\n const ranRungs: ModelRung[] = ran.map((entry, index) => {\n const name =\n (nameCounts.get(entry.inference_model_name) ?? 0) > 1\n ? `${entry.inference_model_name} · ${modelTypeLabel(entry.model_type)}`\n : entry.inference_model_name;\n return {\n key: `ran-${index}`,\n text: ran.length > 1 ? `${name} (${entry.inference_calls})` : name,\n };\n });\n\n // The requested rungs collapse when they repeat: an authored name that was never\n // aliased resolves to itself, and a handle already concrete names what ran. The rungs\n // that ran never collapse, since each is a model pipelex counted on its own.\n const requested: ModelRung[] = [];\n const requestedRungs: ModelRung[] = [\n { key: \"authored\", text: authored ?? \"\" },\n { key: \"handle\", text: handle ?? \"\" },\n ];\n for (const rung of requestedRungs) {\n if (rung.text && rung.text !== requested[requested.length - 1]?.text) requested.push(rung);\n }\n if (ranRungs.length > 0 && requested[requested.length - 1]?.text === ranRungs[0].text) {\n requested.pop();\n }\n const chain = [...requested, ...ranRungs];\n if (chain.length === 0) return null;\n\n return (\n <div className=\"detail-kv-row\">\n <span className=\"detail-kv-key\">{label}</span>\n <span className=\"detail-kv-value detail-model-value\">\n {chain.map((rung, index) => (\n <span key={rung.key} className={index === 0 ? undefined : \"detail-model-resolved\"}>\n {rung.text}\n </span>\n ))}\n </span>\n </div>\n );\n}\n\ninterface ModelRung {\n key: string;\n text: string;\n}\n\n/**\n * The words for a usage record's `model_type`, an open set: a type with no entry here\n * prints as itself, its underscores read as spaces.\n */\nconst MODEL_TYPE_LABELS: Readonly<Record<string, string>> = {\n llm: \"LLM\",\n extract: \"extraction\",\n img_gen: \"image generation\",\n search: \"search\",\n judgment: \"judgment\",\n};\n\nfunction modelTypeLabel(modelType: string): string {\n return MODEL_TYPE_LABELS[modelType] ?? modelType.replaceAll(\"_\", \" \");\n}\n","/**\n * Presentation rules for per-node inference usage.\n *\n * Pure, React-free, and the single place the `GraphSpecNodeUsage` invariants are\n * turned into something a human reads. The invariants themselves live on the type\n * in `types.ts`; what this module adds is the rule that a *missing* dollar is\n * never printed as a zero one, and a *partial* dollar is never printed as a\n * complete one.\n *\n * Cost is a side-panel concern only — it is never rendered on a graph card.\n */\nimport type { GraphSpecModelUsage, GraphSpecNodeUsage } from \"./types\";\n\n/**\n * Which half of a usage object a node should be read through.\n *\n * A controller runs no inference itself — its own numbers are always zero — so\n * it must read the subtree half or it reports nothing at all. An operator is a\n * leaf and reads its own.\n */\nexport type UsageScope = \"own\" | \"subtree\";\n\n/** The scoped numbers, with the own/subtree distinction already resolved away. */\nexport interface ScopedUsage {\n scope: UsageScope;\n inferenceCalls: number;\n ratedInferenceCalls: number;\n /**\n * ⚠ NOT a token count for every pipe type — never render these unless\n * `hasRealTokenCounts` holds for this scope.\n *\n * Extract, search and image generation are billed per request, and pipelex\n * encodes that price by putting exactly `1_000_000` in each token category:\n * rates are per-million, so `1_000_000 x rate/1e6` reproduces the per-request\n * price exactly (see `linkup_extract_worker.py`, `extract_worker_abstract.py`).\n * A one-page extract therefore reports 2,000,000 \"tokens\".\n *\n * A controller's subtree total sums those sentinels with real tokens, so a\n * figure is a measurement only when every model under it is token-billed,\n * which is what `hasRealTokenCounts` tests. `cost` survives the encoding and\n * is shown either way.\n */\n nbTokensByCategory: Record<string, number>;\n /** ⚠ See `nbTokensByCategory` — rendered only where `hasRealTokenCounts` holds. */\n totalTokens: number;\n cost: number | null;\n costInput: number | null;\n costOutput: number | null;\n models: GraphSpecModelUsage[];\n}\n\nexport function scopeUsage(usage: GraphSpecNodeUsage, scope: UsageScope): ScopedUsage {\n if (scope === \"subtree\") {\n return {\n scope,\n inferenceCalls: usage.subtree_inference_calls,\n ratedInferenceCalls: usage.subtree_rated_inference_calls,\n nbTokensByCategory: usage.subtree_nb_tokens_by_category,\n totalTokens: usage.subtree_total_tokens,\n cost: usage.subtree_cost,\n costInput: usage.subtree_cost_input,\n costOutput: usage.subtree_cost_output,\n models: usage.subtree_by_model,\n };\n }\n return {\n scope,\n inferenceCalls: usage.inference_calls,\n ratedInferenceCalls: usage.rated_inference_calls,\n nbTokensByCategory: usage.nb_tokens_by_category,\n totalTokens: usage.total_tokens,\n cost: usage.cost,\n costInput: usage.cost_input,\n costOutput: usage.cost_output,\n models: usage.by_model,\n };\n}\n\n/**\n * The four states a scoped usage can be rendered in.\n *\n * `ran-nothing` and an absent usage object both render as nothing, but they are\n * distinct upstream — see invariant 1 — and the detail panel says so.\n */\nexport type UsageState = \"ran-nothing\" | \"unrated\" | \"partial\" | \"rated\";\n\nexport function usageState(scoped: ScopedUsage): UsageState {\n if (scoped.inferenceCalls === 0) return \"ran-nothing\";\n if (scoped.cost === null) return \"unrated\";\n if (scoped.ratedInferenceCalls < scoped.inferenceCalls) return \"partial\";\n return \"rated\";\n}\n\n/**\n * USD at the same 4-decimal precision the pipelex cost table uses.\n *\n * A rated call that cost nothing is a real `$0.0000` and prints as such; a cost\n * too small to show at 4 decimals prints as `<$0.0001` rather than rounding to\n * zero, because \"rounded to nothing\" and \"cost nothing\" are different claims.\n */\nexport function formatCost(cost: number): string {\n if (cost > 0 && cost < 0.0001) return \"<$0.0001\";\n return `$${cost.toFixed(4)}`;\n}\n\n/**\n * The model types whose usage records carry the tokens the provider billed: an LLM\n * call, and a judgment call, whose worker records the input and output tokens the\n * judgment API reports. A type missing from this set is read as billed per request,\n * which hides its tokens rather than printing a request counter as a measurement.\n */\nconst TOKEN_BILLED_MODEL_TYPES: ReadonlySet<string> = new Set([\"llm\", \"judgment\"]);\n\n/**\n * Whether this scope's token counts are real measurements.\n *\n * True only when every model that ran is token-billed. Anything else is billed per\n * request, and pipelex encodes that price as `1_000_000` tokens per category — so a\n * mixed branch (an LLM beside an extract) has a token total that silently blends a\n * measurement with a request counter, and must not be displayed either.\n */\nexport function hasRealTokenCounts(scoped: ScopedUsage): boolean {\n return (\n scoped.models.length > 0 &&\n scoped.models.every((entry) => TOKEN_BILLED_MODEL_TYPES.has(entry.model_type))\n );\n}\n","import React from \"react\";\nimport type { GraphSpecNodeUsage } from \"@graph/types\";\nimport {\n formatCost,\n hasRealTokenCounts,\n scopeUsage,\n usageState,\n type ScopedUsage,\n} from \"@graph/usageFormat\";\nimport { KV } from \"./shared\";\n\n/**\n * Inference cost, rendered inline beside the status and duration.\n *\n * Cost belongs with the other facts about the run itself — it succeeded, it took\n * 23.57s, it cost $0.0138 — so it shares that line and that formatting rather\n * than claiming a block of its own. Everything else about usage (call counts,\n * the node's own figures vs its branch's) is a diagnostic and lives behind the\n * chevron. Token counts are shown nowhere — see UsageColumn for why.\n *\n * The cost text is honest about the three states rather than printing a number\n * in all of them: a real price, a lower bound when only some calls were priced,\n * and nothing at all when there is no price to give.\n *\n * The state lives in the panel, not here, because the trigger sits inside the\n * status row while the body renders below it.\n */\n\n/** Which half of the usage a node reports: a controller has only its branch. */\nexport function usageHeadlineScope(usage: GraphSpecNodeUsage, isController: boolean): ScopedUsage {\n return scopeUsage(usage, isController ? \"subtree\" : \"own\");\n}\n\nfunction costText(scoped: ScopedUsage): string | null {\n const state = usageState(scoped);\n // No inference, or nothing priced: there is no cost to state, and a \"0\" or a\n // \"—\" would each imply something. Say nothing.\n if (state === \"ran-nothing\" || state === \"unrated\") return null;\n const cost = formatCost(scoped.cost ?? 0);\n return state === \"partial\" ? `≥ ${cost}` : cost;\n}\n\nfunction costTitle(scoped: ScopedUsage, isController: boolean): string {\n const scopeWord = isController ? \"This pipe and everything below it\" : \"This pipe\";\n const state = usageState(scoped);\n if (state === \"partial\") {\n return `${scopeWord}: only ${scoped.ratedInferenceCalls} of ${scoped.inferenceCalls} calls were priced, so this is a lower bound. Click for details.`;\n }\n return `${scopeWord}: ${scoped.inferenceCalls} inference call(s). Click for the breakdown.`;\n}\n\n/** Thin chevron, deliberately quieter than the text it sits beside. */\nfunction Chevron({ open }: { open: boolean }) {\n return (\n <svg\n className={`detail-usage-chevron ${open ? \"detail-usage-chevron--open\" : \"\"}`}\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n );\n}\n\n/**\n * The inline cost + disclosure trigger. Returns null when there is no price to\n * show, so nothing appears beside the duration on a run that cost nothing.\n */\nexport function UsageCostInline({\n usage,\n isController,\n expanded,\n onToggle,\n}: {\n usage: GraphSpecNodeUsage;\n isController: boolean;\n expanded: boolean;\n onToggle: () => void;\n}) {\n const scoped = usageHeadlineScope(usage, isController);\n const text = costText(scoped);\n if (text === null) return null;\n\n return (\n <button\n type=\"button\"\n className=\"detail-usage-inline\"\n aria-expanded={expanded}\n onClick={onToggle}\n title={costTitle(scoped, isController)}\n >\n <span className=\"detail-usage-value\">{text}</span>\n <Chevron open={expanded} />\n </button>\n );\n}\n\n/**\n * The categories that get a paired count/cost row of their own. Everything else in\n * `nb_tokens_by_category` (cached, audio, reasoning, prediction) is a detail listed\n * after — and only when non-zero, since a zero there says nothing a missing row\n * would not.\n */\nconst PAIRED_CATEGORIES = new Set([\"input\", \"output\"]);\n\nfunction extraCategories(nbTokensByCategory: Record<string, number>): [string, number][] {\n return Object.entries(nbTokensByCategory)\n .filter(([category, nbTokens]) => !PAIRED_CATEGORIES.has(category) && nbTokens > 0)\n .sort(([a], [b]) => a.localeCompare(b));\n}\n\n/**\n * One usage scope: calls, then each token count beside the cost it produced.\n *\n * The pairing is the point — input tokens next to what the input cost, output next\n * to what the output cost, totals last. Reading down the column answers \"where did\n * the money go\" without the reader holding two separate blocks in their head.\n *\n * Token rows are gated on `hasRealTokenCounts` — every model in this scope being\n * token-billed — rather than on the node's pipe type. That is the difference between\n * a heuristic and the actual discriminator: it gets a controller's branch right too,\n * showing tokens for a branch of LLM and judgment calls and hiding them the moment an\n * extract or a search joins it and turns the total into a blend of measurement and\n * request counter. The costs stay in either case: a price is a price.\n */\nfunction UsageColumn({ scoped, label }: { scoped: ScopedUsage; label: string }) {\n const showsTokens = hasRealTokenCounts(scoped);\n const isPriced = scoped.cost !== null;\n const nbTokensInput = scoped.nbTokensByCategory.input ?? 0;\n const nbTokensOutput = scoped.nbTokensByCategory.output ?? 0;\n\n return (\n <div>\n <div className=\"detail-section-label\">{label}</div>\n <KV label=\"inference calls\" value={scoped.inferenceCalls} />\n <KV label=\"priced calls\" value={scoped.ratedInferenceCalls} />\n\n {showsTokens && <KV label=\"input tokens\" value={nbTokensInput.toLocaleString()} />}\n {isPriced && scoped.costInput !== null && (\n <KV label=\"input cost\" value={formatCost(scoped.costInput)} />\n )}\n\n {showsTokens && <KV label=\"output tokens\" value={nbTokensOutput.toLocaleString()} />}\n {isPriced && scoped.costOutput !== null && (\n <KV label=\"output cost\" value={formatCost(scoped.costOutput)} />\n )}\n\n {/* total_tokens, never a sum of the categories: input_cached is a subset of\n input, so summing them double-counts. */}\n {showsTokens && <KV label=\"total tokens\" value={scoped.totalTokens.toLocaleString()} />}\n <KV label=\"total cost\" value={isPriced ? formatCost(scoped.cost ?? 0) : \"not priced\"} />\n\n {showsTokens &&\n extraCategories(scoped.nbTokensByCategory).map(([category, nbTokens]) => (\n <KV key={category} label={`tokens · ${category}`} value={nbTokens.toLocaleString()} />\n ))}\n </div>\n );\n}\n\n/** The expanded diagnostics: the node's own figures, and its branch's when they differ. */\nexport function UsageDetails({\n usage,\n isController,\n}: {\n usage: GraphSpecNodeUsage;\n isController: boolean;\n}) {\n const own = scopeUsage(usage, \"own\");\n const subtree = scopeUsage(usage, \"subtree\");\n // A leaf's branch is identical to itself; repeating it is noise.\n const showsSubtree = isController || subtree.inferenceCalls !== own.inferenceCalls;\n\n return (\n <div className=\"detail-usage-details\">\n <UsageColumn scoped={own} label={isController ? \"This pipe itself\" : \"Usage\"} />\n {showsSubtree && <UsageColumn scoped={subtree} label=\"This pipe and everything below it\" />}\n </div>\n );\n}\n","import React from \"react\";\nimport type { GraphSpecModelUsage, PipeBlueprintUnion } from \"@graph/types\";\nimport { KV, ModelRows, 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 modelsRan,\n modelHandles,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeLLM\" }>;\n executionData?: Record<string, unknown>;\n /** Models that actually ran on this node; absent for a dry or static graph. */\n modelsRan?: GraphSpecModelUsage[];\n /** execution_data, ungated: the deck-resolved model handle exists in dry specs too. */\n modelHandles?: 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 = modelHandles?.resolved_model as string | undefined;\n const resolvedModelForObject = modelHandles?.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 // The authored choices, straight from the .mthds — the head of the resolution chain.\n // NOT `resolvedModel || authored`: in a live run the handle is already concrete, and\n // preferring it would hide the alias the method actually declares.\n const authoredModel = blueprint.llm_choices?.for_text;\n const authoredModelForObject = blueprint.llm_choices?.for_object;\n // A separate object pass means a second request worth naming. When it matches the\n // text pass there is one request, and the models that ran hang under that one row.\n const hasDistinctObjectRequest = Boolean(\n authoredModelForObject && authoredModelForObject !== authoredModel,\n );\n\n return (\n <>\n {/* Model — the request, with what it resolved to underneath when they differ.\n Every model that served this node is listed there, with call counts when\n there are several. They are NOT split across the two request rows: which\n pass a given model served is not recorded, and splitting them would be a\n guess presented as a fact. */}\n <ModelRows modelsRan={modelsRan} authored={authoredModel} handle={resolvedModel} />\n {hasDistinctObjectRequest && (\n <ModelRows\n authored={authoredModelForObject}\n handle={resolvedModelForObject}\n label=\"Model (object)\"\n />\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","import React from \"react\";\nimport type { GraphSpecModelUsage, PipeBlueprintUnion } from \"@graph/types\";\nimport { KV, ModelRows, PromptToggle } from \"./shared\";\n\nexport function PipeImgGenSection({\n blueprint,\n executionData,\n modelsRan,\n modelHandles,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeImgGen\" }>;\n executionData?: Record<string, unknown>;\n /** Models that actually ran on this node; absent for a dry or static graph. */\n modelsRan?: GraphSpecModelUsage[];\n /** execution_data, ungated: the deck-resolved model handle exists in dry specs too. */\n modelHandles?: Record<string, unknown>;\n}) {\n const spec = blueprint.img_gen_prompt_blueprint;\n const resolvedModel = modelHandles?.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 <ModelRows modelsRan={modelsRan} authored={blueprint.img_gen_choice} handle={resolvedModel} />\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","import React from \"react\";\nimport type { GraphSpecModelUsage, PipeBlueprintUnion } from \"@graph/types\";\nimport { KV, ModelRows } from \"./shared\";\n\nexport function PipeExtractSection({\n blueprint,\n modelsRan,\n modelHandles,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeExtract\" }>;\n /** Models that actually ran on this node; absent for a dry or static graph. */\n modelsRan?: GraphSpecModelUsage[];\n /** execution_data, ungated: the deck-resolved model handle exists in dry specs too. */\n modelHandles?: Record<string, unknown>;\n}) {\n const resolvedModel = modelHandles?.resolved_model as string | undefined;\n\n return (\n <>\n <ModelRows modelsRan={modelsRan} authored={blueprint.extract_choice} handle={resolvedModel} />\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","import React from \"react\";\nimport type { GraphSpecModelUsage, PipeBlueprintUnion } from \"@graph/types\";\nimport { KV, ModelRows, PromptToggle } from \"./shared\";\n\nexport function PipeSearchSection({\n blueprint,\n executionData,\n modelsRan,\n modelHandles,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeSearch\" }>;\n executionData?: Record<string, unknown>;\n /** Models that actually ran on this node; absent for a dry or static graph. */\n modelsRan?: GraphSpecModelUsage[];\n /** execution_data, ungated: the deck-resolved model handle exists in dry specs too. */\n modelHandles?: Record<string, unknown>;\n}) {\n const resolvedModel = modelHandles?.resolved_model as string | undefined;\n const renderedQuery = executionData?.rendered_query as string | undefined;\n\n return (\n <>\n <ModelRows modelsRan={modelsRan} authored={blueprint.search_choice} handle={resolvedModel} />\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","/**\n * Keys, in priority order, under which an inline LLM-choice object may carry its\n * model identifier. `model` is the real field on pipelex's serialized\n * `LLMSetting`; the rest are defensive fallbacks for adjacent shapes.\n */\nconst LLM_CHOICE_LABEL_KEYS = [\"model\", \"llm_handle\", \"handle\", \"llm_name\", \"name\"] as const;\n\nfunction nonEmptyString(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\n/**\n * Derive a human-readable model label from a pipe's `llm_choice`, which may be a\n * plain string handle or an inline LLM setting object (serialized pipelex\n * `LLMSetting`, keyed by `model`). Returns `undefined` when no label can be\n * derived — null, empty, or an unrecognized object — so callers can fall back to\n * the runtime-resolved model.\n */\nexport function labelFromLlmChoice(\n choice: string | Record<string, unknown> | null | undefined,\n): string | undefined {\n if (typeof choice === \"string\") return nonEmptyString(choice);\n if (choice && typeof choice === \"object\") {\n for (const key of LLM_CHOICE_LABEL_KEYS) {\n const label = nonEmptyString(choice[key]);\n if (label) return label;\n }\n }\n return undefined;\n}\n","import React from \"react\";\nimport type { GraphSpecModelUsage, PipeBlueprintUnion } from \"@graph/types\";\nimport { KV, ModelRows, PromptToggle } from \"./shared\";\nimport { labelFromLlmChoice } from \"./llmChoice\";\n\n/**\n * Unified PipeStructure detail — merges blueprint config and runtime execution\n * data into a single view. Runtime values take precedence when available.\n * PipeStructure is an LLM-backed operator that turns a single Text input into a\n * structured concept.\n */\nexport function PipeStructureSection({\n blueprint,\n executionData,\n modelsRan,\n modelHandles,\n}: {\n blueprint: Extract<PipeBlueprintUnion, { type: \"PipeStructure\" }>;\n executionData?: Record<string, unknown>;\n /** Models that actually ran on this node; absent for a dry or static graph. */\n modelsRan?: GraphSpecModelUsage[];\n /** execution_data, ungated: the deck-resolved model handle exists in dry specs too. */\n modelHandles?: Record<string, unknown>;\n}) {\n // Runtime-resolved values (from execution_data).\n const resolvedModel = modelHandles?.resolved_model as string | undefined;\n const isMultipleOutput = executionData?.is_multiple_output as boolean | undefined;\n const renderedUser = executionData?.rendered_user_prompt as string | undefined;\n\n // The authored choice (a string handle or an inline LLMSetting object), shown as\n // the head of the resolution chain rather than as a fallback — see ModelRows.\n const authoredModel = labelFromLlmChoice(blueprint.llm_choice);\n\n return (\n <>\n <ModelRows modelsRan={modelsRan} authored={authoredModel} handle={resolvedModel} />\n <KV label=\"Text Variable\" value={blueprint.text_input_name} />\n <KV label=\"Multiple Output\" value={isMultipleOutput} />\n <KV label=\"Output Multiplicity\" value={blueprint.output_multiplicity} />\n\n {/* Rendered structuring prompt sent to the LLM. */}\n <PromptToggle label=\"Prompt\" templateText={undefined} renderedText={renderedUser} />\n </>\n );\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 // Loose `!= null`: a host that drops nulls delivers a template-mode blueprint with\n // no `construct_blueprint` key at all (see the registry types in types.ts).\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","import React from \"react\";\nimport type { GraphSpecModelUsage, PipeBlueprintUnion } from \"@graph/types\";\nimport { KV, ModelRows, PromptToggle } from \"./shared\";\nimport { labelFromLlmChoice } from \"./llmChoice\";\n\n/**\n * The words for what the step's engine prints from, keyed by the runtime's\n * `DocGenSource` token: an open set, so a token with no entry prints as itself.\n */\nconst DOC_GEN_SOURCE_LABELS: Readonly<Record<string, string>> = {\n layout: \"auto-layout\",\n html: \"HTML template\",\n template_file: \"template file\",\n};\n\ntype PipeDocGenBlueprint = Extract<PipeBlueprintUnion, { type: \"PipeDocGen\" }>;\n\n/**\n * The source token a step composes from, derived from the blueprint alone for a\n * graph that ran nothing, by the runtime's own rule: no template is the\n * auto-layout, and a template is HTML for a pdf, inline or read from its file,\n * and a template file for any other format.\n */\nfunction declaredSource(blueprint: PipeDocGenBlueprint): string {\n if (blueprint.template == null && blueprint.template_file == null) return \"layout\";\n if (blueprint.template != null || blueprint.doc_gen_format === \"pdf\") return \"html\";\n return \"template_file\";\n}\n\nfunction nonEmpty(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() !== \"\" ? value : undefined;\n}\n\n/**\n * A PipeDocGen step: the document it prints, the engine that prints it, what it\n * prints from, and the name it is stored under.\n *\n * It never shows the stored document's `url`, which the run's execution data\n * carries: the document is the step's output, which the graph shows through its\n * data panel, and a second, raw copy here is, with an inlined document, a wall\n * of base64.\n */\nexport function PipeDocGenSection({\n blueprint,\n executionData,\n modelsRan,\n modelHandles,\n}: {\n blueprint: PipeDocGenBlueprint;\n /** execution_data of a real run only: the rendered file name is a product of the run. */\n executionData?: Record<string, unknown>;\n /** Models that actually ran on this node; absent for a dry or static graph. */\n modelsRan?: GraphSpecModelUsage[];\n /**\n * execution_data, ungated: the engine the deck resolves and the source the step\n * composes from are decided before anything runs, so a dry graph carries both.\n */\n modelHandles?: Record<string, unknown>;\n}) {\n const format = nonEmpty(blueprint.doc_gen_format);\n const authoredEngine = labelFromLlmChoice(blueprint.doc_gen_choice);\n const resolvedEngine = nonEmpty(modelHandles?.resolved_model);\n const hasEngine = !!authoredEngine || !!resolvedEngine || (modelsRan?.length ?? 0) > 0;\n const source = nonEmpty(modelHandles?.source) ?? declaredSource(blueprint);\n const renderedFilename = nonEmpty(executionData?.filename);\n\n return (\n <>\n <KV label=\"Format\" value={format?.toUpperCase()} />\n {hasEngine ? (\n <ModelRows\n label=\"Engine\"\n modelsRan={modelsRan}\n authored={authoredEngine}\n handle={resolvedEngine}\n />\n ) : (\n <KV label=\"Engine\" value=\"deck default\" />\n )}\n <KV label=\"Source\" value={DOC_GEN_SOURCE_LABELS[source] ?? source} />\n <KV label=\"Template File\" value={blueprint.template_file} />\n <KV label=\"File Name\" value={blueprint.filename} />\n {renderedFilename && renderedFilename !== blueprint.filename && (\n <KV label=\"Stored As\" value={renderedFilename} />\n )}\n {blueprint.template && (\n <PromptToggle label=\"Template\" templateText={blueprint.template} renderedText={null} />\n )}\n </>\n );\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","import React from \"react\";\nimport type { PipeBlueprintUnion } from \"@graph/types\";\nimport { isBindingStepSpec } 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 {isBindingStepSpec(step) ? (\n // A binding step runs no pipe: it names the path it binds.\n <span className=\"detail-step-code\" title=\"Binding step\">\n from {step.from_path}\n </span>\n ) : (\n <span className=\"detail-step-code\">{step.pipe_code}</span>\n )}\n {step.output_name && (\n <span className=\"detail-io-concept\">-&gt; {step.output_name}</span>\n )}\n </div>\n ))}\n </div>\n </div>\n );\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\">-&gt; {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","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","import React from \"react\";\nimport type { GraphSpecNode } from \"@graph/types\";\nimport { KV } from \"./shared\";\n\n/**\n * What a binding step binds: the path it reads and the name it stores the value\n * under. Both are structural, so they show in every mode, a static graph\n * included.\n *\n * pipelex records them as the node's `execution_data` (`from`, `result`), the\n * static builder too. The node itself says as much when that record is absent:\n * its `pipe_code` is the `from` path, and its one output, when it bound a value,\n * carries the `result` name.\n */\nexport function BindingStepSection({ node }: { node: GraphSpecNode }) {\n const executionData = node.execution_data ?? {};\n const fromPath = typeof executionData.from === \"string\" ? executionData.from : node.pipe_code;\n const result =\n typeof executionData.result === \"string\" ? executionData.result : node.io.outputs[0]?.name;\n return (\n <div>\n <div className=\"detail-section-label\">Binding</div>\n <KV label=\"From\" value={fromPath} />\n <KV label=\"Result\" value={result} />\n </div>\n );\n}\n","import type { NodePipeType, PipeType } from \"@graph/types\";\n\n/**\n * Pipe types whose runtime `execution_data` is merged into their blueprint\n * section (`Pipe*Section`). When the blueprint resolves, the section already\n * renders the runtime values, so the dedicated execution-data dump is\n * suppressed to avoid duplication. Every type with a `Pipe*Section` renderer is\n * listed here; `PipeFunc` (no section) and `PipeSignature` (stub) are not.\n */\nexport const MERGED_EXECUTION_DATA_TYPES: ReadonlySet<string> = new Set<PipeType>([\n \"PipeLLM\",\n \"PipeImgGen\",\n \"PipeExtract\",\n \"PipeSearch\",\n \"PipeStructure\",\n \"PipeCompose\",\n \"PipeDocGen\",\n \"PipeSequence\",\n \"PipeParallel\",\n \"PipeCondition\",\n \"PipeBatch\",\n]);\n\n/**\n * Execution-data keys the raw dump never shows, per pipe type, even when the\n * blueprint failed to resolve. A `PipeDocGen`'s `url` is the stored document\n * itself, which is the step's output and shown as one: with an inlined\n * document it is a `data:` URL carrying the whole file in base64.\n */\nconst UNDUMPED_EXECUTION_DATA_KEYS: Readonly<Partial<Record<NodePipeType, ReadonlySet<string>>>> = {\n PipeDocGen: new Set([\"url\"]),\n};\n\n/**\n * Decide whether to render the raw execution-data dump (`GenericExecutionData`).\n *\n * For a merged type we only dump when the blueprint failed to resolve — otherwise\n * its runtime values would be silently dropped, since the per-type section never\n * mounts (it is gated on the blueprint). For any other type (`PipeFunc`,\n * `PipeSignature`, or a future/unknown type) there is no merged section, so the\n * dump is always shown.\n */\nexport function shouldDumpExecutionData(pipeType: string, hasBlueprint: boolean): boolean {\n if (MERGED_EXECUTION_DATA_TYPES.has(pipeType)) return !hasBlueprint;\n return true;\n}\n\n/** The execution-data entries the raw dump shows for a pipe type, in their order. */\nexport function dumpableExecutionData(\n pipeType: NodePipeType,\n executionData: Record<string, unknown>,\n): [string, unknown][] {\n const undumped = UNDUMPED_EXECUTION_DATA_KEYS[pipeType];\n const entries = Object.entries(executionData);\n return undumped ? entries.filter(([key]) => !undumped.has(key)) : entries;\n}\n","import React from \"react\";\nimport type { ConceptInfo, GraphSpecNodeIoItem } from \"@graph/types\";\nimport { isPluralMultiplicity, multiplicitySuffix } from \"@graph/types\";\n\n// ─── Props ──────────────────────────────────────────────────────────────\n\nexport interface ConceptDetailPanelProps {\n concept: ConceptInfo;\n /** The data item for this concept instance, as the `GraphSpec` holds it. */\n ioData?: GraphSpecNodeIoItem;\n /** Whether this is a dry run (schema only, no real data). */\n isDryRun?: boolean;\n /**\n * Renders the data half. `GraphViewer` supplies it as a `StuffResultPanel`,\n * the form kernel's descriptor-driven result view, when the host's `graph`\n * carries `pipeIoContracts` and `outputForm`; see `docs/stuff-result-panel.md`.\n *\n * Without it — or when it returns nothing for this item — the panel shows the\n * structure table alone and no tabs, which is what a viewer that has not been\n * given a renderer honestly has to offer.\n */\n renderData?: () => React.ReactNode;\n /**\n * Identity of the selected node/instance (e.g. the graph node id). Drives\n * the Data/Structure tab reset: a new `instanceKey` remounts the body so\n * the Data tab is selected again. Without it, two nodes sharing the same\n * concept AND the same stuff name/digest (typical for batch branches) would\n * keep the previous node's tab selection.\n */\n instanceKey?: string;\n}\n\n// ─── Component ──────────────────────────────────────────────────────────\n\nexport function ConceptDetailPanel({\n concept,\n ioData,\n isDryRun,\n renderData,\n instanceKey,\n}: ConceptDetailPanelProps) {\n // The concept describes one item; the io item says how many a stuff holds.\n const multiplicity = ioData?.multiplicity;\n return (\n <>\n {/* Header */}\n <div className=\"detail-header\">\n <span className=\"detail-concept-code\">\n {concept.code + multiplicitySuffix(multiplicity)}\n </span>\n <span className=\"detail-concept-domain\">{concept.domain_code}</span>\n </div>\n\n {/* Plurality, stated before the description so \"A document\" reads as one item of the list */}\n {isPluralMultiplicity(multiplicity) && (\n <div className=\"detail-multiplicity\">\n {multiplicity === true\n ? `A variable-length list of ${concept.code} items`\n : `A fixed-length list of exactly ${multiplicity as number} ${concept.code} items`}\n </div>\n )}\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 <ConceptBody\n key={\n instanceKey ??\n `${concept.code}:${ioData && \"digest\" in ioData ? ioData.digest : (ioData?.name ?? \"\")}`\n }\n concept={concept}\n ioData={ioData}\n isDryRun={isDryRun}\n renderData={renderData}\n />\n </>\n );\n}\n\n/**\n * Structure + data sections. When instance data exists, the two are split\n * into \"Data\" / \"Structure\" tabs with Data shown by default — the schema\n * table is reference material, not something to scroll past on every click.\n * Without data (dry run / unexecuted), the structure renders directly.\n */\nfunction ConceptBody({ concept, ioData, isDryRun, renderData }: ConceptDetailPanelProps) {\n // The data tab exists only when something can actually fill it. Three\n // conditions, and the third is the new one: an item, a real run behind it,\n // and a renderer that produced something for it. A tab that opens onto an\n // empty pane is worse than no tab, because it reads as data that failed to\n // load rather than as a viewer that was never given a way to show it.\n const dataView = ioData && !isDryRun ? renderData?.() : undefined;\n const hasData = Boolean(dataView);\n const [activeTab, setActiveTab] = React.useState<TabId>(hasData ? \"data\" : \"structure\");\n const baseId = React.useId();\n const tabId = (tab: TabId) => `${baseId}-tab-${tab}`;\n const panelId = (tab: TabId) => `${baseId}-tabpanel-${tab}`;\n\n const structure = concept.json_schema ? (\n <div>\n <div className=\"detail-section-label\">Structure</div>\n <SchemaTable schema={concept.json_schema} />\n </div>\n ) : (\n <div className=\"detail-not-available\">Schema not available</div>\n );\n\n if (!hasData) return structure;\n\n // ARIA tabs keyboard pattern: arrows move between the two tabs (and\n // activate, per \"selection follows focus\"), Home/End jump to first/last.\n const onTabKeyDown = (event: React.KeyboardEvent) => {\n let next: TabId;\n switch (event.key) {\n case \"ArrowLeft\":\n case \"ArrowRight\":\n next = activeTab === \"data\" ? \"structure\" : \"data\";\n break;\n case \"Home\":\n next = \"data\";\n break;\n case \"End\":\n next = \"structure\";\n break;\n default:\n return;\n }\n event.preventDefault();\n setActiveTab(next);\n document.getElementById(tabId(next))?.focus();\n };\n\n const renderTab = (tab: TabId, label: string) => (\n <button\n type=\"button\"\n role=\"tab\"\n id={tabId(tab)}\n aria-selected={activeTab === tab}\n aria-controls={panelId(tab)}\n tabIndex={activeTab === tab ? 0 : -1}\n className={`detail-tab ${activeTab === tab ? \"detail-tab--active\" : \"\"}`}\n onClick={() => setActiveTab(tab)}\n onKeyDown={onTabKeyDown}\n >\n {label}\n </button>\n );\n\n return (\n <>\n <div className=\"detail-tabs\" role=\"tablist\" aria-label=\"Concept views\">\n {renderTab(\"data\", \"Data\")}\n {renderTab(\"structure\", \"Structure\")}\n </div>\n <div role=\"tabpanel\" id={panelId(activeTab)} aria-labelledby={tabId(activeTab)}>\n {activeTab === \"data\" ? dataView : structure}\n </div>\n </>\n );\n}\n\ntype TabId = \"data\" | \"structure\";\n\n// ─── Schema table renderer ──────────────────────────────────────────────\n\nfunction SchemaTable({ schema }: { schema: Record<string, unknown> }) {\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\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 {fields.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 (typeof schema.type === \"string\") return schema.type;\n if (Array.isArray(schema.type)) return schema.type.join(\" | \");\n if (schema.anyOf) return \"union\";\n if (schema.allOf) return \"all\";\n if (typeof schema.$ref === \"string\") {\n const ref = schema.$ref;\n return ref.split(\"/\").pop() ?? \"(unresolved type)\";\n }\n return \"(unresolved type)\";\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 { EdgeRoute, 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 * A route the layout computed travels in `data.route`, where the routed edge\n * component reads it (see `RoutedEdgeData`).\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 ...(e.route ? { data: { route: e.route } satisfies RoutedEdgeData } : {}),\n }));\n}\n\n/** What a routed edge carries in its ReactFlow `data`. */\nexport interface RoutedEdgeData extends Record<string, unknown> {\n route?: EdgeRoute;\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 { Panel, type PanelPosition } from \"@xyflow/react\";\nimport {\n GRAPH_DIRECTION,\n GRAPH_THEME_MODE,\n VALIDATION_STATE,\n toolbarOrientation,\n toolbarSide,\n type GraphDirection,\n type GraphStyleId,\n type GraphThemeMode,\n type ToolbarPosition,\n type ValidationIssue,\n type ValidationState,\n} from \"@graph/types\";\nimport { ValidationPanel, validationLabel, validationPanelPlacement } from \"./ValidationPanel\";\nimport { StyleMenu } from \"./StyleMenu\";\nimport { usePopoverDismiss } from \"./usePopoverDismiss\";\n\n/**\n * ReactFlow's default `<Panel>` margin (`.react-flow__panel { margin: 15px }`).\n * Its center-anchor rules hardcode a `translate(-15px)` that cancels exactly\n * this margin, so we let ReactFlow own the base margin and only *add* to it for\n * the detail-panel dodge — never override the `margin` shorthand (see below).\n */\nconst REACTFLOW_PANEL_MARGIN = 15;\n\n// Guarantees our public `ToolbarPosition` enum stays a strict subset of\n// ReactFlow's `PanelPosition`, so every value passes straight to `<Panel>`.\n// This assertion belongs in the React layer — `types.ts` stays React-free and\n// must never import `PanelPosition`.\ntype _AssertToolbarPositionIsPanelPosition = ToolbarPosition extends PanelPosition ? true : never;\nconst _toolbarPositionCompat: _AssertToolbarPositionIsPanelPosition = true;\nvoid _toolbarPositionCompat;\n\nexport interface GraphToolbarProps {\n direction: GraphDirection;\n onDirectionChange: (direction: GraphDirection) => void;\n showControllers: boolean;\n /**\n * Toggle handler for the controller frames. The toggle renders only when this\n * is set: a style that decides its own frames leaves it unset.\n */\n onShowControllersChange?: (showControllers: boolean) => void;\n /** The active graph style, shown on the style menu's button. */\n graphStyle?: GraphStyleId;\n /**\n * The styles the menu offers, in order. The menu renders when this holds at\n * least two styles and `graphStyle` and `onGraphStyleChange` are set.\n */\n styleMenuOptions?: readonly GraphStyleId[];\n /** Style change handler, called with the style chosen in the menu. */\n onGraphStyleChange?: (style: GraphStyleId) => 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 /** Current theme mode. Renders the theme toggle when both this and `onThemeModeChange` are set. */\n themeMode?: GraphThemeMode;\n /** Theme mode change handler. Renders the theme toggle when both this and `themeMode` are set. */\n onThemeModeChange?: (mode: GraphThemeMode) => void;\n /** Pixel offset from the right edge (e.g. detail panel width when open). */\n rightOffset?: number;\n /**\n * State of the validation widget. Renders the widget (as the toolbar's first\n * section) only when set — `undefined` (the default) hides it entirely.\n */\n validationState?: ValidationState;\n /** Issues listed in the validation dropdown; the badge shows their count. */\n validationIssues?: ValidationIssue[];\n /** Issue row-click handler; the host typically navigates to the issue's source. */\n onValidationIssueClick?: (index: number, issue: ValidationIssue) => void;\n /**\n * Controlled open state of the validation dropdown. GraphViewer owns it so\n * node badges can open the panel; the toolbar still handles the toggle\n * button and outside-click/Escape dismissal through `onValidationOpenChange`.\n */\n validationOpen?: boolean;\n /** Open-state change requests (toggle click, outside click, Escape). */\n onValidationOpenChange?: (open: boolean) => void;\n /**\n * Anchor for the toolbar. The value is forwarded to a ReactFlow\n * `<Panel position=…>`; orientation (row vs column) is derived from it via\n * {@link toolbarOrientation}. Required — `GraphViewer` always resolves it from\n * the prop/config/default chain (see `resolveToolbarPosition`).\n */\n position: ToolbarPosition;\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\nconst SUN_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 <circle cx=\"12\" cy=\"12\" r=\"4\" />\n <line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"4\" />\n <line x1=\"12\" y1=\"20\" x2=\"12\" y2=\"22\" />\n <line x1=\"4.93\" y1=\"4.93\" x2=\"6.34\" y2=\"6.34\" />\n <line x1=\"17.66\" y1=\"17.66\" x2=\"19.07\" y2=\"19.07\" />\n <line x1=\"2\" y1=\"12\" x2=\"4\" y2=\"12\" />\n <line x1=\"20\" y1=\"12\" x2=\"22\" y2=\"12\" />\n <line x1=\"4.93\" y1=\"19.07\" x2=\"6.34\" y2=\"17.66\" />\n <line x1=\"17.66\" y1=\"6.34\" x2=\"19.07\" y2=\"4.93\" />\n </svg>\n);\n\nconst MOON_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=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\" />\n </svg>\n);\n\n/** `system` mode — a monitor glyph reading as \"follow the system\". */\nconst MONITOR_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=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\" />\n <line x1=\"8\" y1=\"21\" x2=\"16\" y2=\"21\" />\n <line x1=\"12\" y1=\"17\" x2=\"12\" y2=\"21\" />\n </svg>\n);\n\n/** `validating` — a three-quarter arc, spun by CSS. */\nconst SPINNER_ICON = (\n <svg\n className=\"graph-toolbar-validation-spin\"\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=\"M21 12a9 9 0 1 1-6.219-8.56\" />\n </svg>\n);\n\nconst CHECK_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=\"20 6 9 17 4 12\" />\n </svg>\n);\n\nconst X_CIRCLE_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 <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\" />\n <line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\" />\n </svg>\n);\n\nconst ALERT_TRIANGLE_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=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z\" />\n <line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\" />\n <line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\" />\n </svg>\n);\n\n/** `unvalidated` — an information mark: notes from reading, not a verdict. */\nconst INFO_CIRCLE_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 <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\" />\n <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\" />\n </svg>\n);\n\n/** The icon shown for a validation state. Pure, unit-testable. */\nexport function validationIcon(state: ValidationState): React.ReactElement {\n switch (state) {\n case VALIDATION_STATE.VALIDATING:\n return SPINNER_ICON;\n case VALIDATION_STATE.VALID:\n return CHECK_ICON;\n case VALIDATION_STATE.INVALID:\n return X_CIRCLE_ICON;\n case VALIDATION_STATE.ERROR:\n return ALERT_TRIANGLE_ICON;\n case VALIDATION_STATE.UNVALIDATED:\n return INFO_CIRCLE_ICON;\n default: {\n const _exhaustive: never = state;\n return _exhaustive;\n }\n }\n}\n\n// ─── Theme-mode toggle: pure cycle + presentation helpers ───────────────────\n// Exported so the cycle order and per-state labels/icons are unit-testable\n// without rendering. Order: system → light → dark → system.\n\nconst THEME_MODE_CYCLE: readonly GraphThemeMode[] = [\n GRAPH_THEME_MODE.SYSTEM,\n GRAPH_THEME_MODE.LIGHT,\n GRAPH_THEME_MODE.DARK,\n];\n\n/** Next mode in the system → light → dark → system cycle. */\nexport function nextThemeMode(current: GraphThemeMode): GraphThemeMode {\n const idx = THEME_MODE_CYCLE.indexOf(current);\n return THEME_MODE_CYCLE[(idx + 1) % THEME_MODE_CYCLE.length];\n}\n\n/** The icon shown for the current mode (represents the state, not the next action). */\nexport function themeModeIcon(mode: GraphThemeMode): React.ReactElement {\n if (mode === GRAPH_THEME_MODE.LIGHT) return SUN_ICON;\n if (mode === GRAPH_THEME_MODE.DARK) return MOON_ICON;\n return MONITOR_ICON;\n}\n\n/** Accessible label naming the current mode and the one a click switches to. */\nexport function themeModeLabel(mode: GraphThemeMode): string {\n const names: Record<GraphThemeMode, string> = {\n [GRAPH_THEME_MODE.SYSTEM]: \"system\",\n [GRAPH_THEME_MODE.LIGHT]: \"light\",\n [GRAPH_THEME_MODE.DARK]: \"dark\",\n };\n const next = nextThemeMode(mode);\n return `Theme: ${names[mode]} — switch to ${names[next]}`;\n}\n\nexport function GraphToolbar({\n direction,\n onDirectionChange,\n showControllers,\n onShowControllersChange,\n graphStyle,\n styleMenuOptions = [],\n onGraphStyleChange,\n onZoomIn,\n onZoomOut,\n onFitView,\n onFoldAll,\n onExpandAll,\n foldAllDisabled = false,\n expandAllDisabled = false,\n themeMode,\n onThemeModeChange,\n rightOffset = 0,\n position,\n validationState,\n validationIssues = [],\n onValidationIssueClick,\n validationOpen = false,\n onValidationOpenChange,\n}: GraphToolbarProps) {\n const themeToggleEnabled = themeMode !== undefined && onThemeModeChange !== undefined;\n const orientation = toolbarOrientation(position);\n\n // The dropdown's open state is controlled by GraphViewer (so node badges can\n // open the panel too); the toolbar owns the toggle button and the\n // outside-click/Escape dismissal, reported through onValidationOpenChange.\n const setValidationOpen = onValidationOpenChange ?? (() => {});\n const setValidationOpenRef = React.useRef(setValidationOpen);\n setValidationOpenRef.current = setValidationOpen;\n const validationRef = React.useRef<HTMLDivElement | null>(null);\n // useId, not a constant: several viewers can coexist on one page (Storybook grids).\n const validationPanelId = React.useId();\n // The widget can be hidden (validationState undefined) while GraphToolbar stays\n // mounted; drop the open state so re-enabling doesn't resurrect the dropdown.\n React.useEffect(() => {\n if (validationState === undefined) setValidationOpenRef.current(false);\n }, [validationState]);\n usePopoverDismiss(validationOpen, validationRef, () => setValidationOpenRef.current(false));\n const styleMenuEnabled =\n graphStyle !== undefined && onGraphStyleChange !== undefined && styleMenuOptions.length >= 2;\n // ReactFlow's <Panel> owns all base positioning: the anchor, its default 15px\n // margin, and the center-anchor transforms calibrated to cancel exactly that\n // margin. We deliberately do NOT set the `margin` shorthand here —\n // - overriding it (e.g. to 8px) leaves ReactFlow's hardcoded -15px center\n // compensation in place, mis-centering every center anchor; and\n // - mixing an inline `margin` shorthand with a conditional `marginRight`\n // longhand defeats React's style reconciliation — clearing the longhand\n // can't restore the shorthand, so the bar stays stuck at the wrong offset\n // once the panel closes.\n // The only override is the detail-panel dodge: the panel overlays the right\n // edge, so right-anchored bars shift left by its width. Expressed as\n // `marginRight` alone (base margin + width); when the panel closes the inline\n // value is dropped and the gap falls cleanly back to the stylesheet's margin.\n const dodgesDetailPanel = toolbarSide(position) === \"right\" && rightOffset > 0;\n const panelStyle: React.CSSProperties | undefined = dodgesDetailPanel\n ? { marginRight: REACTFLOW_PANEL_MARGIN + rightOffset }\n : undefined;\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 <Panel position={position} className=\"graph-toolbar-panel\" style={panelStyle}>\n <div className={`graph-toolbar graph-toolbar--${orientation}`}>\n {validationState !== undefined && (\n <>\n <div className=\"graph-toolbar-validation\" ref={validationRef}>\n <button\n type=\"button\"\n className={`graph-toolbar-btn graph-toolbar-validation-btn graph-toolbar-validation-btn--${validationState}`}\n onClick={() => setValidationOpen(!validationOpen)}\n title={validationLabel(validationState, validationIssues.length)}\n aria-label={validationLabel(validationState, validationIssues.length)}\n aria-expanded={validationOpen}\n aria-haspopup=\"true\"\n aria-controls={validationPanelId}\n >\n {validationIcon(validationState)}\n {validationIssues.length > 0 && (\n <span className=\"graph-toolbar-validation-badge\">\n {validationIssues.length > 99 ? \"99+\" : validationIssues.length}\n </span>\n )}\n </button>\n {validationOpen && (\n <ValidationPanel\n id={validationPanelId}\n state={validationState}\n issues={validationIssues}\n onIssueClick={onValidationIssueClick}\n placement={validationPanelPlacement(position)}\n />\n )}\n </div>\n <div className=\"graph-toolbar-separator\" />\n </>\n )}\n\n {styleMenuEnabled && (\n <>\n <StyleMenu\n value={graphStyle}\n options={styleMenuOptions}\n onChange={onGraphStyleChange}\n placement={validationPanelPlacement(position)}\n />\n <div className=\"graph-toolbar-separator\" />\n </>\n )}\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 {foldAllSection && <div className=\"graph-toolbar-separator\" />}\n\n {onShowControllersChange && (\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\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 {(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\n {themeToggleEnabled && (\n <>\n <div className=\"graph-toolbar-separator\" />\n <button\n type=\"button\"\n className=\"graph-toolbar-btn\"\n onClick={() => onThemeModeChange(nextThemeMode(themeMode))}\n title={themeModeLabel(themeMode)}\n aria-label={themeModeLabel(themeMode)}\n >\n {themeModeIcon(themeMode)}\n </button>\n </>\n )}\n </div>\n </Panel>\n );\n}\n","import React from \"react\";\nimport {\n TOOLBAR_POSITION,\n VALIDATION_STATE,\n type ToolbarPosition,\n type ValidationIssue,\n type ValidationState,\n} from \"@graph/types\";\n\n/**\n * Human label for a validation state + issue count. Used as the widget button's\n * title/aria-label and as the panel header. Pure, unit-testable.\n */\nexport function validationLabel(state: ValidationState, issueCount: number): string {\n const issues = issueCount === 1 ? \"1 issue\" : `${issueCount} issues`;\n switch (state) {\n case VALIDATION_STATE.VALIDATING:\n return issueCount > 0 ? `Validating method… — ${issues}` : \"Validating method…\";\n case VALIDATION_STATE.VALID:\n return issueCount > 0 ? `Method is valid — ${issues}` : \"Method is valid\";\n case VALIDATION_STATE.INVALID:\n return `Method is invalid — ${issues}`;\n case VALIDATION_STATE.ERROR:\n return \"Validation could not run\";\n case VALIDATION_STATE.UNVALIDATED:\n return issueCount > 0\n ? `Not validated — ${issues} found reading the source`\n : \"Not validated\";\n default: {\n const _exhaustive: never = state;\n return _exhaustive;\n }\n }\n}\n\n/**\n * How the dropdown opens relative to the validation button, derived from the\n * toolbar anchor so the panel always unfolds toward the graph, never off-screen:\n * `down-*`/`up-*` for horizontal bars (top vs bottom anchors), aligned to the\n * button's `start` (left) or `end` (right) edge; `side-end`/`side-start` for the\n * vertical bars, opening away from the hugged edge.\n */\nexport type ValidationPanelPlacement =\n | \"down-start\"\n | \"down-end\"\n | \"up-start\"\n | \"up-end\"\n | \"side-start\"\n | \"side-end\";\n\n/** Derive the dropdown placement from the toolbar anchor. Pure, unit-testable. */\nexport function validationPanelPlacement(position: ToolbarPosition): ValidationPanelPlacement {\n switch (position) {\n case TOOLBAR_POSITION.TOP_LEFT:\n case TOOLBAR_POSITION.TOP_CENTER:\n return \"down-start\";\n case TOOLBAR_POSITION.TOP_RIGHT:\n return \"down-end\";\n case TOOLBAR_POSITION.BOTTOM_LEFT:\n case TOOLBAR_POSITION.BOTTOM_CENTER:\n return \"up-start\";\n case TOOLBAR_POSITION.BOTTOM_RIGHT:\n return \"up-end\";\n case TOOLBAR_POSITION.CENTER_LEFT:\n return \"side-end\";\n case TOOLBAR_POSITION.CENTER_RIGHT:\n return \"side-start\";\n default: {\n const _exhaustive: never = position;\n return _exhaustive;\n }\n }\n}\n\n/** Fallback body text when the host supplied no issues for the current state. */\nexport function validationEmptyText(state: ValidationState): string {\n switch (state) {\n case VALIDATION_STATE.VALIDATING:\n return \"Validating…\";\n case VALIDATION_STATE.VALID:\n return \"No issues found.\";\n case VALIDATION_STATE.INVALID:\n return \"No details available.\";\n case VALIDATION_STATE.ERROR:\n return \"Validation could not run.\";\n case VALIDATION_STATE.UNVALIDATED:\n return \"Nothing found reading the source. The method has not been validated.\";\n default: {\n const _exhaustive: never = state;\n return _exhaustive;\n }\n }\n}\n\nexport interface ValidationPanelProps {\n state: ValidationState;\n issues: ValidationIssue[];\n /** Row-click handler; rows render as buttons only when this is set. */\n onIssueClick?: (index: number, issue: ValidationIssue) => void;\n placement: ValidationPanelPlacement;\n /** Id of the panel root, referenced by the toolbar button's aria-controls. */\n id?: string;\n}\n\n/**\n * The dropdown listing validation issues, opened from the toolbar's validation\n * widget. Purely presentational: the host owns the issue list and what a row\n * click does (typically: navigate to the issue's source location).\n */\nexport function ValidationPanel({\n state,\n issues,\n onIssueClick,\n placement,\n id,\n}: ValidationPanelProps) {\n return (\n <div\n id={id}\n className={`graph-validation-panel graph-validation-panel--${placement}`}\n role=\"region\"\n aria-label=\"Validation issues\"\n >\n <div className=\"graph-validation-panel-header\">{validationLabel(state, issues.length)}</div>\n {/* Explicit role=\"list\": list-style:none strips implicit list semantics in Safari. */}\n {issues.length === 0 ? (\n <div className=\"graph-validation-empty\">{validationEmptyText(state)}</div>\n ) : (\n <ul className=\"graph-validation-issues\" role=\"list\">\n {issues.map((issue, index) => {\n const clickable = onIssueClick !== undefined;\n const meta = (issue.context || issue.file) && (\n <div className=\"graph-validation-issue-meta\">\n {issue.context && (\n <span className=\"graph-validation-issue-context\">{issue.context}</span>\n )}\n {issue.file && <span className=\"graph-validation-issue-file\">{issue.file}</span>}\n </div>\n );\n // Button semantics go on an inner body element, not the <li> itself,\n // so each row keeps its listitem role for assistive tech.\n return (\n <li\n key={index}\n className={\n `graph-validation-issue graph-validation-issue--${issue.severity}` +\n (clickable ? \" graph-validation-issue--clickable\" : \"\")\n }\n >\n <div\n className=\"graph-validation-issue-body\"\n role={clickable ? \"button\" : undefined}\n tabIndex={clickable ? 0 : undefined}\n onClick={clickable ? () => onIssueClick(index, issue) : undefined}\n onKeyDown={\n clickable\n ? (event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onIssueClick(index, issue);\n }\n }\n : undefined\n }\n >\n {meta}\n <div className=\"graph-validation-issue-message\">{issue.message}</div>\n {issue.suggestedFix && (\n <div className=\"graph-validation-issue-fix\">{issue.suggestedFix}</div>\n )}\n </div>\n </li>\n );\n })}\n </ul>\n )}\n </div>\n );\n}\n","import React from \"react\";\nimport { GRAPH_STYLE, type GraphStyleId } from \"@graph/types\";\nimport { GRAPH_STYLES } from \"@graph/styles/graphStyles\";\nimport type { ValidationPanelPlacement } from \"./ValidationPanel\";\nimport { usePopoverDismiss } from \"./usePopoverDismiss\";\n\nconst ICON_PROPS = {\n viewBox: \"0 0 24 24\",\n width: 14,\n height: 14,\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\" as const,\n strokeLinejoin: \"round\" as const,\n};\n\n/**\n * Each style's icon, on the toolbar button (the current style) and in its menu\n * row. Keyed by `GraphStyleId`, so a new style does not compile without one.\n */\nconst STYLE_ICONS: Record<GraphStyleId, React.ReactElement> = {\n // Cards with their rows: every pipe with its slots.\n [GRAPH_STYLE.DETAILED]: (\n <svg {...ICON_PROPS}>\n <rect x=\"3\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\" />\n <rect x=\"3\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\" />\n <line x1=\"14\" y1=\"4\" x2=\"21\" y2=\"4\" />\n <line x1=\"14\" y1=\"9\" x2=\"21\" y2=\"9\" />\n <line x1=\"14\" y1=\"15\" x2=\"21\" y2=\"15\" />\n <line x1=\"14\" y1=\"20\" x2=\"21\" y2=\"20\" />\n </svg>\n ),\n // Two steps and the arrow between them: a flowchart.\n [GRAPH_STYLE.SIMPLE]: (\n <svg {...ICON_PROPS}>\n <rect x=\"3\" y=\"3\" width=\"8\" height=\"8\" rx=\"2\" />\n <path d=\"M7 11v4a2 2 0 0 0 2 2h4\" />\n <rect x=\"13\" y=\"13\" width=\"8\" height=\"8\" rx=\"2\" />\n </svg>\n ),\n};\n\nconst CHECK_ICON = (\n <svg {...ICON_PROPS}>\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n);\n\n/** The icon of a style. Pure, unit-testable. */\nexport function graphStyleIcon(style: GraphStyleId): React.ReactElement {\n return STYLE_ICONS[style];\n}\n\n/** Accessible label of the menu button: the current style, and what the button does. */\nexport function styleMenuLabel(style: GraphStyleId): string {\n return `Graph style: ${GRAPH_STYLES[style].name} — choose how the graph is drawn`;\n}\n\nexport interface StyleMenuProps {\n /** The active style, shown on the button and checked in the list. */\n value: GraphStyleId;\n /** The styles offered, in order. */\n options: readonly GraphStyleId[];\n onChange: (style: GraphStyleId) => void;\n /** Where the list opens, from the toolbar's anchor — the validation dropdown's vocabulary. */\n placement: ValidationPanelPlacement;\n}\n\n/**\n * The toolbar's style menu: a button showing the current style's icon, opening\n * a list of radio items, each with its icon, name and one-line description, and\n * a check on the current one. A list rather than a two-state toggle, because\n * the registry is built for more than two styles. Keyboard: arrows, Home and\n * End move, Enter or Space choose, Escape closes and returns to the button.\n */\nexport function StyleMenu({ value, options, onChange, placement }: StyleMenuProps) {\n const [open, setOpen] = React.useState(false);\n const [activeIndex, setActiveIndex] = React.useState(0);\n const wrapperRef = React.useRef<HTMLDivElement | null>(null);\n const buttonRef = React.useRef<HTMLButtonElement | null>(null);\n const itemRefs = React.useRef<(HTMLButtonElement | null)[]>([]);\n // useId, not a constant: several viewers can coexist on one page.\n const menuId = React.useId();\n\n usePopoverDismiss(open, wrapperRef, (reason) => {\n setOpen(false);\n if (reason === \"escape\") buttonRef.current?.focus();\n });\n\n // Opening moves focus to the checked item, as a radio menu does.\n React.useEffect(() => {\n if (!open) return;\n const index = Math.max(0, options.indexOf(value));\n setActiveIndex(index);\n itemRefs.current[index]?.focus();\n // Only on opening: choosing a style closes the menu anyway.\n }, [open]);\n\n const focusItem = (index: number) => {\n const count = options.length;\n const next = ((index % count) + count) % count;\n setActiveIndex(next);\n itemRefs.current[next]?.focus();\n };\n\n const onMenuKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n switch (event.key) {\n case \"ArrowDown\":\n event.preventDefault();\n focusItem(activeIndex + 1);\n break;\n case \"ArrowUp\":\n event.preventDefault();\n focusItem(activeIndex - 1);\n break;\n case \"Home\":\n event.preventDefault();\n focusItem(0);\n break;\n case \"End\":\n event.preventDefault();\n focusItem(options.length - 1);\n break;\n case \"Tab\":\n setOpen(false);\n break;\n default:\n break;\n }\n };\n\n const choose = (style: GraphStyleId) => {\n setOpen(false);\n buttonRef.current?.focus();\n if (style !== value) onChange(style);\n };\n\n const label = styleMenuLabel(value);\n return (\n <div className=\"graph-toolbar-style\" ref={wrapperRef}>\n <button\n ref={buttonRef}\n type=\"button\"\n className={`graph-toolbar-btn${open ? \" graph-toolbar-btn--open\" : \"\"}`}\n onClick={() => setOpen(!open)}\n onKeyDown={(event) => {\n if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n setOpen(true);\n }\n }}\n title={label}\n aria-label={label}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-controls={open ? menuId : undefined}\n >\n {graphStyleIcon(value)}\n </button>\n {open && (\n <div\n id={menuId}\n role=\"menu\"\n aria-label=\"Graph style\"\n className={`graph-style-menu graph-style-menu--${placement}`}\n onKeyDown={onMenuKeyDown}\n >\n {options.map((style, index) => {\n const descriptor = GRAPH_STYLES[style];\n const checked = style === value;\n return (\n <button\n key={style}\n ref={(el) => {\n itemRefs.current[index] = el;\n }}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={checked}\n tabIndex={index === activeIndex ? 0 : -1}\n className={`graph-style-menu-item${checked ? \" graph-style-menu-item--checked\" : \"\"}`}\n onClick={() => choose(style)}\n >\n <span className=\"graph-style-menu-icon\" aria-hidden=\"true\">\n {graphStyleIcon(style)}\n </span>\n <span className=\"graph-style-menu-text\">\n <span className=\"graph-style-menu-name\">{descriptor.name}</span>\n <span className=\"graph-style-menu-description\">{descriptor.description}</span>\n </span>\n <span className=\"graph-style-menu-check\" aria-hidden=\"true\">\n {checked ? CHECK_ICON : null}\n </span>\n </button>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n","import React from \"react\";\n\n/** Why an open popover asked to close: a press outside it, or the Escape key. */\nexport type PopoverDismissReason = \"outside\" | \"escape\";\n\n/**\n * Close a toolbar popover (the validation dropdown, the style menu) on a press\n * outside its wrapper or on Escape, while it is open. The listeners live on the\n * document only while `open` is true. `onDismiss` may change between renders\n * without re-registering them.\n *\n * The press is heard in the capture phase: the graph's pane handles its own\n * presses for panning and stops them there, so a listener waiting for them to\n * bubble to the document never hears a press on the canvas, the most common\n * place to click away from a popover.\n */\nexport function usePopoverDismiss(\n open: boolean,\n wrapperRef: React.RefObject<HTMLElement | null>,\n onDismiss: (reason: PopoverDismissReason) => void,\n): void {\n const onDismissRef = React.useRef(onDismiss);\n onDismissRef.current = onDismiss;\n React.useEffect(() => {\n if (!open) return;\n const onPointerDown = (event: PointerEvent) => {\n const wrapper = wrapperRef.current;\n if (wrapper && event.target instanceof Node && !wrapper.contains(event.target)) {\n onDismissRef.current(\"outside\");\n }\n };\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") onDismissRef.current(\"escape\");\n };\n document.addEventListener(\"pointerdown\", onPointerDown, true);\n document.addEventListener(\"keydown\", onKeyDown);\n return () => {\n document.removeEventListener(\"pointerdown\", onPointerDown, true);\n document.removeEventListener(\"keydown\", onKeyDown);\n };\n }, [open, wrapperRef]);\n}\n","import React from \"react\";\nimport type { NodeValidationSummary } from \"@graph/types\";\n\n/**\n * Corner count badge for a node's validation decoration, shared by pipe cards\n * and controller groups. The tooltip lists every issue's message (and `Fix: …`\n * line). Renders a button when `onClick` is set (opens the validation panel),\n * a plain span otherwise.\n */\nexport function NodeValidationBadge({\n validation,\n onClick,\n}: {\n validation: NodeValidationSummary;\n onClick?: () => void;\n}) {\n const label = `${validation.count} validation ${validation.count === 1 ? \"issue\" : \"issues\"}`;\n const tooltip = validation.lines.join(\"\\n\");\n const className = `node-validation-badge node-validation-badge--${validation.severity}`;\n const text = validation.count > 99 ? \"99+\" : String(validation.count);\n if (!onClick) {\n return (\n <span className={className} title={tooltip} aria-label={label}>\n {text}\n </span>\n );\n }\n return (\n <button\n type=\"button\"\n className={className}\n title={tooltip}\n aria-label={`${label} — open validation panel`}\n onClick={(e) => {\n e.stopPropagation();\n onClick();\n }}\n >\n {text}\n </button>\n );\n}\n\n/** Ring modifier class for a decorated node root (empty string when undecorated). */\nexport function validationRingClass(validation: NodeValidationSummary | undefined): string {\n return validation ? ` node-validation-ring--${validation.severity}` : \"\";\n}\n","import React from \"react\";\nimport type { FoldToggleOptions, NodeValidationSummary, PipeControllerType } from \"@graph/types\";\nimport { MAX_VISIBLE_CONTROLLER_CHILDREN } from \"@graph/graphControllers\";\nimport { NodeValidationBadge, validationRingClass } from \"../NodeValidationBadge\";\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 validation?: NodeValidationSummary;\n onValidationBadgeClick?: () => 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}${validationRingClass(data.validation)}`}>\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 {data.validation && (\n <NodeValidationBadge validation={data.validation} onClick={data.onValidationBadgeClick} />\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 { GraphNodeData } from \"@graph/types\";\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: GraphNodeData;\n sourcePosition?: Position;\n targetPosition?: Position;\n}) {\n const payload = data.pipeCardData;\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 { NodePipeType, PipeCardData, PipeControllerType, PipeStatus } from \"./pipeCardTypes\";\nimport { BINDING_STEP_TYPE } from \"@graph/types\";\nimport { NodeValidationBadge, validationRingClass } from \"../NodeValidationBadge\";\n\n// ─── Pipe type badge labels ──────────────────────────────────────────────\n\nconst PIPE_TYPE_BADGES: Record<NodePipeType, string> = {\n PipeLLM: \"LLM\",\n PipeExtract: \"Extract\",\n PipeCompose: \"Compose\",\n PipeImgGen: \"ImgGen\",\n PipeSearch: \"Search\",\n PipeFunc: \"Func\",\n PipeStructure: \"Structure\",\n PipeJudge: \"Judge\",\n PipeDocGen: \"DocGen\",\n PipeSignature: \"Signature\",\n PipeSequence: \"Sequence\",\n PipeParallel: \"Parallel\",\n PipeCondition: \"Condition\",\n PipeBatch: \"Batch\",\n BindingStep: \"Binding\",\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: NodePipeType): 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 canceled: { color: \"#6272a4\", label: \"Canceled\" },\n};\n\nconst MAX_VISIBLE_INPUTS = 4;\n\nfunction getBadge(pipeType: NodePipeType): 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];\n const isRunning = data.status === \"running\";\n const isController = isControllerType(data.pipeType);\n const isSignature = data.pipeType === \"PipeSignature\";\n // A binding step runs no pipe: its card names the path it binds, and reads as data plumbing.\n const isBinding = data.pipeType === BINDING_STEP_TYPE;\n const isStatic = data.graphMode === \"static\";\n const outcome = isStatic ? data.tags?.outcome : undefined;\n const batchMultiplicity = isStatic ? data.tags?.batch_multiplicity : undefined;\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 signatureClass = isSignature ? \" pipe-card--signature\" : \"\";\n const bindingClass = isBinding ? \" pipe-card--binding\" : \"\";\n const staticClass = isStatic ? \" pipe-card--static\" : \"\";\n const badgeClass = isController\n ? \"pipe-card-badge pipe-card-badge--controller\"\n : isSignature\n ? \"pipe-card-badge pipe-card-badge--signature\"\n : isBinding\n ? \"pipe-card-badge pipe-card-badge--binding\"\n : \"pipe-card-badge\";\n\n const ringClass = validationRingClass(data.validation);\n\n return (\n <div\n className={`pipe-card ${dirClass}${controllerClass}${signatureClass}${bindingClass}${staticClass}${ringClass}`}\n >\n {/* Header: badge + (document format) + pipe code + status + (optional) expand + validation */}\n <div className=\"pipe-card-header\">\n <span className={badgeClass}>{badge}</span>\n {/* A document step's format is part of what the step is, so it sits with\n its type rather than in the annotation row, and in every mode. */}\n {data.docGenFormat && (\n <span className=\"pipe-card-format\" title={`Document format: ${data.docGenFormat}`}>\n {data.docGenFormat.toUpperCase()}\n </span>\n )}\n <span className=\"pipe-card-code\" title={data.pipeCode}>\n {data.pipeCode}\n </span>\n {!isStatic && (\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 )}\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 {data.validation && (\n <NodeValidationBadge validation={data.validation} onClick={data.onValidationBadgeClick} />\n )}\n </div>\n\n {(outcome || batchMultiplicity) && (\n <div className=\"pipe-card-annotations\">\n {outcome && (\n <span className=\"pipe-card-annotation pipe-card-annotation--outcome\">\n outcome: {outcome}\n </span>\n )}\n {batchMultiplicity && (\n <span className=\"pipe-card-annotation pipe-card-annotation--batch\">\n {batchMultiplicity}\n </span>\n )}\n </div>\n )}\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 { NodePipeType } from \"./pipeCardTypes\";\nimport type { PipeCardBaseProps } from \"./PipeCardBase\";\nimport { PipeCardBase } from \"./PipeCardBase\";\n\n/**\n * Registry mapping pipe type → card component, the binding step included.\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<NodePipeType, ComponentType<PipeCardBaseProps>> = {\n PipeLLM: PipeCardBase,\n PipeExtract: PipeCardBase,\n PipeCompose: PipeCardBase,\n PipeImgGen: PipeCardBase,\n PipeSearch: PipeCardBase,\n PipeFunc: PipeCardBase,\n PipeStructure: PipeCardBase,\n PipeJudge: PipeCardBase,\n PipeDocGen: PipeCardBase,\n PipeSignature: PipeCardBase,\n PipeSequence: PipeCardBase,\n PipeParallel: PipeCardBase,\n PipeCondition: PipeCardBase,\n PipeBatch: PipeCardBase,\n BindingStep: PipeCardBase,\n};\n\nexport function getPipeCardComponent(pipeType: NodePipeType): ComponentType<PipeCardBaseProps> {\n return PIPE_CARD_REGISTRY[pipeType];\n}\n","import React from \"react\";\nimport { Handle, Position } from \"@xyflow/react\";\nimport type {\n GraphNodeData,\n NodeValidationSummary,\n PipeStatus,\n SimpleNodePayload,\n StepCategory,\n} from \"@graph/types\";\nimport {\n NODE_TYPE_SIMPLE_DECISION,\n NODE_TYPE_SIMPLE_FRAME,\n NODE_TYPE_SIMPLE_STEP,\n NODE_TYPE_SIMPLE_TERMINAL,\n} from \"@graph/types\";\nimport { STEP_CATEGORY_WORDS } from \"@graph/styles/simpleStyle\";\nimport { NodeValidationBadge, validationRingClass } from \"../../nodes/NodeValidationBadge\";\n\n// ─── Icons ──────────────────────────────────────────────────────────────────\n\nconst ICON_PROPS = {\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\" as const,\n strokeLinejoin: \"round\" as const,\n \"aria-hidden\": true,\n};\n\nfunction Icon({ size = 13, children }: { size?: number; children: React.ReactNode }) {\n return (\n <svg {...ICON_PROPS} width={size} height={size}>\n {children}\n </svg>\n );\n}\n\n/** Each category's icon. Keyed by `StepCategory`, so a new category does not compile without one. */\nconst CATEGORY_ICONS: Record<StepCategory, React.ReactNode> = {\n ai: (\n <>\n <path d=\"M9.94 15.5a2 2 0 0 0-1.44-1.44l-6.13-1.58a.5.5 0 0 1 0-.96L8.5 9.94A2 2 0 0 0 9.94 8.5l1.58-6.14a.5.5 0 0 1 .96 0l1.58 6.14a2 2 0 0 0 1.44 1.44l6.14 1.58a.5.5 0 0 1 0 .96l-6.14 1.58a2 2 0 0 0-1.44 1.44l-1.58 6.13a.5.5 0 0 1-.96 0z\" />\n <path d=\"M20 3v4\" />\n <path d=\"M22 5h-4\" />\n </>\n ),\n extract: (\n <>\n <path d=\"M3 7V5a2 2 0 0 1 2-2h2\" />\n <path d=\"M17 3h2a2 2 0 0 1 2 2v2\" />\n <path d=\"M21 17v2a2 2 0 0 1-2 2h-2\" />\n <path d=\"M7 21H5a2 2 0 0 1-2-2v-2\" />\n <path d=\"M7 8h8\" />\n <path d=\"M7 12h10\" />\n <path d=\"M7 16h6\" />\n </>\n ),\n image: (\n <>\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" />\n <circle cx=\"9\" cy=\"9\" r=\"2\" />\n <path d=\"m21 15-3.09-3.09a2 2 0 0 0-2.82 0L6 21\" />\n </>\n ),\n search: (\n <>\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <path d=\"m21 21-4.3-4.3\" />\n </>\n ),\n code: (\n <>\n <polyline points=\"16 18 22 12 16 6\" />\n <polyline points=\"8 6 2 12 8 18\" />\n </>\n ),\n template: (\n <>\n <path d=\"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\" />\n <path d=\"M14 2v4a2 2 0 0 0 2 2h4\" />\n <path d=\"M16 13H8\" />\n <path d=\"M16 17H8\" />\n </>\n ),\n document: (\n <>\n <path d=\"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\" />\n <path d=\"M14 2v4a2 2 0 0 0 2 2h4\" />\n <path d=\"M12 18v-6\" />\n <path d=\"m9 15 3 3 3-3\" />\n </>\n ),\n judge: (\n <>\n <path d=\"m16 16 3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1Z\" />\n <path d=\"m2 16 3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1Z\" />\n <path d=\"M7 21h10\" />\n <path d=\"M12 3v18\" />\n <path d=\"M3 7h2c2 0 5-1 7-2 2 1 5 2 7 2h2\" />\n </>\n ),\n planned: <circle cx=\"12\" cy=\"12\" r=\"9\" strokeDasharray=\"3 3\" />,\n steps: (\n <>\n <path d=\"m12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83Z\" />\n <path d=\"m22 17.65-9.17 4.16a2 2 0 0 1-1.66 0L2 17.65\" />\n <path d=\"m22 12.65-9.17 4.16a2 2 0 0 1-1.66 0L2 12.65\" />\n </>\n ),\n parallel: (\n <>\n <path d=\"M16 3h5v5\" />\n <path d=\"M8 3H3v5\" />\n <path d=\"M12 22v-8.3a4 4 0 0 0-1.17-2.87L3 3\" />\n <path d=\"m15 9 6-6\" />\n </>\n ),\n decision: <path d=\"M12 2 22 12 12 22 2 12Z\" />,\n repeat: (\n <>\n <path d=\"m17 2 4 4-4 4\" />\n <path d=\"M3 11v-1a4 4 0 0 1 4-4h14\" />\n <path d=\"m7 22-4-4 4-4\" />\n <path d=\"M21 13v1a4 4 0 0 1-4 4H3\" />\n </>\n ),\n pick: (\n <>\n <polyline points=\"15 10 20 15 15 20\" />\n <path d=\"M4 4v7a4 4 0 0 0 4 4h12\" />\n </>\n ),\n};\n\nconst EXPAND_ICON = (\n <Icon size={12}>\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 </Icon>\n);\n\nconst COLLAPSE_ICON = (\n <Icon size={12}>\n <polyline points=\"4 14 10 14 10 20\" />\n <polyline points=\"20 10 14 10 14 4\" />\n <line x1=\"14\" y1=\"10\" x2=\"21\" y2=\"3\" />\n <line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\" />\n </Icon>\n);\n\n// ─── Run status ─────────────────────────────────────────────────────────────\n\nconst STATUS_LABELS: Record<PipeStatus, string> = {\n succeeded: \"Done\",\n failed: \"Failed\",\n running: \"Running\",\n scheduled: \"Waiting\",\n skipped: \"Skipped\",\n canceled: \"Canceled\",\n};\n\nconst STATUS_ICONS: Record<PipeStatus, React.ReactNode> = {\n succeeded: <polyline points=\"20 6 9 17 4 12\" />,\n failed: (\n <>\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </>\n ),\n running: <path d=\"M21 12a9 9 0 1 1-6.22-8.56\" />,\n scheduled: <circle cx=\"12\" cy=\"12\" r=\"8\" />,\n skipped: <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />,\n canceled: <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />,\n};\n\n/** The run status mark a step shows once the method has run; nothing in a static graph. */\nfunction StatusMark({ status, graphMode }: { status: PipeStatus; graphMode?: string }) {\n if (graphMode === \"static\") return null;\n return (\n <span\n className={`simple-status simple-status--${status}`}\n title={STATUS_LABELS[status]}\n aria-label={STATUS_LABELS[status]}\n >\n <Icon size={11}>{STATUS_ICONS[status]}</Icon>\n </span>\n );\n}\n\n// ─── Shared wrapper pieces ──────────────────────────────────────────────────\n\ninterface SimpleRFNodeProps {\n data: GraphNodeData;\n sourcePosition?: Position;\n targetPosition?: Position;\n}\n\nfunction Handles({\n sourcePosition = Position.Right,\n targetPosition = Position.Left,\n children,\n}: {\n sourcePosition?: Position;\n targetPosition?: Position;\n children: React.ReactNode;\n}) {\n return (\n <>\n <Handle type=\"target\" position={targetPosition} className=\"simple-handle\" />\n {children}\n <Handle type=\"source\" position={sourcePosition} className=\"simple-handle\" />\n </>\n );\n}\n\nfunction ValidationMark({\n validation,\n onClick,\n}: {\n validation?: NodeValidationSummary;\n onClick?: () => void;\n}) {\n return validation ? <NodeValidationBadge validation={validation} onClick={onClick} /> : null;\n}\n\nfunction payloadOf<K extends SimpleNodePayload[\"kind\"]>(\n data: GraphNodeData,\n kinds: readonly K[],\n): Extract<SimpleNodePayload, { kind: K }> | null {\n const simple = data.simple;\n if (!simple || !(kinds as readonly string[]).includes(simple.kind)) return null;\n return simple as Extract<SimpleNodePayload, { kind: K }>;\n}\n\n// ─── Step ───────────────────────────────────────────────────────────────────\n\n/** A step: what the pipe does, in its author's words, with a plain category word. */\nexport function SimpleStepNode({ data, sourcePosition, targetPosition }: SimpleRFNodeProps) {\n const step = payloadOf(data, [\"step\"] as const);\n if (!step) return null;\n const statusClass = step.graphMode !== \"static\" ? ` simple-step--${step.status}` : \"\";\n return (\n <Handles sourcePosition={sourcePosition} targetPosition={targetPosition}>\n <div\n className={`simple-step simple-step--${step.category}${statusClass}${validationRingClass(data.validation)}`}\n >\n <div className=\"simple-step-header\">\n <span className=\"simple-step-category\">\n <Icon>{CATEGORY_ICONS[step.category]}</Icon>\n {STEP_CATEGORY_WORDS[step.category]}\n </span>\n <StatusMark status={step.status} graphMode={step.graphMode} />\n <ValidationMark validation={data.validation} onClick={data.onValidationBadgeClick} />\n </div>\n <div\n className=\"simple-step-title\"\n title={step.title}\n style={{\n fontSize: step.titleFit.fontPx,\n lineHeight: `${step.titleFit.lineHeightPx}px`,\n WebkitLineClamp: step.titleFit.maxLines,\n }}\n >\n {step.title}\n </div>\n {step.forEach && (\n <span className=\"simple-step-foreach\">\n <Icon size={11}>{CATEGORY_ICONS.repeat}</Icon>\n {step.forEach}\n </span>\n )}\n {step.innerStepCount !== undefined && (\n <button\n type=\"button\"\n className=\"simple-step-open\"\n title=\"Show the steps inside (alt/option: only this one)\"\n onClick={(event) => {\n event.stopPropagation();\n step.onExpand?.({ soloMode: event.altKey });\n }}\n disabled={!step.onExpand}\n >\n {EXPAND_ICON}\n {step.innerStepCount === 1 ? \"1 step inside\" : `${step.innerStepCount} steps inside`}\n </button>\n )}\n </div>\n </Handles>\n );\n}\n\n// ─── Input and output ───────────────────────────────────────────────────────\n\n/** The document shape's outline: a page whose foot is a wave. Stretched to the node. */\nconst DOCUMENT_PATH = \"M1 1 H99 V84 C80 98 62 74 44 86 C28 96 14 96 1 88 Z\";\n\nfunction DocumentShape({ className }: { className: string }) {\n return (\n <svg className={className} viewBox=\"0 0 100 100\" preserveAspectRatio=\"none\" aria-hidden=\"true\">\n <path d={DOCUMENT_PATH} vectorEffect=\"non-scaling-stroke\" />\n </svg>\n );\n}\n\n/** A method input or final output: a document, stacked when it is a list. */\nexport function SimpleTerminalNode({ data, sourcePosition, targetPosition }: SimpleRFNodeProps) {\n const terminal = payloadOf(data, [\"input\", \"output\"] as const);\n if (!terminal) return null;\n return (\n <Handles sourcePosition={sourcePosition} targetPosition={targetPosition}>\n <div\n className={`simple-terminal simple-terminal--${terminal.kind}${terminal.isList ? \" simple-terminal--list\" : \"\"}`}\n >\n {terminal.isList && (\n <>\n <DocumentShape className=\"simple-terminal-shape simple-terminal-shape--back2\" />\n <DocumentShape className=\"simple-terminal-shape simple-terminal-shape--back1\" />\n </>\n )}\n <DocumentShape className=\"simple-terminal-shape\" />\n <div className=\"simple-terminal-text\">\n <span className=\"simple-terminal-title\" title={terminal.title}>\n {terminal.title}\n </span>\n {terminal.subtitle && (\n <span className=\"simple-terminal-subtitle\">{terminal.subtitle}</span>\n )}\n </div>\n </div>\n </Handles>\n );\n}\n\n// ─── Decision ───────────────────────────────────────────────────────────────\n\n/** A decision: a diamond carrying what the condition decides; its arrows carry the outcomes. */\nexport function SimpleDecisionNode({ data, sourcePosition, targetPosition }: SimpleRFNodeProps) {\n const decision = payloadOf(data, [\"decision\"] as const);\n if (!decision) return null;\n const statusClass = decision.graphMode !== \"static\" ? ` simple-decision--${decision.status}` : \"\";\n return (\n <Handles sourcePosition={sourcePosition} targetPosition={targetPosition}>\n <div className={`simple-decision${statusClass}${validationRingClass(data.validation)}`}>\n <svg\n className=\"simple-decision-shape\"\n viewBox=\"0 0 100 100\"\n preserveAspectRatio=\"none\"\n aria-hidden=\"true\"\n >\n <path d=\"M50 1 L99 50 L50 99 L1 50 Z\" vectorEffect=\"non-scaling-stroke\" />\n </svg>\n <div className=\"simple-decision-text\" title={decision.title}>\n {decision.title}\n </div>\n <div className=\"simple-decision-marks\">\n <StatusMark status={decision.status} graphMode={decision.graphMode} />\n <ValidationMark validation={data.validation} onClick={data.onValidationBadgeClick} />\n </div>\n </div>\n </Handles>\n );\n}\n\n// ─── \"For each\" frame ───────────────────────────────────────────────────────\n\n/** A batch whose branch has several steps: a light frame saying \"for each\", with a stack behind it. */\nexport function SimpleFrameNode({ data }: { data: GraphNodeData }) {\n const frame = payloadOf(data, [\"frame\"] as const);\n if (!frame) return null;\n return (\n <div className={`simple-frame${validationRingClass(data.validation)}`}>\n <div className=\"simple-frame-header\">\n <span className=\"simple-frame-title\">\n <Icon size={12}>{CATEGORY_ICONS.repeat}</Icon>\n {frame.title}\n </span>\n <StatusMark status={frame.status} graphMode={frame.graphMode} />\n <ValidationMark validation={data.validation} onClick={data.onValidationBadgeClick} />\n {frame.onFold && (\n <button\n type=\"button\"\n className=\"simple-frame-fold\"\n title=\"Fold into one step (alt/option: only this one)\"\n aria-label=\"Fold into one step\"\n onClick={(event) => {\n event.stopPropagation();\n frame.onFold?.({ soloMode: event.altKey });\n }}\n >\n {COLLAPSE_ICON}\n </button>\n )}\n </div>\n </div>\n );\n}\n\n// Stable reference — registered once in GraphViewer's module-level node types.\nexport const simpleNodeTypes = {\n [NODE_TYPE_SIMPLE_STEP]: SimpleStepNode,\n [NODE_TYPE_SIMPLE_TERMINAL]: SimpleTerminalNode,\n [NODE_TYPE_SIMPLE_DECISION]: SimpleDecisionNode,\n [NODE_TYPE_SIMPLE_FRAME]: SimpleFrameNode,\n};\n","import { BaseEdge, getSmoothStepPath } from \"@xyflow/react\";\nimport type { Edge, EdgeProps } from \"@xyflow/react\";\nimport { fitRoute, roundedPolylinePath, routeLabelCenter } from \"@graph/edgeRoutes\";\nimport type { RoutedEdgeData } from \"@graph/react/rfTypes\";\n\n/**\n * An edge drawn along the route the layout computed (`EDGE_TYPE_ROUTED`), so\n * it bends around the nodes in its way instead of crossing them, with its\n * label in the box the layout reserved. Once a node is dragged away from where\n * the layout put it, the route no longer meets its handles, and the edge falls\n * back to a rounded step between them.\n */\nexport function RoutedEdge({\n id,\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourcePosition,\n targetPosition,\n data,\n label,\n labelStyle,\n labelShowBg,\n labelBgStyle,\n labelBgPadding,\n labelBgBorderRadius,\n style,\n markerEnd,\n markerStart,\n interactionWidth,\n}: EdgeProps<Edge<RoutedEdgeData>>) {\n const route = data?.route;\n const fitted = route\n ? fitRoute(route.points, { x: sourceX, y: sourceY }, { x: targetX, y: targetY })\n : null;\n\n let path: string;\n let labelX: number;\n let labelY: number;\n if (route && fitted) {\n path = roundedPolylinePath(fitted);\n ({ x: labelX, y: labelY } = routeLabelCenter(route, fitted));\n } else {\n [path, labelX, labelY] = getSmoothStepPath({\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourcePosition,\n targetPosition,\n borderRadius: 8,\n });\n }\n\n return (\n <BaseEdge\n id={id}\n path={path}\n labelX={labelX}\n labelY={labelY}\n label={label}\n labelStyle={labelStyle}\n labelShowBg={labelShowBg}\n labelBgStyle={labelBgStyle}\n labelBgPadding={labelBgPadding}\n labelBgBorderRadius={labelBgBorderRadius}\n style={style}\n markerEnd={markerEnd}\n markerStart={markerStart}\n interactionWidth={interactionWidth}\n />\n );\n}\n"],"mappings":"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","names":["React","React","React","jsx","jsxs","React","React","jsx","jsxs","_a","jsx","jsxs","jsx","jsxs","Fragment","jsx","jsxs","Fragment","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","jsx","jsxs","Fragment","jsx","jsxs","React","React","Fragment","jsx","jsxs","React","_a","jsx","jsxs","React","jsx","jsxs","React","React","jsx","jsxs","CHECK_ICON","React","Fragment","jsx","jsxs","jsxs","jsx","CHECK_ICON","React","Fragment","jsx","jsx","jsxs","_a","useState","jsx","jsxs","PIPE_TYPE_BADGES","useState","_a","Fragment","jsx","jsxs","Handle","Position","Fragment","jsx","jsxs","ICON_PROPS","EXPAND_ICON","COLLAPSE_ICON","Position","Handle","jsx","Fragment","jsx","jsxs","React","_a","_b","nodes","_c","graphspec"]}