@particle-academy/fancy-flow 0.54.0 → 0.56.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.
Files changed (53) hide show
  1. package/dist/{chunk-CIBW5ATA.js → chunk-22OJOD4X.js} +7 -3
  2. package/dist/chunk-22OJOD4X.js.map +1 -0
  3. package/dist/{chunk-VWANLNL5.js → chunk-E3AGYTHP.js} +3 -3
  4. package/dist/{chunk-VWANLNL5.js.map → chunk-E3AGYTHP.js.map} +1 -1
  5. package/dist/{chunk-FH6MWLKD.js → chunk-GB4A7DFM.js} +20 -5
  6. package/dist/chunk-GB4A7DFM.js.map +1 -0
  7. package/dist/{chunk-FTGVVKWX.js → chunk-HMEI2LFU.js} +4 -4
  8. package/dist/{chunk-FTGVVKWX.js.map → chunk-HMEI2LFU.js.map} +1 -1
  9. package/dist/{chunk-WCFRKXH5.js → chunk-KP4TBF3A.js} +3 -3
  10. package/dist/{chunk-WCFRKXH5.js.map → chunk-KP4TBF3A.js.map} +1 -1
  11. package/dist/{chunk-FG3C7LIG.js → chunk-L4QAAGLV.js} +3 -3
  12. package/dist/{chunk-FG3C7LIG.js.map → chunk-L4QAAGLV.js.map} +1 -1
  13. package/dist/durable/index.d.cts +1 -1
  14. package/dist/durable/index.d.ts +1 -1
  15. package/dist/durable.cjs +5 -1
  16. package/dist/durable.cjs.map +1 -1
  17. package/dist/durable.js +1 -1
  18. package/dist/engine.cjs +5 -1
  19. package/dist/engine.cjs.map +1 -1
  20. package/dist/engine.d.cts +2 -2
  21. package/dist/engine.d.ts +2 -2
  22. package/dist/engine.js +3 -3
  23. package/dist/index.cjs +22 -3
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.cts +2 -2
  26. package/dist/index.d.ts +2 -2
  27. package/dist/index.js +11 -11
  28. package/dist/registry.cjs +5 -1
  29. package/dist/registry.cjs.map +1 -1
  30. package/dist/registry.js +2 -2
  31. package/dist/{run-cohort-BPIOpE8A.d.ts → run-cohort-C1nRh_mi.d.ts} +1 -1
  32. package/dist/{run-cohort-r-L8dMED.d.cts → run-cohort-CBRAUj-z.d.cts} +1 -1
  33. package/dist/{run-flow-COdAOFg2.d.cts → run-flow-2XsHBwpd.d.cts} +31 -0
  34. package/dist/{run-flow-DJ7KYT6E.d.ts → run-flow-D7AOCcfE.d.ts} +31 -0
  35. package/dist/runtime/index.d.cts +3 -3
  36. package/dist/runtime/index.d.ts +3 -3
  37. package/dist/runtime.cjs +5 -1
  38. package/dist/runtime.cjs.map +1 -1
  39. package/dist/runtime.js +3 -3
  40. package/dist/schema/index.d.cts +29 -5
  41. package/dist/schema/index.d.ts +29 -5
  42. package/dist/schema.cjs +22 -3
  43. package/dist/schema.cjs.map +1 -1
  44. package/dist/schema.js +2 -2
  45. package/dist/screens.cjs +5 -1
  46. package/dist/screens.cjs.map +1 -1
  47. package/dist/screens.js +4 -4
  48. package/dist/ux.cjs +5 -1
  49. package/dist/ux.cjs.map +1 -1
  50. package/dist/ux.js +1 -1
  51. package/package.json +2 -2
  52. package/dist/chunk-CIBW5ATA.js.map +0 -1
  53. package/dist/chunk-FH6MWLKD.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { getNodeKind, categoryAccent, resolveNodePorts, nodeConfig, NodeResizer, NodeToolbar, Handle, Position, listNodeKinds, kindIds } from './chunk-CIBW5ATA.js';
1
+ import { getNodeKind, categoryAccent, resolveNodePorts, nodeConfig, NodeResizer, NodeToolbar, Handle, Position, listNodeKinds, kindIds } from './chunk-22OJOD4X.js';
2
2
  import { memo, useMemo } from 'react';
3
3
  import { jsxs, jsx } from 'react/jsx-runtime';
4
4
 
@@ -192,5 +192,5 @@ function buildNodeTypes() {
192
192
  }
193
193
 
194
194
  export { ANY_PORT_TYPE, RegistryNode, buildNodeTypes, createConnectionValidator, defaultPortCompatibility };
195
- //# sourceMappingURL=chunk-VWANLNL5.js.map
196
- //# sourceMappingURL=chunk-VWANLNL5.js.map
195
+ //# sourceMappingURL=chunk-E3AGYTHP.js.map
196
+ //# sourceMappingURL=chunk-E3AGYTHP.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/registry/connection.ts","../src/registry/RegistryNode.tsx","../src/registry/index.ts"],"names":[],"mappings":"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","file":"chunk-VWANLNL5.js","sourcesContent":["import type { Connection, Edge } from \"@xyflow/react\";\nimport type { FlowNode, PortDescriptor } from \"../types\";\nimport { getNodeKind } from \"./registry\";\nimport { resolveNodePorts } from \"./ports\";\n\n/**\n * Connection validation — the single rule that decides whether an edge between\n * two ports is allowed. Lives here (React-free, registry-adjacent) so BOTH the\n * canvas (`<FlowCanvas isValidConnection>`) and the agent bridge's\n * `flow_connect` tool call the same function: a connection the canvas refuses\n * is a connection an agent cannot sneak past, and vice versa — no drift.\n *\n * `PortDescriptor.type` has always documented itself as being \"for hosts that\n * want to validate connections\", but nothing consumed it. This wires it up.\n */\n\n/**\n * Wildcard port type — matches any other type. A port that declares no `type`\n * is treated as a wildcard too, so existing flows (whose ports are untyped)\n * validate exactly as before.\n */\nexport const ANY_PORT_TYPE = \"any\";\n\n/** Decides whether a source-output port may feed a target-input port. */\nexport type PortCompatibility = (\n source: PortDescriptor | undefined,\n target: PortDescriptor | undefined,\n) => boolean;\n\n/**\n * Default compatibility rule: allow the connection UNLESS both ports declare a\n * concrete, differing type. An absent type or the `any` wildcard matches\n * anything — so typed ports get enforced while untyped ports stay permissive,\n * making this a safe default that never breaks an existing untyped graph.\n */\nexport const defaultPortCompatibility: PortCompatibility = (source, target) => {\n const s = source?.type;\n const t = target?.type;\n if (!s || !t) return true;\n if (s === ANY_PORT_TYPE || t === ANY_PORT_TYPE) return true;\n return s === t;\n};\n\nexport type ConnectionValidatorOptions = {\n /** Override the type-compatibility rule. Defaults to {@link defaultPortCompatibility}. */\n compatible?: PortCompatibility;\n /**\n * Allow a node's own output to feed its own input (a self-loop). Default\n * false — self-connections are almost always an accident, and the rare flow\n * that wants one can opt in.\n */\n allowSelfConnection?: boolean;\n};\n\n/** Resolve a node's effective ports for one side, going through the registry. */\nfunction portsFor(node: FlowNode, side: \"inputs\" | \"outputs\"): PortDescriptor[] {\n const kind = getNodeKind((node.data as any)?.kind ?? node.type);\n const resolved = resolveNodePorts(node, kind ?? undefined);\n return resolved[side] ?? [];\n}\n\n/**\n * Resolve which port a handle id refers to. When a side has a single port and\n * the handle id is absent (React Flow omits it for a lone default handle), use\n * that port; otherwise match by id.\n */\nfunction findPort(\n ports: PortDescriptor[],\n handleId: string | null | undefined,\n): PortDescriptor | undefined {\n if (handleId == null) return ports.length === 1 ? ports[0] : undefined;\n return ports.find((p) => p.id === handleId);\n}\n\n/**\n * Build an `isValidConnection` predicate that enforces port-type compatibility\n * against a live node list. Pass it straight to `<FlowCanvas isValidConnection>`\n * or reuse it to gate an agent's `flow_connect`.\n *\n * `getNodes` is called on every check so the validator always sees the current\n * graph (wire it to a ref/state getter, not a snapshot).\n *\n * A connection is rejected when: an endpoint is missing; it is a self-loop and\n * `allowSelfConnection` is off; either node is unknown; or the resolved ports\n * are type-incompatible. Nodes/ports with no declared type validate as before.\n */\nexport function createConnectionValidator(\n getNodes: () => FlowNode[],\n options: ConnectionValidatorOptions = {},\n): (connection: Connection | Edge) => boolean {\n const compatible = options.compatible ?? defaultPortCompatibility;\n return (connection) => {\n const { source, target, sourceHandle, targetHandle } = connection;\n if (!source || !target) return false;\n if (!options.allowSelfConnection && source === target) return false;\n\n const nodes = getNodes();\n const src = nodes.find((n) => n.id === source);\n const tgt = nodes.find((n) => n.id === target);\n if (!src || !tgt) return false;\n\n const outPort = findPort(portsFor(src, \"outputs\"), sourceHandle);\n const inPort = findPort(portsFor(tgt, \"inputs\"), targetHandle);\n return compatible(outPort, inPort);\n };\n}\n","import { memo, useMemo } from \"react\";\nimport { Handle, NodeResizer, NodeToolbar, Position, type NodeProps } from \"@xyflow/react\";\nimport type { FlowNode, NodeRunStatus, PortDescriptor } from \"../types\";\nimport { categoryAccent, getNodeKind } from \"./registry\";\nimport { nodeConfig, resolveNodePorts } from \"./ports\";\n\n/**\n * RegistryNode — generic node renderer that looks up the node's kind in\n * the registry and applies its `accent`/`label`/`icon`/`renderBody`. Used\n * as the xyflow node component for every registered kind.\n */\nfunction RegistryNodeInner(props: NodeProps<FlowNode>) {\n const kindName = (props.data as any).kind ?? props.type;\n const kind = useMemo(() => getNodeKind(kindName), [kindName]);\n\n if (!kind) {\n return (\n <div className=\"ff-node ff-node--unknown\">\n <div className=\"ff-node__header\" style={{ background: \"#71717a\" }}>\n <span className=\"ff-node__tag\">UNKNOWN</span>\n <span className=\"ff-node__label\">{kindName}</span>\n </div>\n <p className=\"ff-node__desc\">No registered kind for \"{kindName}\".</p>\n </div>\n );\n }\n\n const data = props.data;\n const status: NodeRunStatus = data.status ?? \"idle\";\n const accent = kind.accent ?? categoryAccent(kind.category);\n const resolved = resolveNodePorts(props, kind);\n const inputs: PortDescriptor[] = resolved.inputs ?? defaultInputs(kind.category);\n const outputs: PortDescriptor[] = resolved.outputs ?? defaultOutputs(kind.category);\n const config = nodeConfig(props);\n const label = data.label ?? kind.label;\n\n return (\n <div\n className={[\n \"ff-node\",\n `ff-node--status-${status}`,\n `ff-node--cat-${kind.category}`,\n props.selected ? \"ff-node--selected\" : \"\",\n kind.resizable ? \"ff-node--resizable\" : \"\",\n ].filter(Boolean).join(\" \")}\n style={{ borderColor: props.selected ? accent : undefined }}\n >\n {kind.resizable && (\n <NodeResizer\n isVisible={props.selected ?? false}\n color={accent}\n {...(typeof kind.resizable === \"object\" ? kind.resizable : {})}\n />\n )}\n {kind.toolbar && (\n <NodeToolbar isVisible={props.selected ?? false}>\n {kind.toolbar({ nodeId: props.id, config: config as any, selected: props.selected ?? false })}\n </NodeToolbar>\n )}\n <header className=\"ff-node__header\" style={{ background: accent }}>\n {kind.icon && <span className=\"ff-node__icon\" aria-hidden>{kind.icon}</span>}\n <span className=\"ff-node__tag\">{kind.label.toUpperCase()}</span>\n <span className=\"ff-node__label\">{label}</span>\n {status !== \"idle\" && <span className={`ff-node__dot ff-node__dot--${status}`} aria-label={`status ${status}`} />}\n </header>\n\n {data.description && <p className=\"ff-node__desc\">{data.description}</p>}\n\n <div className=\"ff-node__body\">\n {kind.renderBody\n ? kind.renderBody({ nodeId: props.id, config: config as any, selected: props.selected ?? false })\n : <DefaultBody config={config} kind={kind.configSchema} />}\n </div>\n\n {data.statusText && <p className=\"ff-node__status-text\">{data.statusText}</p>}\n\n {(data as any).output !== undefined && (\n <p className=\"ff-node__output\" title=\"Latest output\">→ {previewValue((data as any).output)}</p>\n )}\n\n {inputs.map((p, i) => (\n <Handle\n key={p.id}\n type=\"target\"\n position={Position.Left}\n id={p.id}\n style={portStyle(i, inputs.length)}\n title={p.label ?? p.id}\n />\n ))}\n {outputs.map((p, i) => (\n <Handle\n key={p.id}\n type=\"source\"\n position={Position.Right}\n id={p.id}\n style={portStyle(i, outputs.length)}\n title={p.label ?? p.id}\n />\n ))}\n </div>\n );\n}\n\nexport const RegistryNode = memo(RegistryNodeInner);\n\nfunction defaultInputs(category: string): PortDescriptor[] {\n return category === \"trigger\" ? [] : [{ id: \"in\" }];\n}\nfunction defaultOutputs(category: string): PortDescriptor[] {\n return category === \"output\" ? [] : [{ id: \"out\" }];\n}\n\nfunction portStyle(i: number, total: number): React.CSSProperties {\n if (total <= 1) return {};\n const slot = (100 / (total + 1)) * (i + 1);\n return { top: `${slot}%` };\n}\n\n/**\n * DefaultBody — compact summary of the config values for nodes that\n * don't provide a custom renderBody. Skips fields that look empty.\n */\nfunction DefaultBody({ config, kind }: { config: Record<string, unknown>; kind?: import(\"./types\").ConfigField[] }) {\n const fields = kind ?? [];\n // A kind with no config schema has nothing to configure — don't nag with a\n // \"configure in the panel\" prompt (that's only for a kind that HAS fields but\n // none are filled in yet). Triggers, Output, etc. render as just their header.\n if (fields.length === 0) return null;\n const visible = fields\n .map((f) => ({ field: f, value: config[f.key] }))\n .filter(({ value }) => value !== undefined && value !== \"\" && value !== null);\n if (visible.length === 0) {\n return <div className=\"ff-node__body-empty\">— configure in the panel</div>;\n }\n return (\n <ul className=\"ff-node__summary\">\n {visible.slice(0, 4).map(({ field, value }) => (\n <li key={field.key}>\n <span className=\"ff-node__summary-key\">{field.label}:</span>\n <span className=\"ff-node__summary-value\">{previewValue(value)}</span>\n </li>\n ))}\n {visible.length > 4 && <li className=\"ff-node__summary-more\">+ {visible.length - 4} more</li>}\n </ul>\n );\n}\n\nconst truncate = (s: string, n = 30): string => (s.length > n ? s.slice(0, n - 1) + \"…\" : s);\n\n/** A short, human name for one item in a repeater/list value. */\nfunction itemLabel(item: unknown): string {\n if (item && typeof item === \"object\") {\n const o = item as Record<string, unknown>;\n const name = o.label ?? o.name ?? o.key ?? o.title ?? o.id;\n if (typeof name === \"string\" && name) return name;\n if (typeof name === \"number\") return String(name);\n return \"item\";\n }\n return String(item ?? \"\");\n}\n\n/**\n * A node card's job is to read at a glance, not to be a data dump — so a value\n * is summarised, never `JSON.stringify`d. An array becomes its item names (or a\n * count), an object becomes a field count. Raw JSON on a card was the specific\n * thing to kill: `Fields: [{\"key\":\"answer\",…}]` reads as noise.\n */\nexport function previewValue(v: unknown): string {\n if (v === null || v === undefined) return \"\";\n if (typeof v === \"string\") return truncate(v);\n if (typeof v === \"number\" || typeof v === \"boolean\") return String(v);\n if (Array.isArray(v)) {\n if (v.length === 0) return \"none\";\n const names = v.slice(0, 3).map(itemLabel).filter(Boolean).join(\", \");\n const rest = v.length > 3 ? `, +${v.length - 3}` : \"\";\n return names ? truncate(names + rest) : `${v.length} item${v.length === 1 ? \"\" : \"s\"}`;\n }\n if (typeof v === \"object\") {\n const keys = Object.keys(v as object);\n return keys.length === 0 ? \"empty\" : `${keys.length} field${keys.length === 1 ? \"\" : \"s\"}`;\n }\n return \"…\";\n}\n","export type {\n ConfigField,\n TextConfigField,\n TextareaConfigField,\n NumberConfigField,\n SelectConfigField,\n SwitchConfigField,\n JsonConfigField,\n ExpressionConfigField,\n CredentialConfigField,\n RepeaterConfigField,\n RepeaterRowField,\n KeyValueConfigField,\n DocumentConfigField,\n NodeCategory,\n NodeKindDefinition,\n PortSpec,\n RenderBodyContext,\n} from \"./types\";\n\nexport { resolvePortSpec, resolveNodePorts, nodeConfig } from \"./ports\";\n\nexport {\n createConnectionValidator,\n defaultPortCompatibility,\n ANY_PORT_TYPE,\n type PortCompatibility,\n type ConnectionValidatorOptions,\n} from \"./connection\";\n\n/** Host capabilities — core declares the contract, the host supplies the impl. */\nexport {\n registerLlmClient,\n getLlmClient,\n registerWorkflowResolver,\n getWorkflowResolver,\n capabilityStatus,\n type LlmClient,\n type LlmRoute,\n type LlmRouteRequest,\n type LlmRouteChoice,\n type WorkflowResolver,\n type WorkflowResolution,\n type WorkflowResolutionFailure,\n type CapabilityId,\n isResolutionFailure,\n} from \"./capabilities\";\n\n/**\n * The human-pause contract — a run waiting for a person, not a failure.\n * `decodePause` is the one function a durable runner needs.\n */\nexport {\n pauseForHuman,\n encodePause,\n decodePause,\n isPause,\n PAUSE_PREFIX,\n LEGACY_PAUSE_PREFIXES,\n type PauseAwaiting,\n type PauseSignal,\n} from \"./pause\";\n\nexport { subflowExecutor, subflowPorts, subflowMode, DEFAULT_MAX_DEPTH, type SubflowMode } from \"./subflow\";\nexport { llmRouterExecutor, declaredRoutes, resolveFallbackPort } from \"./llm-router\";\n/** @deprecated Renamed to `llmRouterExecutor` — the id and label now match. */\nexport { llmRouterExecutor as llmBranchExecutor } from \"./llm-router\";\n\nexport {\n registerRichInputAdapter,\n getRichInputAdapter,\n isRichInputEnabled,\n onRichInputAdapterChanged,\n RichInputPreview,\n type RichInputAdapter,\n} from \"./rich-input\";\n\nexport {\n registerNodeKind,\n overrideNodeKind,\n clearNodeKindOverrides,\n type NodeKindPresentation,\n getNodeKind,\n resolveKindId,\n kindIds,\n listNodeKinds,\n onNodeKindsChanged,\n defaultConfigFor,\n validateConfig,\n categoryAccent,\n} from \"./registry\";\n\nexport { RegistryNode } from \"./RegistryNode\";\nexport { registerBuiltinKinds, BUILTIN_KINDS } from \"./builtin\";\nexport { ensureBuiltinKinds } from \"./registry\";\n\nimport type { NodeTypes } from \"@xyflow/react\";\nimport { RegistryNode } from \"./RegistryNode\";\nimport { kindIds, listNodeKinds } from \"./registry\";\n\n/**\n * Build an xyflow `nodeTypes` map from the registry — every registered\n * kind gets `RegistryNode` as its renderer. Refresh manually via\n * `useNodeTypes()` (a hook that subscribes to registry changes).\n */\nexport function buildNodeTypes(): NodeTypes {\n const map: NodeTypes = {};\n for (const k of listNodeKinds()) {\n // A kind may bring its own full renderer (lanes/containers); otherwise the\n // default card. Key on every id the kind answers to, not just the canonical\n // one — xyflow looks the renderer up by `node.type` BEFORE RegistryNode gets\n // a chance to resolve aliases, so a graph carrying a pre-namespace type would\n // otherwise fall through to the unknown-node placeholder.\n const renderer = k.component ?? RegistryNode;\n for (const id of kindIds(k)) map[id] = renderer;\n }\n return map;\n}\n"]}
1
+ {"version":3,"sources":["../src/registry/connection.ts","../src/registry/RegistryNode.tsx","../src/registry/index.ts"],"names":[],"mappings":";;;;;AAqBO,IAAM,aAAA,GAAgB;AActB,IAAM,wBAAA,GAA8C,CAAC,MAAA,EAAQ,MAAA,KAAW;AAC7E,EAAA,MAAM,IAAI,MAAA,EAAQ,IAAA;AAClB,EAAA,MAAM,IAAI,MAAA,EAAQ,IAAA;AAClB,EAAA,IAAI,CAAC,CAAA,IAAK,CAAC,CAAA,EAAG,OAAO,IAAA;AACrB,EAAA,IAAI,CAAA,KAAM,aAAA,IAAiB,CAAA,KAAM,aAAA,EAAe,OAAO,IAAA;AACvD,EAAA,OAAO,CAAA,KAAM,CAAA;AACf;AAcA,SAAS,QAAA,CAAS,MAAgB,IAAA,EAA8C;AAC9E,EAAA,MAAM,OAAO,WAAA,CAAa,IAAA,CAAK,IAAA,EAAc,IAAA,IAAQ,KAAK,IAAI,CAAA;AAC9D,EAAA,MAAM,QAAA,GAAW,gBAAA,CAAiB,IAAA,EAAM,IAAA,IAAQ,MAAS,CAAA;AACzD,EAAA,OAAO,QAAA,CAAS,IAAI,CAAA,IAAK,EAAC;AAC5B;AAOA,SAAS,QAAA,CACP,OACA,QAAA,EAC4B;AAC5B,EAAA,IAAI,QAAA,IAAY,MAAM,OAAO,KAAA,CAAM,WAAW,CAAA,GAAI,KAAA,CAAM,CAAC,CAAA,GAAI,MAAA;AAC7D,EAAA,OAAO,MAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,QAAQ,CAAA;AAC5C;AAcO,SAAS,yBAAA,CACd,QAAA,EACA,OAAA,GAAsC,EAAC,EACK;AAC5C,EAAA,MAAM,UAAA,GAAa,QAAQ,UAAA,IAAc,wBAAA;AACzC,EAAA,OAAO,CAAC,UAAA,KAAe;AACrB,IAAA,MAAM,EAAE,MAAA,EAAQ,MAAA,EAAQ,YAAA,EAAc,cAAa,GAAI,UAAA;AACvD,IAAA,IAAI,CAAC,MAAA,IAAU,CAAC,MAAA,EAAQ,OAAO,KAAA;AAC/B,IAAA,IAAI,CAAC,OAAA,CAAQ,mBAAA,IAAuB,MAAA,KAAW,QAAQ,OAAO,KAAA;AAE9D,IAAA,MAAM,QAAQ,QAAA,EAAS;AACvB,IAAA,MAAM,MAAM,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,MAAM,CAAA;AAC7C,IAAA,MAAM,MAAM,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,MAAM,CAAA;AAC7C,IAAA,IAAI,CAAC,GAAA,IAAO,CAAC,GAAA,EAAK,OAAO,KAAA;AAEzB,IAAA,MAAM,UAAU,QAAA,CAAS,QAAA,CAAS,GAAA,EAAK,SAAS,GAAG,YAAY,CAAA;AAC/D,IAAA,MAAM,SAAS,QAAA,CAAS,QAAA,CAAS,GAAA,EAAK,QAAQ,GAAG,YAAY,CAAA;AAC7D,IAAA,OAAO,UAAA,CAAW,SAAS,MAAM,CAAA;AAAA,EACnC,CAAA;AACF;AC9FA,SAAS,kBAAkB,KAAA,EAA4B;AACrD,EAAA,MAAM,QAAA,GAAY,KAAA,CAAM,IAAA,CAAa,IAAA,IAAQ,KAAA,CAAM,IAAA;AACnD,EAAA,MAAM,IAAA,GAAO,QAAQ,MAAM,WAAA,CAAY,QAAQ,CAAA,EAAG,CAAC,QAAQ,CAAC,CAAA;AAE5D,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,0BAAA,EACb,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,SAAI,SAAA,EAAU,iBAAA,EAAkB,OAAO,EAAE,UAAA,EAAY,WAAU,EAC9D,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,cAAA,EAAe,QAAA,EAAA,SAAA,EAAO,CAAA;AAAA,wBACtC,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,gBAAA,EAAkB,QAAA,EAAA,QAAA,EAAS;AAAA,OAAA,EAC7C,CAAA;AAAA,sBACA,IAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,eAAA,EAAgB,QAAA,EAAA;AAAA,QAAA,0BAAA;AAAA,QAAyB,QAAA;AAAA,QAAS;AAAA,OAAA,EAAE;AAAA,KAAA,EACnE,CAAA;AAAA,EAEJ;AAEA,EAAA,MAAM,OAAO,KAAA,CAAM,IAAA;AACnB,EAAA,MAAM,MAAA,GAAwB,KAAK,MAAA,IAAU,MAAA;AAC7C,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,IAAU,cAAA,CAAe,KAAK,QAAQ,CAAA;AAC1D,EAAA,MAAM,QAAA,GAAW,gBAAA,CAAiB,KAAA,EAAO,IAAI,CAAA;AAC7C,EAAA,MAAM,MAAA,GAA2B,QAAA,CAAS,MAAA,IAAU,aAAA,CAAc,KAAK,QAAQ,CAAA;AAC/E,EAAA,MAAM,OAAA,GAA4B,QAAA,CAAS,OAAA,IAAW,cAAA,CAAe,KAAK,QAAQ,CAAA;AAClF,EAAA,MAAM,MAAA,GAAS,WAAW,KAAK,CAAA;AAC/B,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,IAAS,IAAA,CAAK,KAAA;AAEjC,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW;AAAA,QACT,SAAA;AAAA,QACA,mBAAmB,MAAM,CAAA,CAAA;AAAA,QACzB,CAAA,aAAA,EAAgB,KAAK,QAAQ,CAAA,CAAA;AAAA,QAC7B,KAAA,CAAM,WAAW,mBAAA,GAAsB,EAAA;AAAA,QACvC,IAAA,CAAK,YAAY,oBAAA,GAAuB;AAAA,OAC1C,CAAE,MAAA,CAAO,OAAO,CAAA,CAAE,KAAK,GAAG,CAAA;AAAA,MAC1B,OAAO,EAAE,WAAA,EAAa,KAAA,CAAM,QAAA,GAAW,SAAS,MAAA,EAAU;AAAA,MAEzD,QAAA,EAAA;AAAA,QAAA,IAAA,CAAK,SAAA,oBACJ,GAAA;AAAA,UAAC,WAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAW,MAAM,QAAA,IAAY,KAAA;AAAA,YAC7B,KAAA,EAAO,MAAA;AAAA,YACN,GAAI,OAAO,IAAA,CAAK,cAAc,QAAA,GAAW,IAAA,CAAK,YAAY;AAAC;AAAA,SAC9D;AAAA,QAED,IAAA,CAAK,2BACJ,GAAA,CAAC,WAAA,EAAA,EAAY,WAAW,KAAA,CAAM,QAAA,IAAY,OACvC,QAAA,EAAA,IAAA,CAAK,OAAA,CAAQ,EAAE,MAAA,EAAQ,KAAA,CAAM,IAAI,MAAA,EAAuB,QAAA,EAAU,MAAM,QAAA,IAAY,KAAA,EAAO,CAAA,EAC9F,CAAA;AAAA,wBAEF,IAAA,CAAC,YAAO,SAAA,EAAU,iBAAA,EAAkB,OAAO,EAAE,UAAA,EAAY,QAAO,EAC7D,QAAA,EAAA;AAAA,UAAA,IAAA,CAAK,IAAA,wBAAS,MAAA,EAAA,EAAK,SAAA,EAAU,iBAAgB,aAAA,EAAW,IAAA,EAAE,eAAK,IAAA,EAAK,CAAA;AAAA,8BACpE,MAAA,EAAA,EAAK,SAAA,EAAU,gBAAgB,QAAA,EAAA,IAAA,CAAK,KAAA,CAAM,aAAY,EAAE,CAAA;AAAA,0BACzD,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,gBAAA,EAAkB,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,UACvC,MAAA,KAAW,MAAA,oBAAU,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAW,CAAA,2BAAA,EAA8B,MAAM,CAAA,CAAA,EAAI,YAAA,EAAY,CAAA,OAAA,EAAU,MAAM,CAAA,CAAA,EAAI;AAAA,SAAA,EACjH,CAAA;AAAA,QAEC,KAAK,WAAA,oBAAe,GAAA,CAAC,OAAE,SAAA,EAAU,eAAA,EAAiB,eAAK,WAAA,EAAY,CAAA;AAAA,wBAEpE,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,eAAA,EACZ,QAAA,EAAA,IAAA,CAAK,aACF,IAAA,CAAK,UAAA,CAAW,EAAE,MAAA,EAAQ,KAAA,CAAM,EAAA,EAAI,QAAuB,QAAA,EAAU,KAAA,CAAM,QAAA,IAAY,KAAA,EAAO,CAAA,mBAC9F,GAAA,CAAC,WAAA,EAAA,EAAY,MAAA,EAAgB,IAAA,EAAM,IAAA,CAAK,YAAA,EAAc,CAAA,EAC5D,CAAA;AAAA,QAEC,KAAK,UAAA,oBAAc,GAAA,CAAC,OAAE,SAAA,EAAU,sBAAA,EAAwB,eAAK,UAAA,EAAW,CAAA;AAAA,QAEvE,IAAA,CAAa,WAAW,MAAA,oBACxB,IAAA,CAAC,OAAE,SAAA,EAAU,iBAAA,EAAkB,OAAM,eAAA,EAAgB,QAAA,EAAA;AAAA,UAAA,SAAA;AAAA,UAAG,YAAA,CAAc,KAAa,MAAM;AAAA,SAAA,EAAE,CAAA;AAAA,QAG5F,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,qBACd,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YAEC,IAAA,EAAK,QAAA;AAAA,YACL,UAAU,QAAA,CAAS,IAAA;AAAA,YACnB,IAAI,CAAA,CAAE,EAAA;AAAA,YACN,KAAA,EAAO,SAAA,CAAU,CAAA,EAAG,MAAA,CAAO,MAAM,CAAA;AAAA,YACjC,KAAA,EAAO,CAAA,CAAE,KAAA,IAAS,CAAA,CAAE;AAAA,WAAA;AAAA,UALf,CAAA,CAAE;AAAA,SAOV,CAAA;AAAA,QACA,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,qBACf,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YAEC,IAAA,EAAK,QAAA;AAAA,YACL,UAAU,QAAA,CAAS,KAAA;AAAA,YACnB,IAAI,CAAA,CAAE,EAAA;AAAA,YACN,KAAA,EAAO,SAAA,CAAU,CAAA,EAAG,OAAA,CAAQ,MAAM,CAAA;AAAA,YAClC,KAAA,EAAO,CAAA,CAAE,KAAA,IAAS,CAAA,CAAE;AAAA,WAAA;AAAA,UALf,CAAA,CAAE;AAAA,SAOV;AAAA;AAAA;AAAA,GACH;AAEJ;AAEO,IAAM,YAAA,GAAe,KAAK,iBAAiB;AAElD,SAAS,cAAc,QAAA,EAAoC;AACzD,EAAA,OAAO,QAAA,KAAa,YAAY,EAAC,GAAI,CAAC,EAAE,EAAA,EAAI,MAAM,CAAA;AACpD;AACA,SAAS,eAAe,QAAA,EAAoC;AAC1D,EAAA,OAAO,QAAA,KAAa,WAAW,EAAC,GAAI,CAAC,EAAE,EAAA,EAAI,OAAO,CAAA;AACpD;AAEA,SAAS,SAAA,CAAU,GAAW,KAAA,EAAoC;AAChE,EAAA,IAAI,KAAA,IAAS,CAAA,EAAG,OAAO,EAAC;AACxB,EAAA,MAAM,IAAA,GAAQ,GAAA,IAAO,KAAA,GAAQ,CAAA,CAAA,IAAO,CAAA,GAAI,CAAA,CAAA;AACxC,EAAA,OAAO,EAAE,GAAA,EAAK,CAAA,EAAG,IAAI,CAAA,CAAA,CAAA,EAAI;AAC3B;AAMA,SAAS,WAAA,CAAY,EAAE,MAAA,EAAQ,IAAA,EAAK,EAAgF;AAClH,EAAA,MAAM,MAAA,GAAS,QAAQ,EAAC;AAIxB,EAAA,IAAI,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AAChC,EAAA,MAAM,OAAA,GAAU,MAAA,CACb,GAAA,CAAI,CAAC,CAAA,MAAO,EAAE,KAAA,EAAO,CAAA,EAAG,KAAA,EAAO,MAAA,CAAO,CAAA,CAAE,GAAG,GAAE,CAAE,CAAA,CAC/C,MAAA,CAAO,CAAC,EAAE,KAAA,EAAM,KAAM,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,EAAA,IAAM,KAAA,KAAU,IAAI,CAAA;AAC9E,EAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,IAAA,uBAAO,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBAAA,EAAsB,QAAA,EAAA,+BAAA,EAAwB,CAAA;AAAA,EACtE;AACA,EAAA,uBACE,IAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,kBAAA,EACX,QAAA,EAAA;AAAA,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,EAAE,KAAA,EAAO,KAAA,EAAM,qBACvC,IAAA,CAAC,IAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,MAAA,EAAA,EAAK,WAAU,sBAAA,EAAwB,QAAA,EAAA;AAAA,QAAA,KAAA,CAAM,KAAA;AAAA,QAAM;AAAA,OAAA,EAAC,CAAA;AAAA,0BACpD,MAAA,EAAA,EAAK,SAAA,EAAU,wBAAA,EAA0B,QAAA,EAAA,YAAA,CAAa,KAAK,CAAA,EAAE;AAAA,KAAA,EAAA,EAFvD,KAAA,CAAM,GAGf,CACD,CAAA;AAAA,IACA,QAAQ,MAAA,GAAS,CAAA,oBAAK,IAAA,CAAC,IAAA,EAAA,EAAG,WAAU,uBAAA,EAAwB,QAAA,EAAA;AAAA,MAAA,IAAA;AAAA,MAAG,QAAQ,MAAA,GAAS,CAAA;AAAA,MAAE;AAAA,KAAA,EAAK;AAAA,GAAA,EAC1F,CAAA;AAEJ;AAEA,IAAM,QAAA,GAAW,CAAC,CAAA,EAAW,CAAA,GAAI,OAAgB,CAAA,CAAE,MAAA,GAAS,CAAA,GAAI,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,CAAA,GAAI,CAAC,IAAI,QAAA,GAAM,CAAA;AAG1F,SAAS,UAAU,IAAA,EAAuB;AACxC,EAAA,IAAI,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,EAAU;AACpC,IAAA,MAAM,CAAA,GAAI,IAAA;AACV,IAAA,MAAM,IAAA,GAAO,EAAE,KAAA,IAAS,CAAA,CAAE,QAAQ,CAAA,CAAE,GAAA,IAAO,CAAA,CAAE,KAAA,IAAS,CAAA,CAAE,EAAA;AACxD,IAAA,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,IAAA,EAAM,OAAO,IAAA;AAC7C,IAAA,IAAI,OAAO,IAAA,KAAS,QAAA,EAAU,OAAO,OAAO,IAAI,CAAA;AAChD,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,OAAO,MAAA,CAAO,QAAQ,EAAE,CAAA;AAC1B;AAQO,SAAS,aAAa,CAAA,EAAoB;AAC/C,EAAA,IAAI,CAAA,KAAM,IAAA,IAAQ,CAAA,KAAM,MAAA,EAAW,OAAO,EAAA;AAC1C,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,EAAU,OAAO,SAAS,CAAC,CAAA;AAC5C,EAAA,IAAI,OAAO,MAAM,QAAA,IAAY,OAAO,MAAM,SAAA,EAAW,OAAO,OAAO,CAAC,CAAA;AACpE,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,EAAG;AACpB,IAAA,IAAI,CAAA,CAAE,MAAA,KAAW,CAAA,EAAG,OAAO,MAAA;AAC3B,IAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CAAE,GAAA,CAAI,SAAS,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,CAAE,KAAK,IAAI,CAAA;AACpE,IAAA,MAAM,IAAA,GAAO,EAAE,MAAA,GAAS,CAAA,GAAI,MAAM,CAAA,CAAE,MAAA,GAAS,CAAC,CAAA,CAAA,GAAK,EAAA;AACnD,IAAA,OAAO,KAAA,GAAQ,QAAA,CAAS,KAAA,GAAQ,IAAI,CAAA,GAAI,CAAA,EAAG,CAAA,CAAE,MAAM,CAAA,KAAA,EAAQ,CAAA,CAAE,MAAA,KAAW,CAAA,GAAI,KAAK,GAAG,CAAA,CAAA;AAAA,EACtF;AACA,EAAA,IAAI,OAAO,MAAM,QAAA,EAAU;AACzB,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,IAAA,CAAK,CAAW,CAAA;AACpC,IAAA,OAAO,IAAA,CAAK,MAAA,KAAW,CAAA,GAAI,OAAA,GAAU,CAAA,EAAG,IAAA,CAAK,MAAM,CAAA,MAAA,EAAS,IAAA,CAAK,MAAA,KAAW,CAAA,GAAI,EAAA,GAAK,GAAG,CAAA,CAAA;AAAA,EAC1F;AACA,EAAA,OAAO,QAAA;AACT;;;AC9EO,SAAS,cAAA,GAA4B;AAC1C,EAAA,MAAM,MAAiB,EAAC;AACxB,EAAA,KAAA,MAAW,CAAA,IAAK,eAAc,EAAG;AAM/B,IAAA,MAAM,QAAA,GAAW,EAAE,SAAA,IAAa,YAAA;AAChC,IAAA,KAAA,MAAW,MAAM,OAAA,CAAQ,CAAC,CAAA,EAAG,GAAA,CAAI,EAAE,CAAA,GAAI,QAAA;AAAA,EACzC;AACA,EAAA,OAAO,GAAA;AACT","file":"chunk-E3AGYTHP.js","sourcesContent":["import type { Connection, Edge } from \"@xyflow/react\";\nimport type { FlowNode, PortDescriptor } from \"../types\";\nimport { getNodeKind } from \"./registry\";\nimport { resolveNodePorts } from \"./ports\";\n\n/**\n * Connection validation — the single rule that decides whether an edge between\n * two ports is allowed. Lives here (React-free, registry-adjacent) so BOTH the\n * canvas (`<FlowCanvas isValidConnection>`) and the agent bridge's\n * `flow_connect` tool call the same function: a connection the canvas refuses\n * is a connection an agent cannot sneak past, and vice versa — no drift.\n *\n * `PortDescriptor.type` has always documented itself as being \"for hosts that\n * want to validate connections\", but nothing consumed it. This wires it up.\n */\n\n/**\n * Wildcard port type — matches any other type. A port that declares no `type`\n * is treated as a wildcard too, so existing flows (whose ports are untyped)\n * validate exactly as before.\n */\nexport const ANY_PORT_TYPE = \"any\";\n\n/** Decides whether a source-output port may feed a target-input port. */\nexport type PortCompatibility = (\n source: PortDescriptor | undefined,\n target: PortDescriptor | undefined,\n) => boolean;\n\n/**\n * Default compatibility rule: allow the connection UNLESS both ports declare a\n * concrete, differing type. An absent type or the `any` wildcard matches\n * anything — so typed ports get enforced while untyped ports stay permissive,\n * making this a safe default that never breaks an existing untyped graph.\n */\nexport const defaultPortCompatibility: PortCompatibility = (source, target) => {\n const s = source?.type;\n const t = target?.type;\n if (!s || !t) return true;\n if (s === ANY_PORT_TYPE || t === ANY_PORT_TYPE) return true;\n return s === t;\n};\n\nexport type ConnectionValidatorOptions = {\n /** Override the type-compatibility rule. Defaults to {@link defaultPortCompatibility}. */\n compatible?: PortCompatibility;\n /**\n * Allow a node's own output to feed its own input (a self-loop). Default\n * false — self-connections are almost always an accident, and the rare flow\n * that wants one can opt in.\n */\n allowSelfConnection?: boolean;\n};\n\n/** Resolve a node's effective ports for one side, going through the registry. */\nfunction portsFor(node: FlowNode, side: \"inputs\" | \"outputs\"): PortDescriptor[] {\n const kind = getNodeKind((node.data as any)?.kind ?? node.type);\n const resolved = resolveNodePorts(node, kind ?? undefined);\n return resolved[side] ?? [];\n}\n\n/**\n * Resolve which port a handle id refers to. When a side has a single port and\n * the handle id is absent (React Flow omits it for a lone default handle), use\n * that port; otherwise match by id.\n */\nfunction findPort(\n ports: PortDescriptor[],\n handleId: string | null | undefined,\n): PortDescriptor | undefined {\n if (handleId == null) return ports.length === 1 ? ports[0] : undefined;\n return ports.find((p) => p.id === handleId);\n}\n\n/**\n * Build an `isValidConnection` predicate that enforces port-type compatibility\n * against a live node list. Pass it straight to `<FlowCanvas isValidConnection>`\n * or reuse it to gate an agent's `flow_connect`.\n *\n * `getNodes` is called on every check so the validator always sees the current\n * graph (wire it to a ref/state getter, not a snapshot).\n *\n * A connection is rejected when: an endpoint is missing; it is a self-loop and\n * `allowSelfConnection` is off; either node is unknown; or the resolved ports\n * are type-incompatible. Nodes/ports with no declared type validate as before.\n */\nexport function createConnectionValidator(\n getNodes: () => FlowNode[],\n options: ConnectionValidatorOptions = {},\n): (connection: Connection | Edge) => boolean {\n const compatible = options.compatible ?? defaultPortCompatibility;\n return (connection) => {\n const { source, target, sourceHandle, targetHandle } = connection;\n if (!source || !target) return false;\n if (!options.allowSelfConnection && source === target) return false;\n\n const nodes = getNodes();\n const src = nodes.find((n) => n.id === source);\n const tgt = nodes.find((n) => n.id === target);\n if (!src || !tgt) return false;\n\n const outPort = findPort(portsFor(src, \"outputs\"), sourceHandle);\n const inPort = findPort(portsFor(tgt, \"inputs\"), targetHandle);\n return compatible(outPort, inPort);\n };\n}\n","import { memo, useMemo } from \"react\";\nimport { Handle, NodeResizer, NodeToolbar, Position, type NodeProps } from \"@xyflow/react\";\nimport type { FlowNode, NodeRunStatus, PortDescriptor } from \"../types\";\nimport { categoryAccent, getNodeKind } from \"./registry\";\nimport { nodeConfig, resolveNodePorts } from \"./ports\";\n\n/**\n * RegistryNode — generic node renderer that looks up the node's kind in\n * the registry and applies its `accent`/`label`/`icon`/`renderBody`. Used\n * as the xyflow node component for every registered kind.\n */\nfunction RegistryNodeInner(props: NodeProps<FlowNode>) {\n const kindName = (props.data as any).kind ?? props.type;\n const kind = useMemo(() => getNodeKind(kindName), [kindName]);\n\n if (!kind) {\n return (\n <div className=\"ff-node ff-node--unknown\">\n <div className=\"ff-node__header\" style={{ background: \"#71717a\" }}>\n <span className=\"ff-node__tag\">UNKNOWN</span>\n <span className=\"ff-node__label\">{kindName}</span>\n </div>\n <p className=\"ff-node__desc\">No registered kind for \"{kindName}\".</p>\n </div>\n );\n }\n\n const data = props.data;\n const status: NodeRunStatus = data.status ?? \"idle\";\n const accent = kind.accent ?? categoryAccent(kind.category);\n const resolved = resolveNodePorts(props, kind);\n const inputs: PortDescriptor[] = resolved.inputs ?? defaultInputs(kind.category);\n const outputs: PortDescriptor[] = resolved.outputs ?? defaultOutputs(kind.category);\n const config = nodeConfig(props);\n const label = data.label ?? kind.label;\n\n return (\n <div\n className={[\n \"ff-node\",\n `ff-node--status-${status}`,\n `ff-node--cat-${kind.category}`,\n props.selected ? \"ff-node--selected\" : \"\",\n kind.resizable ? \"ff-node--resizable\" : \"\",\n ].filter(Boolean).join(\" \")}\n style={{ borderColor: props.selected ? accent : undefined }}\n >\n {kind.resizable && (\n <NodeResizer\n isVisible={props.selected ?? false}\n color={accent}\n {...(typeof kind.resizable === \"object\" ? kind.resizable : {})}\n />\n )}\n {kind.toolbar && (\n <NodeToolbar isVisible={props.selected ?? false}>\n {kind.toolbar({ nodeId: props.id, config: config as any, selected: props.selected ?? false })}\n </NodeToolbar>\n )}\n <header className=\"ff-node__header\" style={{ background: accent }}>\n {kind.icon && <span className=\"ff-node__icon\" aria-hidden>{kind.icon}</span>}\n <span className=\"ff-node__tag\">{kind.label.toUpperCase()}</span>\n <span className=\"ff-node__label\">{label}</span>\n {status !== \"idle\" && <span className={`ff-node__dot ff-node__dot--${status}`} aria-label={`status ${status}`} />}\n </header>\n\n {data.description && <p className=\"ff-node__desc\">{data.description}</p>}\n\n <div className=\"ff-node__body\">\n {kind.renderBody\n ? kind.renderBody({ nodeId: props.id, config: config as any, selected: props.selected ?? false })\n : <DefaultBody config={config} kind={kind.configSchema} />}\n </div>\n\n {data.statusText && <p className=\"ff-node__status-text\">{data.statusText}</p>}\n\n {(data as any).output !== undefined && (\n <p className=\"ff-node__output\" title=\"Latest output\">→ {previewValue((data as any).output)}</p>\n )}\n\n {inputs.map((p, i) => (\n <Handle\n key={p.id}\n type=\"target\"\n position={Position.Left}\n id={p.id}\n style={portStyle(i, inputs.length)}\n title={p.label ?? p.id}\n />\n ))}\n {outputs.map((p, i) => (\n <Handle\n key={p.id}\n type=\"source\"\n position={Position.Right}\n id={p.id}\n style={portStyle(i, outputs.length)}\n title={p.label ?? p.id}\n />\n ))}\n </div>\n );\n}\n\nexport const RegistryNode = memo(RegistryNodeInner);\n\nfunction defaultInputs(category: string): PortDescriptor[] {\n return category === \"trigger\" ? [] : [{ id: \"in\" }];\n}\nfunction defaultOutputs(category: string): PortDescriptor[] {\n return category === \"output\" ? [] : [{ id: \"out\" }];\n}\n\nfunction portStyle(i: number, total: number): React.CSSProperties {\n if (total <= 1) return {};\n const slot = (100 / (total + 1)) * (i + 1);\n return { top: `${slot}%` };\n}\n\n/**\n * DefaultBody — compact summary of the config values for nodes that\n * don't provide a custom renderBody. Skips fields that look empty.\n */\nfunction DefaultBody({ config, kind }: { config: Record<string, unknown>; kind?: import(\"./types\").ConfigField[] }) {\n const fields = kind ?? [];\n // A kind with no config schema has nothing to configure — don't nag with a\n // \"configure in the panel\" prompt (that's only for a kind that HAS fields but\n // none are filled in yet). Triggers, Output, etc. render as just their header.\n if (fields.length === 0) return null;\n const visible = fields\n .map((f) => ({ field: f, value: config[f.key] }))\n .filter(({ value }) => value !== undefined && value !== \"\" && value !== null);\n if (visible.length === 0) {\n return <div className=\"ff-node__body-empty\">— configure in the panel</div>;\n }\n return (\n <ul className=\"ff-node__summary\">\n {visible.slice(0, 4).map(({ field, value }) => (\n <li key={field.key}>\n <span className=\"ff-node__summary-key\">{field.label}:</span>\n <span className=\"ff-node__summary-value\">{previewValue(value)}</span>\n </li>\n ))}\n {visible.length > 4 && <li className=\"ff-node__summary-more\">+ {visible.length - 4} more</li>}\n </ul>\n );\n}\n\nconst truncate = (s: string, n = 30): string => (s.length > n ? s.slice(0, n - 1) + \"…\" : s);\n\n/** A short, human name for one item in a repeater/list value. */\nfunction itemLabel(item: unknown): string {\n if (item && typeof item === \"object\") {\n const o = item as Record<string, unknown>;\n const name = o.label ?? o.name ?? o.key ?? o.title ?? o.id;\n if (typeof name === \"string\" && name) return name;\n if (typeof name === \"number\") return String(name);\n return \"item\";\n }\n return String(item ?? \"\");\n}\n\n/**\n * A node card's job is to read at a glance, not to be a data dump — so a value\n * is summarised, never `JSON.stringify`d. An array becomes its item names (or a\n * count), an object becomes a field count. Raw JSON on a card was the specific\n * thing to kill: `Fields: [{\"key\":\"answer\",…}]` reads as noise.\n */\nexport function previewValue(v: unknown): string {\n if (v === null || v === undefined) return \"\";\n if (typeof v === \"string\") return truncate(v);\n if (typeof v === \"number\" || typeof v === \"boolean\") return String(v);\n if (Array.isArray(v)) {\n if (v.length === 0) return \"none\";\n const names = v.slice(0, 3).map(itemLabel).filter(Boolean).join(\", \");\n const rest = v.length > 3 ? `, +${v.length - 3}` : \"\";\n return names ? truncate(names + rest) : `${v.length} item${v.length === 1 ? \"\" : \"s\"}`;\n }\n if (typeof v === \"object\") {\n const keys = Object.keys(v as object);\n return keys.length === 0 ? \"empty\" : `${keys.length} field${keys.length === 1 ? \"\" : \"s\"}`;\n }\n return \"…\";\n}\n","export type {\n ConfigField,\n TextConfigField,\n TextareaConfigField,\n NumberConfigField,\n SelectConfigField,\n SwitchConfigField,\n JsonConfigField,\n ExpressionConfigField,\n CredentialConfigField,\n RepeaterConfigField,\n RepeaterRowField,\n KeyValueConfigField,\n DocumentConfigField,\n NodeCategory,\n NodeKindDefinition,\n PortSpec,\n RenderBodyContext,\n} from \"./types\";\n\nexport { resolvePortSpec, resolveNodePorts, nodeConfig } from \"./ports\";\n\nexport {\n createConnectionValidator,\n defaultPortCompatibility,\n ANY_PORT_TYPE,\n type PortCompatibility,\n type ConnectionValidatorOptions,\n} from \"./connection\";\n\n/** Host capabilities — core declares the contract, the host supplies the impl. */\nexport {\n registerLlmClient,\n getLlmClient,\n registerWorkflowResolver,\n getWorkflowResolver,\n capabilityStatus,\n type LlmClient,\n type LlmRoute,\n type LlmRouteRequest,\n type LlmRouteChoice,\n type WorkflowResolver,\n type WorkflowResolution,\n type WorkflowResolutionFailure,\n type CapabilityId,\n isResolutionFailure,\n} from \"./capabilities\";\n\n/**\n * The human-pause contract — a run waiting for a person, not a failure.\n * `decodePause` is the one function a durable runner needs.\n */\nexport {\n pauseForHuman,\n encodePause,\n decodePause,\n isPause,\n PAUSE_PREFIX,\n LEGACY_PAUSE_PREFIXES,\n type PauseAwaiting,\n type PauseSignal,\n} from \"./pause\";\n\nexport { subflowExecutor, subflowPorts, subflowMode, DEFAULT_MAX_DEPTH, type SubflowMode } from \"./subflow\";\nexport { llmRouterExecutor, declaredRoutes, resolveFallbackPort } from \"./llm-router\";\n/** @deprecated Renamed to `llmRouterExecutor` — the id and label now match. */\nexport { llmRouterExecutor as llmBranchExecutor } from \"./llm-router\";\n\nexport {\n registerRichInputAdapter,\n getRichInputAdapter,\n isRichInputEnabled,\n onRichInputAdapterChanged,\n RichInputPreview,\n type RichInputAdapter,\n} from \"./rich-input\";\n\nexport {\n registerNodeKind,\n overrideNodeKind,\n clearNodeKindOverrides,\n type NodeKindPresentation,\n getNodeKind,\n resolveKindId,\n kindIds,\n listNodeKinds,\n onNodeKindsChanged,\n defaultConfigFor,\n validateConfig,\n categoryAccent,\n} from \"./registry\";\n\nexport { RegistryNode } from \"./RegistryNode\";\nexport { registerBuiltinKinds, BUILTIN_KINDS } from \"./builtin\";\nexport { ensureBuiltinKinds } from \"./registry\";\n\nimport type { NodeTypes } from \"@xyflow/react\";\nimport { RegistryNode } from \"./RegistryNode\";\nimport { kindIds, listNodeKinds } from \"./registry\";\n\n/**\n * Build an xyflow `nodeTypes` map from the registry — every registered\n * kind gets `RegistryNode` as its renderer. Refresh manually via\n * `useNodeTypes()` (a hook that subscribes to registry changes).\n */\nexport function buildNodeTypes(): NodeTypes {\n const map: NodeTypes = {};\n for (const k of listNodeKinds()) {\n // A kind may bring its own full renderer (lanes/containers); otherwise the\n // default card. Key on every id the kind answers to, not just the canonical\n // one — xyflow looks the renderer up by `node.type` BEFORE RegistryNode gets\n // a chance to resolve aliases, so a graph carrying a pre-namespace type would\n // otherwise fall through to the unknown-node placeholder.\n const renderer = k.component ?? RegistryNode;\n for (const id of kindIds(k)) map[id] = renderer;\n }\n return map;\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { resolveNodePorts, getNodeKind, defaultConfigFor, validateConfig } from './chunk-CIBW5ATA.js';
1
+ import { resolveNodePorts, getNodeKind, defaultConfigFor, validateConfig } from './chunk-22OJOD4X.js';
2
2
 
3
3
  // src/schema/workflow-schema.ts
4
4
  var WORKFLOW_SCHEMA_VERSION = 1;
@@ -53,8 +53,23 @@ function toSchemaEdge(e) {
53
53
  label: typeof e.label === "string" ? e.label : void 0
54
54
  };
55
55
  }
56
- function migrateSchema(schema) {
57
- return schema;
56
+ var MIGRATIONS = {};
57
+ function migrateSchema(schema, steps = MIGRATIONS) {
58
+ if (!schema || typeof schema !== "object") return schema;
59
+ const doc = schema;
60
+ let version = doc.version;
61
+ if (typeof version !== "number" || !Number.isInteger(version) || version >= WORKFLOW_SCHEMA_VERSION) {
62
+ return schema;
63
+ }
64
+ let out = doc;
65
+ while (version < WORKFLOW_SCHEMA_VERSION) {
66
+ const step = steps[version];
67
+ if (!step) return out;
68
+ out = step(out);
69
+ version += 1;
70
+ out.version = version;
71
+ }
72
+ return out;
58
73
  }
59
74
  function importWorkflow(schema, options = {}) {
60
75
  const issues = [];
@@ -151,5 +166,5 @@ function workflowToBlob(schema) {
151
166
  }
152
167
 
153
168
  export { WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, exportWorkflow, importWorkflow, migrateSchema, workflowToBlob };
154
- //# sourceMappingURL=chunk-FH6MWLKD.js.map
155
- //# sourceMappingURL=chunk-FH6MWLKD.js.map
169
+ //# sourceMappingURL=chunk-GB4A7DFM.js.map
170
+ //# sourceMappingURL=chunk-GB4A7DFM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/schema/workflow-schema.ts"],"names":[],"mappings":";;;AAKO,IAAM,uBAAA,GAA0B;AAChC,IAAM,mBAAA,GAAsB;AA2G5B,SAAS,cAAA,CACd,KAAA,EACA,QAAA,EACA,IAAA,EACgB;AAChB,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,mBAAA;AAAA,IACT,OAAA,EAAS,uBAAA;AAAA,IACT,QAAA,EAAU,WAAW,EAAE,GAAG,UAAU,SAAA,EAAW,IAAA,CAAK,GAAA,EAAI,EAAE,GAAI,MAAA;AAAA;AAAA;AAAA,IAG9D,GAAI,KAAA,CAAM,MAAA,IAAU,KAAA,CAAM,MAAA,CAAO,MAAA,GAAS,CAAA,GAAI,EAAE,MAAA,EAAQ,KAAA,CAAM,MAAA,EAAO,GAAI,EAAC;AAAA,IAC1E,KAAA,EAAO;AAAA,MACL,KAAA,EAAO,KAAA,CAAM,KAAA,CAAM,GAAA,CAAI,YAAY,CAAA;AAAA,MACnC,KAAA,EAAO,KAAA,CAAM,KAAA,CAAM,GAAA,CAAI,YAAY;AAAA,KACrC;AAAA,IACA;AAAA,GACF;AACF;AAEA,SAAS,aAAa,CAAA,EAAiC;AACrD,EAAA,MAAM,IAAA,GAAY,CAAA,CAAE,IAAA,IAAQ,EAAC;AAC7B,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,IAAA,IAAQ,CAAA,CAAE,IAAA,IAAQ,QAAA;AAIxC,EAAA,MAAM,QAAQ,gBAAA,CAAiB,CAAA,EAAG,WAAA,CAAY,QAAQ,KAAK,MAAS,CAAA;AACpE,EAAA,MAAM,IAAA,GAAO,CAAA;AACb,EAAA,OAAO;AAAA,IACL,IAAI,CAAA,CAAE,EAAA;AAAA,IACN,IAAA,EAAM,QAAA;AAAA,IACN,QAAA,EAAU,EAAE,CAAA,EAAG,CAAA,CAAE,SAAS,CAAA,EAAG,CAAA,EAAG,CAAA,CAAE,QAAA,CAAS,CAAA,EAAE;AAAA,IAC7C,OAAO,IAAA,CAAK,KAAA;AAAA,IACZ,aAAa,IAAA,CAAK,WAAA;AAAA,IAClB,GAAI,OAAO,IAAA,CAAK,WAAA,KAAgB,QAAA,IAAY,IAAA,CAAK,WAAA,KAAgB,EAAA,GAAK,EAAE,WAAA,EAAa,IAAA,CAAK,WAAA,KAAgB,EAAC;AAAA,IAC3G,GAAI,OAAO,IAAA,CAAK,WAAA,KAAgB,QAAA,IAAY,IAAA,CAAK,WAAA,KAAgB,EAAA,GAAK,EAAE,WAAA,EAAa,IAAA,CAAK,WAAA,KAAgB,EAAC;AAAA,IAC3G,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,QAAQ,KAAA,CAAM,MAAA;AAAA,IACd,SAAS,KAAA,CAAM,OAAA;AAAA;AAAA;AAAA,IAGf,GAAI,KAAK,QAAA,GAAW,EAAE,UAAU,IAAA,CAAK,QAAA,KAAa,EAAC;AAAA,IACnD,GAAI,KAAK,MAAA,GAAS,EAAE,QAAQ,IAAA,CAAK,MAAA,KAAW,EAAC;AAAA,IAC7C,GAAI,OAAO,IAAA,CAAK,KAAA,KAAU,QAAA,GAAW,EAAE,KAAA,EAAO,IAAA,CAAK,KAAA,EAAM,GAAI,EAAC;AAAA,IAC9D,GAAI,OAAO,IAAA,CAAK,MAAA,KAAW,QAAA,GAAW,EAAE,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAO,GAAI,EAAC;AAAA,IACjE,GAAI,KAAK,KAAA,GAAQ,EAAE,OAAO,IAAA,CAAK,KAAA,KAAU;AAAC,GAC5C;AACF;AAEA,SAAS,aAAa,CAAA,EAAiC;AACrD,EAAA,OAAO;AAAA,IACL,IAAI,CAAA,CAAE,EAAA;AAAA,IACN,QAAQ,CAAA,CAAE,MAAA;AAAA,IACV,QAAQ,CAAA,CAAE,MAAA;AAAA,IACV,YAAA,EAAc,EAAE,YAAA,IAAgB,MAAA;AAAA,IAChC,YAAA,EAAc,EAAE,YAAA,IAAgB,MAAA;AAAA,IAChC,OAAO,OAAO,CAAA,CAAE,KAAA,KAAU,QAAA,GAAW,EAAE,KAAA,GAAQ;AAAA,GACjD;AACF;AAkBO,IAAM,aAA4C,EAAC;AA8BnD,SAAS,aAAA,CACd,MAAA,EACA,KAAA,GAAuC,UAAA,EAC9B;AACT,EAAA,IAAI,CAAC,MAAA,IAAU,OAAO,MAAA,KAAW,UAAU,OAAO,MAAA;AAElD,EAAA,MAAM,GAAA,GAAM,MAAA;AACZ,EAAA,IAAI,UAAU,GAAA,CAAI,OAAA;AAElB,EAAA,IAAI,OAAO,YAAY,QAAA,IAAY,CAAC,OAAO,SAAA,CAAU,OAAO,CAAA,IAAK,OAAA,IAAW,uBAAA,EAAyB;AACnG,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,IAAI,GAAA,GAAM,GAAA;AACV,EAAA,OAAO,UAAU,uBAAA,EAAyB;AACxC,IAAA,MAAM,IAAA,GAAO,MAAM,OAAO,CAAA;AAC1B,IAAA,IAAI,CAAC,MAAM,OAAO,GAAA;AAElB,IAAA,GAAA,GAAM,KAAK,GAAG,CAAA;AACd,IAAA,OAAA,IAAW,CAAA;AACX,IAAA,GAAA,CAAI,OAAA,GAAU,OAAA;AAAA,EAChB;AAEA,EAAA,OAAO,GAAA;AACT;AAOO,SAAS,cAAA,CAAe,MAAA,EAAiB,OAAA,GAAyB,EAAC,EAAiB;AACzF,EAAA,MAAM,SAAwB,EAAC;AAC/B,EAAA,MAAM,OAAA,GAAU,QAAQ,OAAA,KAAY,IAAA;AACpC,EAAA,MAAA,GAAS,cAAc,MAAM,CAAA;AAE7B,EAAA,IAAI,CAAC,MAAA,IAAU,OAAO,MAAA,KAAW,QAAA,EAAU;AACzC,IAAA,OAAO,EAAE,IAAI,KAAA,EAAO,KAAA,EAAO,EAAE,KAAA,EAAO,IAAI,KAAA,EAAO,IAAG,EAAG,MAAA,EAAQ,CAAC,EAAE,KAAA,EAAO,SAAS,OAAA,EAAS,0BAAA,EAA4B,CAAA,EAAE;AAAA,EACzH;AACA,EAAA,MAAM,CAAA,GAAI,MAAA;AACV,EAAA,IAAI,CAAA,CAAE,YAAY,uBAAA,EAAyB;AACzC,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,KAAA,EAAO,UAAU,SAAA,GAAY,OAAA;AAAA,MAC7B,OAAA,EAAS,CAAA,qCAAA,EAAwC,CAAA,CAAE,OAAO,cAAc,uBAAuB,CAAA,CAAA;AAAA,KAChG,CAAA;AACD,IAAA,IAAI,CAAC,OAAA,EAAS,OAAO,EAAE,IAAI,KAAA,EAAO,KAAA,EAAO,EAAE,KAAA,EAAO,EAAC,EAAG,KAAA,EAAO,EAAC,IAAK,MAAA,EAAO;AAAA,EAC5E;AAEA,EAAA,MAAM,QAAA,GAAW,CAAA,CAAE,KAAA,EAAO,KAAA,IAAS,EAAC;AACpC,EAAA,MAAM,QAAA,GAAW,CAAA,CAAE,KAAA,EAAO,KAAA,IAAS,EAAC;AAEpC,EAAA,MAAM,KAAA,GAAoB,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,KAAM;AAC5C,IAAA,MAAM,IAAA,GAAO,WAAA,CAAY,CAAA,CAAE,IAAI,CAAA;AAC/B,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,KAAA,EAAO,UAAU,SAAA,GAAY,OAAA;AAAA,QAC7B,QAAQ,CAAA,CAAE,EAAA;AAAA,QACV,OAAA,EAAS,CAAA,cAAA,EAAiB,CAAA,CAAE,IAAI,CAAA,sCAAA;AAAA,OACjC,CAAA;AAAA,IACH;AACA,IAAA,MAAM,SAAS,CAAA,CAAE,MAAA,KAAW,OAAO,gBAAA,CAAiB,IAAI,IAAI,EAAC,CAAA;AAC7D,IAAA,IAAI,IAAA,EAAM;AACR,MAAA,KAAA,MAAW,GAAA,IAAO,cAAA,CAAe,IAAA,EAAM,MAAM,CAAA,EAAG;AAC9C,QAAA,MAAA,CAAO,IAAA,CAAK,EAAE,KAAA,EAAO,SAAA,EAAW,QAAQ,CAAA,CAAE,EAAA,EAAI,OAAA,EAAS,CAAA,EAAG,IAAI,GAAG,CAAA,EAAA,EAAK,GAAA,CAAI,OAAO,IAAI,CAAA;AAAA,MACvF;AAAA,IACF;AAIA,IAAA,MAAM,MAAA,GAAS,IAAA,EAAM,IAAA,IAAQ,CAAA,CAAE,IAAA;AAC/B,IAAA,OAAO;AAAA,MACL,IAAI,CAAA,CAAE,EAAA;AAAA,MACN,IAAA,EAAM,MAAA;AAAA,MACN,QAAA,EAAU,EAAE,CAAA,EAAG,CAAA,CAAE,QAAA,EAAU,CAAA,IAAK,CAAA,EAAG,CAAA,EAAG,CAAA,CAAE,QAAA,EAAU,CAAA,IAAK,CAAA,EAAE;AAAA;AAAA,MAEzD,GAAI,EAAE,QAAA,GAAW,EAAE,UAAU,CAAA,CAAE,QAAA,KAAa,EAAC;AAAA,MAC7C,GAAI,EAAE,MAAA,GAAS,EAAE,QAAQ,CAAA,CAAE,MAAA,KAAW,EAAC;AAAA,MACvC,GAAI,OAAO,CAAA,CAAE,KAAA,KAAU,QAAA,GAAW,EAAE,KAAA,EAAO,CAAA,CAAE,KAAA,EAAM,GAAI,EAAC;AAAA,MACxD,GAAI,OAAO,CAAA,CAAE,MAAA,KAAW,QAAA,GAAW,EAAE,MAAA,EAAQ,CAAA,CAAE,MAAA,EAAO,GAAI,EAAC;AAAA,MAC3D,GAAI,EAAE,KAAA,GAAQ,EAAE,OAAO,CAAA,CAAE,KAAA,KAAU,EAAC;AAAA,MACpC,IAAA,EAAM;AAAA,QACJ,IAAA,EAAM,MAAA;AAAA,QACN,KAAA,EAAO,CAAA,CAAE,KAAA,IAAS,IAAA,EAAM,SAAS,CAAA,CAAE,IAAA;AAAA,QACnC,aAAa,CAAA,CAAE,WAAA;AAAA,QACf,GAAI,EAAE,WAAA,GAAc,EAAE,aAAa,CAAA,CAAE,WAAA,KAAgB,EAAC;AAAA,QACtD,GAAI,EAAE,WAAA,GAAc,EAAE,aAAa,CAAA,CAAE,WAAA,KAAgB,EAAC;AAAA,QACtD,MAAA;AAAA;AAAA;AAAA,QAGA,GAAI,EAAE,MAAA,GAAS,EAAE,QAAQ,CAAA,CAAE,MAAA,KAAW,EAAC;AAAA,QACvC,GAAI,EAAE,OAAA,GAAU,EAAE,SAAS,CAAA,CAAE,OAAA,KAAY;AAAC;AAC5C,KACF;AAAA,EACF,CAAC,CAAA;AAED,EAAA,MAAM,OAAA,GAAU,IAAI,GAAA,CAAI,KAAA,CAAM,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,EAAE,CAAC,CAAA;AAC9C,EAAA,MAAM,KAAA,GAAoB,QAAA,CACvB,GAAA,CAAI,CAAC,CAAA,KAAM;AACV,IAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,MAAM,CAAA,EAAG;AAC1B,MAAA,MAAA,CAAO,IAAA,CAAK,EAAE,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,CAAA,CAAE,EAAA,EAAI,OAAA,EAAS,CAAA,aAAA,EAAgB,CAAA,CAAE,MAAM,CAAA,YAAA,CAAA,EAAgB,CAAA;AAC/F,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,MAAM,CAAA,EAAG;AAC1B,MAAA,MAAA,CAAO,IAAA,CAAK,EAAE,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,CAAA,CAAE,EAAA,EAAI,OAAA,EAAS,CAAA,aAAA,EAAgB,CAAA,CAAE,MAAM,CAAA,YAAA,CAAA,EAAgB,CAAA;AAC/F,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,OAAO;AAAA,MACL,IAAI,CAAA,CAAE,EAAA;AAAA,MACN,QAAQ,CAAA,CAAE,MAAA;AAAA,MACV,QAAQ,CAAA,CAAE,MAAA;AAAA,MACV,cAAc,CAAA,CAAE,YAAA;AAAA,MAChB,cAAc,CAAA,CAAE,YAAA;AAAA,MAChB,OAAO,CAAA,CAAE;AAAA,KACX;AAAA,EACF,CAAC,CAAA,CACA,MAAA,CAAO,CAAC,CAAA,KAAqB,MAAM,IAAI,CAAA;AAE1C,EAAA,MAAM,KAAK,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA,KAAM,CAAA,CAAE,UAAU,OAAO,CAAA;AAKlD,EAAA,MAAM,iBAAiB,KAAA,CAAM,OAAA,CAAQ,EAAE,MAAM,CAAA,GACxC,EAAE,MAAA,CAA2B,MAAA;AAAA,IAC5B,CAAC,UACC,KAAA,KAAU,IAAA,IAAQ,OAAO,KAAA,KAAU,QAAA,IAAY,OAAQ,KAAA,CAAwB,IAAA,KAAS;AAAA,GAC5F,GACA,MAAA;AAEJ,EAAA,OAAO;AAAA,IACL,EAAA;AAAA,IACA,KAAA,EAAO;AAAA,MACL,KAAA;AAAA,MACA,KAAA;AAAA,MACA,GAAI,kBAAkB,cAAA,CAAe,MAAA,GAAS,IAAI,EAAE,MAAA,EAAQ,cAAA,EAAe,GAAI;AAAC,KAClF;AAAA,IACA;AAAA,GACF;AACF;AAGO,SAAS,eAAe,MAAA,EAA8B;AAC3D,EAAA,OAAO,IAAI,IAAA,CAAK,CAAC,IAAA,CAAK,SAAA,CAAU,MAAA,EAAQ,IAAA,EAAM,CAAC,CAAC,CAAA,EAAG,EAAE,IAAA,EAAM,oBAAoB,CAAA;AACjF","file":"chunk-GB4A7DFM.js","sourcesContent":["import type { FlowEdge, FlowGraph, FlowNode, PortDescriptor, WorkflowInput } from \"../types\";\nimport { defaultConfigFor, getNodeKind, validateConfig } from \"../registry/registry\";\nimport { resolveNodePorts } from \"../registry/ports\";\n\n/** Schema version. Bump on breaking shape changes; add migrations as needed. */\nexport const WORKFLOW_SCHEMA_VERSION = 1 as const;\nexport const WORKFLOW_SCHEMA_URL = \"https://particle.academy/schemas/workflow/v1.json\";\n\nexport type WorkflowSchema = {\n $schema: typeof WORKFLOW_SCHEMA_URL;\n version: typeof WORKFLOW_SCHEMA_VERSION;\n metadata?: WorkflowMetadata;\n /**\n * What this workflow accepts at run start, passed BY NAME.\n *\n * Lives beside `graph` rather than inside it because it describes the\n * workflow's CONTRACT, not its topology: a caller reads this to know what to\n * pass, and reading it should not mean walking nodes looking for a trigger.\n *\n * Omitted entirely when a workflow takes none, so every existing saved\n * document is unchanged byte for byte.\n */\n inputs?: WorkflowInput[];\n graph: {\n nodes: WorkflowSchemaNode[];\n edges: WorkflowSchemaEdge[];\n };\n view?: {\n viewport?: { x: number; y: number; zoom: number };\n };\n};\n\nexport type WorkflowMetadata = {\n id?: string;\n name?: string;\n description?: string;\n createdAt?: number;\n updatedAt?: number;\n author?: string;\n tags?: string[];\n};\n\nexport type WorkflowSchemaNode = {\n id: string;\n /** Registry kind name (e.g. \"memory_store\"). */\n kind: string;\n position: { x: number; y: number };\n label?: string;\n description?: string;\n /**\n * Announced to a person just before / just after this node runs. Omitted\n * entirely when unset, so a graph of ordinary plumbing nodes does not carry\n * a pair of empty keys per node and every diff of a saved graph stays\n * readable.\n */\n startingMsg?: string;\n stoppingMsg?: string;\n config?: Record<string, unknown>;\n /**\n * Resolved ports, written on export.\n *\n * A kind may derive its ports from config (`switch_case` cases,\n * `llm_branch` routes), and that derivation is a JavaScript function — a\n * runtime in another language cannot execute it. Without the resolved ports\n * in the document, the PHP twin sees no declared outputs and falls back to a\n * single `out`, so every branch edge in an exported flow silently stops\n * firing. Serializing them keeps the schema self-describing and preserves\n * the cross-runtime guarantee: same JSON in, same routing out.\n *\n * Optional and additive — a hand-written schema may omit them, and each\n * runtime then falls back to its own kind registry.\n */\n inputs?: PortDescriptor[];\n outputs?: PortDescriptor[];\n /**\n * Visual layout — additive + optional. `parentId`/`extent` carry node grouping\n * (swimlanes / containers); `width`/`height` carry an explicit (resized) size;\n * `style` carries inline presentation. A runtime that only walks edges/ports\n * (e.g. the PHP twin) ignores all of these — they exist purely for the canvas,\n * so an older reader that doesn't know them simply drops them.\n */\n parentId?: string;\n extent?: \"parent\" | [[number, number], [number, number]];\n width?: number;\n height?: number;\n style?: Record<string, unknown>;\n};\n\nexport type WorkflowSchemaEdge = {\n id: string;\n source: string;\n target: string;\n sourceHandle?: string;\n targetHandle?: string;\n label?: string;\n};\n\nexport type ImportIssue = {\n level: \"error\" | \"warning\";\n nodeId?: string;\n edgeId?: string;\n message: string;\n};\n\nexport type ImportResult = {\n graph: FlowGraph;\n issues: ImportIssue[];\n /** True when the import produced a usable graph (errors may have been\n * rewritten to warnings via `lenient: true`). */\n ok: boolean;\n};\n\n/** Snapshot the in-memory graph as a portable WorkflowSchema. */\nexport function exportWorkflow(\n graph: FlowGraph,\n metadata?: WorkflowMetadata,\n view?: WorkflowSchema[\"view\"],\n): WorkflowSchema {\n return {\n $schema: WORKFLOW_SCHEMA_URL,\n version: WORKFLOW_SCHEMA_VERSION,\n metadata: metadata ? { ...metadata, updatedAt: Date.now() } : undefined,\n // Round-trips, or a saved workflow silently forgets its own contract and\n // every caller's props become \"unknown input\" on the next load.\n ...(graph.inputs && graph.inputs.length > 0 ? { inputs: graph.inputs } : {}),\n graph: {\n nodes: graph.nodes.map(toSchemaNode),\n edges: graph.edges.map(toSchemaEdge),\n },\n view,\n };\n}\n\nfunction toSchemaNode(n: FlowNode): WorkflowSchemaNode {\n const data: any = n.data ?? {};\n const kindName = data.kind ?? n.type ?? \"custom\";\n // Resolve through the same helper the canvas and runtime use, so a\n // config-driven kind writes its ACTUAL ports into the document instead of\n // leaving another language's runtime to guess at them.\n const ports = resolveNodePorts(n, getNodeKind(kindName) ?? undefined);\n const node = n as any;\n return {\n id: n.id,\n kind: kindName,\n position: { x: n.position.x, y: n.position.y },\n label: data.label,\n description: data.description,\n ...(typeof data.startingMsg === \"string\" && data.startingMsg !== \"\" ? { startingMsg: data.startingMsg } : {}),\n ...(typeof data.stoppingMsg === \"string\" && data.stoppingMsg !== \"\" ? { stoppingMsg: data.stoppingMsg } : {}),\n config: data.config,\n inputs: ports.inputs,\n outputs: ports.outputs,\n // Visual layout — only when explicitly set (never persist auto-`measured`\n // dimensions, which are derived, not authored).\n ...(node.parentId ? { parentId: node.parentId } : {}),\n ...(node.extent ? { extent: node.extent } : {}),\n ...(typeof node.width === \"number\" ? { width: node.width } : {}),\n ...(typeof node.height === \"number\" ? { height: node.height } : {}),\n ...(node.style ? { style: node.style } : {}),\n };\n}\n\nfunction toSchemaEdge(e: FlowEdge): WorkflowSchemaEdge {\n return {\n id: e.id,\n source: e.source,\n target: e.target,\n sourceHandle: e.sourceHandle ?? undefined,\n targetHandle: e.targetHandle ?? undefined,\n label: typeof e.label === \"string\" ? e.label : undefined,\n };\n}\n\nexport type ImportOptions = {\n /** When true, unknown kinds become warnings + a \"custom\" placeholder\n * instead of errors. Default false. */\n lenient?: boolean;\n};\n\n/** A migration step: takes a version-N document to version N+1. */\nexport type MigrationStep = (schema: Record<string, unknown>) => Record<string, unknown>;\n\n/**\n * Every migration step, keyed by the version it upgrades FROM.\n *\n * Empty today because v1 is current — when a BREAKING bump lands, add the step\n * here and every stored document upgrades on read, in this runtime and its\n * PHP and Python twins.\n */\nexport const MIGRATIONS: Record<number, MigrationStep> = {};\n\n/**\n * Migrate a raw schema object up to the current version, as far as it can go.\n *\n * Additive changes need no migration — an older document simply lacks the newer\n * optional fields. This is the seam for a future BREAKING bump, and\n * `importWorkflow` runs it before validating the version.\n *\n * ## The three rules, each with a reason\n *\n * - **A PAST version migrates forward**, step by step, to the current one.\n * - **A FUTURE version is left ALONE.** We cannot know what a later schema\n * means, and migrating downward would be guessing. Untouched hands it to the\n * version check, which reports it honestly.\n * - **A GAP in the table is left alone too.** A missing step is not a licence\n * to guess.\n *\n * ## Why `steps` is a parameter\n *\n * With only v1 in existence there is no old document to migrate, so a seam\n * tested against the built-in (empty) table is a check that CANNOT fail — it\n * would pass identically against a function that returned its input untouched,\n * which is what this was until the twins needed the same seam.\n *\n * The PHP and Python runtimes carry the identical shape. That mattered more\n * than it sounds: they had no migration at all and errored on any version\n * mismatch, so a v2 bump would have made every stored Op unreadable on exactly\n * the runtimes where durable runs resume.\n */\nexport function migrateSchema(\n schema: unknown,\n steps: Record<number, MigrationStep> = MIGRATIONS,\n): unknown {\n if (!schema || typeof schema !== \"object\") return schema;\n\n const doc = schema as Record<string, unknown>;\n let version = doc.version;\n\n if (typeof version !== \"number\" || !Number.isInteger(version) || version >= WORKFLOW_SCHEMA_VERSION) {\n return schema;\n }\n\n let out = doc;\n while (version < WORKFLOW_SCHEMA_VERSION) {\n const step = steps[version];\n if (!step) return out;\n\n out = step(out);\n version += 1;\n out.version = version;\n }\n\n return out;\n}\n\n/**\n * Hydrate a schema into runtime FlowGraph + validate kinds/configs against\n * the registry. Reports issues for unknown kinds, missing required config,\n * and dangling edges.\n */\nexport function importWorkflow(schema: unknown, options: ImportOptions = {}): ImportResult {\n const issues: ImportIssue[] = [];\n const lenient = options.lenient === true;\n schema = migrateSchema(schema);\n\n if (!schema || typeof schema !== \"object\") {\n return { ok: false, graph: { nodes: [], edges: [] }, issues: [{ level: \"error\", message: \"Schema is not an object.\" }] };\n }\n const s = schema as Partial<WorkflowSchema>;\n if (s.version !== WORKFLOW_SCHEMA_VERSION) {\n issues.push({\n level: lenient ? \"warning\" : \"error\",\n message: `Unsupported workflow schema version: ${s.version} (expected ${WORKFLOW_SCHEMA_VERSION})`,\n });\n if (!lenient) return { ok: false, graph: { nodes: [], edges: [] }, issues };\n }\n\n const rawNodes = s.graph?.nodes ?? [];\n const rawEdges = s.graph?.edges ?? [];\n\n const nodes: FlowNode[] = rawNodes.map((n) => {\n const kind = getNodeKind(n.kind);\n if (!kind) {\n issues.push({\n level: lenient ? \"warning\" : \"error\",\n nodeId: n.id,\n message: `Unknown kind \"${n.kind}\" — register it before importing.`,\n });\n }\n const config = n.config ?? (kind ? defaultConfigFor(kind) : {});\n if (kind) {\n for (const iss of validateConfig(kind, config)) {\n issues.push({ level: \"warning\", nodeId: n.id, message: `${iss.key}: ${iss.message}` });\n }\n }\n // Canonicalise on the way in: a document may carry a pre-namespace id, and\n // rewriting it here means the graph converges on the canonical id the next\n // time it is saved, rather than carrying the ambiguous name forever.\n const kindId = kind?.name ?? n.kind;\n return {\n id: n.id,\n type: kindId,\n position: { x: n.position?.x ?? 0, y: n.position?.y ?? 0 },\n // Rehydrate visual layout onto the node's top level (where xyflow reads it).\n ...(n.parentId ? { parentId: n.parentId } : {}),\n ...(n.extent ? { extent: n.extent } : {}),\n ...(typeof n.width === \"number\" ? { width: n.width } : {}),\n ...(typeof n.height === \"number\" ? { height: n.height } : {}),\n ...(n.style ? { style: n.style } : {}),\n data: {\n kind: kindId,\n label: n.label ?? kind?.label ?? n.kind,\n description: n.description,\n ...(n.startingMsg ? { startingMsg: n.startingMsg } : {}),\n ...(n.stoppingMsg ? { stoppingMsg: n.stoppingMsg } : {}),\n config,\n // Carry serialized ports back onto the node so a round-trip is stable\n // and an unknown kind still routes the way the document described.\n ...(n.inputs ? { inputs: n.inputs } : {}),\n ...(n.outputs ? { outputs: n.outputs } : {}),\n } as any,\n };\n });\n\n const nodeIds = new Set(nodes.map((n) => n.id));\n const edges: FlowEdge[] = rawEdges\n .map((e) => {\n if (!nodeIds.has(e.source)) {\n issues.push({ level: \"warning\", edgeId: e.id, message: `Edge source \"${e.source}\" not found.` });\n return null;\n }\n if (!nodeIds.has(e.target)) {\n issues.push({ level: \"warning\", edgeId: e.id, message: `Edge target \"${e.target}\" not found.` });\n return null;\n }\n return {\n id: e.id,\n source: e.source,\n target: e.target,\n sourceHandle: e.sourceHandle,\n targetHandle: e.targetHandle,\n label: e.label,\n } as FlowEdge;\n })\n .filter((e): e is FlowEdge => e !== null);\n\n const ok = issues.every((i) => i.level !== \"error\");\n // The declaration comes back with the graph. Dropping it on import would be\n // the worse half of losing it on export: the document still says what it\n // accepts, the loaded graph does not, and every prop a caller passes becomes\n // \"unknown input\" — an error pointing at the caller for a bug in the loader.\n const declaredInputs = Array.isArray(s.inputs)\n ? (s.inputs as WorkflowInput[]).filter(\n (input): input is WorkflowInput =>\n input !== null && typeof input === \"object\" && typeof (input as WorkflowInput).name === \"string\",\n )\n : undefined;\n\n return {\n ok,\n graph: {\n nodes,\n edges,\n ...(declaredInputs && declaredInputs.length > 0 ? { inputs: declaredInputs } : {}),\n },\n issues,\n };\n}\n\n/** Convenience: serialize a schema as a downloadable JSON Blob. */\nexport function workflowToBlob(schema: WorkflowSchema): Blob {\n return new Blob([JSON.stringify(schema, null, 2)], { type: \"application/json\" });\n}\n"]}
@@ -1,5 +1,5 @@
1
- import { createConnectionValidator, buildNodeTypes } from './chunk-VWANLNL5.js';
2
- import { Handle, Position, NoteNode, reconnectEdge, index, BackgroundVariant, Background, Controls, MiniMap, getNodeKind, categoryAccent, ViewportPortal } from './chunk-CIBW5ATA.js';
1
+ import { createConnectionValidator, buildNodeTypes } from './chunk-E3AGYTHP.js';
2
+ import { Handle, Position, NoteNode, reconnectEdge, index, BackgroundVariant, Background, Controls, MiniMap, getNodeKind, categoryAccent, ViewportPortal } from './chunk-22OJOD4X.js';
3
3
  import { memo, useMemo, useRef, useState, useCallback, useEffect } from 'react';
4
4
  import { jsxs, jsx } from 'react/jsx-runtime';
5
5
 
@@ -621,5 +621,5 @@ function cx(...parts) {
621
621
  }
622
622
 
623
623
  export { ActionNode, DecisionNode, FlowCanvas, FlowViewer, NodeShell, OutputNode, SubgraphNode, TriggerNode, alignNodes, assignToLane, cloneSubgraph, defaultNodeTypes, distributeNodes, duplicateNode, reconnectEdge2 as reconnectEdge, removeEdges, removeFromLane, removeNodes, setEdgeLabel };
624
- //# sourceMappingURL=chunk-FTGVVKWX.js.map
625
- //# sourceMappingURL=chunk-FTGVVKWX.js.map
624
+ //# sourceMappingURL=chunk-HMEI2LFU.js.map
625
+ //# sourceMappingURL=chunk-HMEI2LFU.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/nodes/NodeShell.tsx","../src/components/nodes/TriggerNode.tsx","../src/components/nodes/ActionNode.tsx","../src/components/nodes/DecisionNode.tsx","../src/components/nodes/OutputNode.tsx","../src/components/nodes/SubgraphNode.tsx","../src/components/nodes/index.ts","../src/components/FlowEditor/graph-ops.ts","../src/components/canvas/helper-lines.ts","../src/components/canvas/HelperLines.tsx","../src/components/canvas/use-resolved-color-mode.ts","../src/components/canvas/FlowCanvas.tsx","../src/components/FlowViewer/FlowViewer.tsx"],"names":["jsx","memo","jsxs","reconnectEdge","cx","useState","useMemo","index"],"mappings":"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","file":"chunk-FTGVVKWX.js","sourcesContent":["import { type ReactNode, memo } from \"react\";\nimport { Handle, Position, type NodeProps } from \"@xyflow/react\";\nimport type { FlowNode, NodeRunStatus, PortDescriptor } from \"../../types\";\n\nexport type NodeShellProps = {\n /** Required: the xyflow node this is rendering. */\n node: NodeProps<FlowNode>;\n /** Accent color for the title bar / status ring. */\n accent: string;\n /** Tag/label shown to the left of the title (e.g. \"TRIGGER\", \"ACTION\"). */\n tag: string;\n /** Optional icon glyph (single-character string is fine). */\n icon?: ReactNode;\n /** Whether to show input handles on the left. Defaults true. */\n showInputs?: boolean;\n /** Whether to show output handles on the right. Defaults true. */\n showOutputs?: boolean;\n /** Body content under the title bar. */\n children?: ReactNode;\n};\n\n/**\n * Shared chrome for every kit node — title bar, accent border, status ring,\n * port handles. Specific node kinds compose this with their body content.\n */\nfunction NodeShellInner({\n node,\n accent,\n tag,\n icon,\n showInputs = true,\n showOutputs = true,\n children,\n}: NodeShellProps) {\n const data = node.data;\n const status: NodeRunStatus = data.status ?? \"idle\";\n const inputs = data.inputs ?? defaultInputs(showInputs);\n const outputs = data.outputs ?? defaultOutputs(showOutputs);\n\n return (\n <div\n className={[\"ff-node\", `ff-node--status-${status}`, node.selected ? \"ff-node--selected\" : \"\"].filter(Boolean).join(\" \")}\n style={{ borderColor: node.selected ? accent : undefined }}\n >\n <header className=\"ff-node__header\" style={{ background: accent }}>\n <span className=\"ff-node__icon\" aria-hidden>{icon ?? null}</span>\n <span className=\"ff-node__tag\">{tag}</span>\n <span className=\"ff-node__label\">{data.label}</span>\n {status !== \"idle\" && <StatusDot status={status} />}\n </header>\n\n {data.description && <p className=\"ff-node__desc\">{data.description}</p>}\n {children && <div className=\"ff-node__body\">{children}</div>}\n {data.statusText && <p className=\"ff-node__status-text\">{data.statusText}</p>}\n\n {inputs.map((p, i) => (\n <Handle\n key={p.id}\n type=\"target\"\n position={Position.Left}\n id={p.id}\n style={portStyle(i, inputs.length)}\n title={p.label ?? p.id}\n />\n ))}\n {outputs.map((p, i) => (\n <Handle\n key={p.id}\n type=\"source\"\n position={Position.Right}\n id={p.id}\n style={portStyle(i, outputs.length)}\n title={p.label ?? p.id}\n />\n ))}\n </div>\n );\n}\n\nexport const NodeShell = memo(NodeShellInner);\n\nfunction defaultInputs(show: boolean): PortDescriptor[] {\n return show ? [{ id: \"in\" }] : [];\n}\nfunction defaultOutputs(show: boolean): PortDescriptor[] {\n return show ? [{ id: \"out\" }] : [];\n}\n\nfunction portStyle(i: number, total: number): React.CSSProperties {\n if (total <= 1) return {};\n const slot = (100 / (total + 1)) * (i + 1);\n return { top: `${slot}%` };\n}\n\nfunction StatusDot({ status }: { status: NodeRunStatus }) {\n return <span className={`ff-node__dot ff-node__dot--${status}`} aria-label={`status ${status}`} />;\n}\n","import { memo } from \"react\";\nimport type { NodeProps } from \"@xyflow/react\";\nimport type { FlowNode } from \"../../types\";\nimport { NodeShell } from \"./NodeShell\";\n\n/** Entry-point node — outputs only, no inputs. */\nfunction TriggerNodeInner(props: NodeProps<FlowNode>) {\n return <NodeShell node={props} accent=\"#10b981\" tag=\"TRIGGER\" icon=\"⚡\" showInputs={false} />;\n}\nexport const TriggerNode = memo(TriggerNodeInner);\n","import { memo } from \"react\";\nimport type { NodeProps } from \"@xyflow/react\";\nimport type { FlowNode } from \"../../types\";\nimport { NodeShell } from \"./NodeShell\";\n\n/** General-purpose work node — inputs and outputs. */\nfunction ActionNodeInner(props: NodeProps<FlowNode>) {\n return <NodeShell node={props} accent=\"#3b82f6\" tag=\"ACTION\" icon=\"▸\" />;\n}\nexport const ActionNode = memo(ActionNodeInner);\n","import { memo } from \"react\";\nimport type { NodeProps } from \"@xyflow/react\";\nimport type { FlowNode, PortDescriptor } from \"../../types\";\nimport { NodeShell } from \"./NodeShell\";\n\nconst DEFAULT_BRANCHES: PortDescriptor[] = [\n { id: \"true\", label: \"true\" },\n { id: \"false\", label: \"false\" },\n];\n\n/** Branching node — multiple typed outputs, one input. */\nfunction DecisionNodeInner(props: NodeProps<FlowNode>) {\n // If the host hasn't customised outputs, default to a true/false split.\n if (!props.data.outputs) {\n props = { ...props, data: { ...props.data, outputs: DEFAULT_BRANCHES } };\n }\n return <NodeShell node={props} accent=\"#f59e0b\" tag=\"DECISION\" icon=\"◇\" />;\n}\nexport const DecisionNode = memo(DecisionNodeInner);\n","import { memo } from \"react\";\nimport type { NodeProps } from \"@xyflow/react\";\nimport type { FlowNode } from \"../../types\";\nimport { NodeShell } from \"./NodeShell\";\n\n/** Terminal node — receives the workflow's final result; no outputs. */\nfunction OutputNodeInner(props: NodeProps<FlowNode>) {\n return <NodeShell node={props} accent=\"#a855f7\" tag=\"OUTPUT\" icon=\"●\" showOutputs={false} />;\n}\nexport const OutputNode = memo(OutputNodeInner);\n","import { memo } from \"react\";\nimport type { NodeProps } from \"@xyflow/react\";\nimport type { FlowNode, SubgraphNodeData } from \"../../types\";\nimport { NodeShell } from \"./NodeShell\";\n\n/**\n * SubgraphNode — collapses a group of nodes behind a single facade with\n * inputs and outputs that map to the inner graph's boundary ports. The\n * runtime treats it like an action node: when running, it dispatches to\n * the registered \"subgraph\" executor (host decides expand vs inline).\n *\n * v0.1 just renders the facade. Expand/collapse interactions and inner-\n * graph editing are deferred — host apps can implement those by toggling\n * `data.collapsed` and rendering a nested <FlowCanvas> when expanded.\n */\nfunction SubgraphNodeInner(props: NodeProps<FlowNode>) {\n const data = props.data as SubgraphNodeData;\n const childCount = data.childIds?.length ?? 0;\n return (\n <NodeShell node={props} accent=\"#0ea5e9\" tag=\"SUBGRAPH\" icon=\"❐\">\n <div className=\"ff-subgraph__meta\">\n <span>{childCount} node{childCount === 1 ? \"\" : \"s\"}</span>\n <span>{data.collapsed === false ? \"expanded\" : \"collapsed\"}</span>\n </div>\n </NodeShell>\n );\n}\nexport const SubgraphNode = memo(SubgraphNodeInner);\n","import type { NodeTypes } from \"@xyflow/react\";\nimport { TriggerNode } from \"./TriggerNode\";\nimport { ActionNode } from \"./ActionNode\";\nimport { DecisionNode } from \"./DecisionNode\";\nimport { OutputNode } from \"./OutputNode\";\nimport { NoteNode } from \"./NoteNode\";\nimport { SubgraphNode } from \"./SubgraphNode\";\n\nexport { TriggerNode, ActionNode, DecisionNode, OutputNode, NoteNode, SubgraphNode };\nexport { LaneNode } from \"./LaneNode\";\nexport { NodeShell, type NodeShellProps } from \"./NodeShell\";\n\n/**\n * Default xyflow `nodeTypes` map covering the kit. Spread into your own:\n *\n * <FlowCanvas nodeTypes={{ ...defaultNodeTypes, custom: MyNode }} ... />\n */\nexport const defaultNodeTypes: NodeTypes = {\n trigger: TriggerNode,\n action: ActionNode,\n decision: DecisionNode,\n output: OutputNode,\n note: NoteNode,\n subgraph: SubgraphNode,\n};\n","import { reconnectEdge as xyReconnectEdge, type Connection, type Edge } from \"@xyflow/react\";\nimport type { FlowGraph, FlowNode } from \"../../types\";\n\n/**\n * Remove nodes AND every edge attached to them.\n *\n * Deleting a node without pruning its edges leaves danglers that point at\n * nothing — they survive a round-trip through the schema and blow up the\n * runner, so the two always move together.\n */\nexport function removeNodes(graph: FlowGraph, ids: string[]): FlowGraph {\n if (ids.length === 0) return graph;\n const doomed = new Set(ids);\n\n return {\n nodes: graph.nodes.filter((n) => !doomed.has(n.id)),\n edges: graph.edges.filter((e) => !doomed.has(e.source) && !doomed.has(e.target)),\n };\n}\n\n/** Remove edges by id, leaving nodes untouched. */\nexport function removeEdges(edges: Edge[], ids: string[]): Edge[] {\n if (ids.length === 0) return edges;\n const doomed = new Set(ids);\n\n return edges.filter((e) => !doomed.has(e.id));\n}\n\n/**\n * Set (or clear) an edge's label.\n *\n * An empty/whitespace label is removed rather than stored as `\"\"` — xyflow\n * renders an empty label as an empty chip on the wire, and a blank key would\n * survive export into the workflow schema.\n */\nexport function setEdgeLabel(edges: Edge[], id: string, label: string | undefined): Edge[] {\n const next = label?.trim();\n return edges.map((e) => {\n if (e.id !== id) return e;\n if (!next) {\n const { label: _drop, ...rest } = e;\n return rest as Edge;\n }\n return { ...e, label: next };\n });\n}\n\n/** Copy a node with a fresh id, offset so it doesn't sit exactly on top. */\nexport function duplicateNode(node: FlowNode, id: string, offset = 40): FlowNode {\n return {\n ...node,\n id,\n position: { x: node.position.x + offset, y: node.position.y + offset },\n // Deep copy so the clone's config edits don't mutate the original.\n data: JSON.parse(JSON.stringify(node.data ?? {})),\n } as FlowNode;\n}\n\n/**\n * Clone a set of nodes AND the edges internal to that set, remapping every id.\n * This is the piece `duplicateNode` lacks: a copy/paste (or duplicate-selection)\n * that preserves the wiring *between* the copied nodes. Edges with an endpoint\n * outside the set are dropped (they'd dangle). A `parentId` pointing inside the\n * set is remapped; one pointing outside is detached.\n */\nexport function cloneSubgraph(\n nodes: FlowNode[],\n edges: Edge[],\n opts: { makeId: () => string; offset?: number },\n): { nodes: FlowNode[]; edges: Edge[]; idMap: Map<string, string> } {\n const offset = opts.offset ?? 40;\n const idMap = new Map<string, string>();\n for (const n of nodes) idMap.set(n.id, opts.makeId());\n\n const clonedNodes = nodes.map((n) => {\n const cloned = duplicateNode(n, idMap.get(n.id)!, offset) as any;\n const parentId = (n as any).parentId;\n if (parentId && idMap.has(parentId)) cloned.parentId = idMap.get(parentId);\n else if (parentId) delete cloned.parentId;\n return cloned as FlowNode;\n });\n\n const clonedEdges = edges\n .filter((e) => idMap.has(e.source) && idMap.has(e.target))\n .map((e) => ({ ...e, id: opts.makeId(), source: idMap.get(e.source)!, target: idMap.get(e.target)! }));\n\n return { nodes: clonedNodes, edges: clonedEdges, idMap };\n}\n\n/**\n * Rewire one edge's endpoint(s) — wraps xyflow's `reconnectEdge`. Keeps the\n * edge's id (`shouldReplaceId: false`) so its label and identity survive the\n * rewire instead of being regenerated from the new endpoints.\n */\nexport function reconnectEdge(edges: Edge[], oldEdge: Edge, newConnection: Connection): Edge[] {\n return xyReconnectEdge(oldEdge, newConnection, edges, { shouldReplaceId: false });\n}\n\nexport type AlignEdge = \"left\" | \"hcenter\" | \"right\" | \"top\" | \"vcenter\" | \"bottom\";\n\nconst nodeW = (n: FlowNode): number => (n as any).width ?? (n as any).measured?.width ?? 0;\nconst nodeH = (n: FlowNode): number => (n as any).height ?? (n as any).measured?.height ?? 0;\n\n/** Align a selection to a shared edge/center of its bounding box. */\nexport function alignNodes(nodes: FlowNode[], edge: AlignEdge): FlowNode[] {\n if (nodes.length < 2) return nodes;\n const minL = Math.min(...nodes.map((n) => n.position.x));\n const maxR = Math.max(...nodes.map((n) => n.position.x + nodeW(n)));\n const minT = Math.min(...nodes.map((n) => n.position.y));\n const maxB = Math.max(...nodes.map((n) => n.position.y + nodeH(n)));\n const cx = (minL + maxR) / 2;\n const cy = (minT + maxB) / 2;\n return nodes.map((n) => {\n let { x, y } = n.position;\n if (edge === \"left\") x = minL;\n else if (edge === \"right\") x = maxR - nodeW(n);\n else if (edge === \"hcenter\") x = cx - nodeW(n) / 2;\n else if (edge === \"top\") y = minT;\n else if (edge === \"bottom\") y = maxB - nodeH(n);\n else if (edge === \"vcenter\") y = cy - nodeH(n) / 2;\n return { ...n, position: { x, y } };\n });\n}\n\n/**\n * Order nodes so every parent precedes its children — xyflow misrenders (and\n * warns) when a child appears before its `parentId` in the array. Stable\n * otherwise. Apply at the render boundary once grouping is in play.\n */\nexport function sortNodesParentFirst<T extends { id: string; parentId?: string }>(nodes: T[]): T[] {\n const byId = new Map(nodes.map((n) => [n.id, n] as const));\n const seen = new Set<string>();\n const out: T[] = [];\n const visit = (n: T) => {\n if (seen.has(n.id)) return;\n const pid = (n as any).parentId as string | undefined;\n if (pid && byId.has(pid) && !seen.has(pid)) visit(byId.get(pid)!);\n seen.add(n.id);\n out.push(n);\n };\n for (const n of nodes) visit(n);\n return out;\n}\n\n/** Absolute position of a node, accounting for one level of parent nesting. */\nfunction absolutePosition(node: FlowNode, nodes: FlowNode[]): { x: number; y: number } {\n const pid = (node as any).parentId as string | undefined;\n if (!pid) return node.position;\n const parent = nodes.find((n) => n.id === pid);\n return parent ? { x: node.position.x + parent.position.x, y: node.position.y + parent.position.y } : node.position;\n}\n\n/**\n * Put a node inside a lane/container: set `parentId` + `extent:'parent'` and\n * convert its position to be relative to the lane. Idempotent-safe; a no-op if\n * either id is missing or they're the same node.\n */\nexport function assignToLane(nodes: FlowNode[], nodeId: string, laneId: string): FlowNode[] {\n if (nodeId === laneId) return nodes;\n const node = nodes.find((n) => n.id === nodeId);\n const lane = nodes.find((n) => n.id === laneId);\n if (!node || !lane) return nodes;\n const abs = absolutePosition(node, nodes);\n const laneAbs = absolutePosition(lane, nodes);\n const rel = { x: abs.x - laneAbs.x, y: abs.y - laneAbs.y };\n return nodes.map((n) => (n.id === nodeId ? ({ ...n, parentId: laneId, extent: \"parent\", position: rel } as FlowNode) : n));\n}\n\n/** Take a node out of its lane: drop `parentId`/`extent`, restore absolute position. */\nexport function removeFromLane(nodes: FlowNode[], nodeId: string): FlowNode[] {\n const node = nodes.find((n) => n.id === nodeId);\n if (!node || !(node as any).parentId) return nodes;\n const abs = absolutePosition(node, nodes);\n return nodes.map((n) => {\n if (n.id !== nodeId) return n;\n const { parentId: _p, extent: _e, ...rest } = n as any;\n return { ...rest, position: abs } as FlowNode;\n });\n}\n\n/**\n * Stack lanes into contiguous rows (horizontal) or columns (vertical) — the\n * \"fixed rows/columns\" behavior. `isLane` picks which nodes are lanes; they're\n * ordered by their current cross-axis position and repacked from the first\n * lane's origin. Each lane keeps its own size (independently resizable).\n */\nexport function stackLanes(\n nodes: FlowNode[],\n isLane: (n: FlowNode) => boolean,\n opts: { orientation?: \"horizontal\" | \"vertical\"; gap?: number } = {},\n): FlowNode[] {\n const orientation = opts.orientation ?? \"horizontal\";\n const gap = opts.gap ?? 12;\n const vertical = orientation === \"vertical\";\n const lanes = nodes.filter(isLane).sort((a, b) => (vertical ? a.position.x - b.position.x : a.position.y - b.position.y));\n if (lanes.length === 0) return nodes;\n const originX = lanes[0].position.x;\n const originY = lanes[0].position.y;\n const moves = new Map<string, { x: number; y: number }>();\n let cursor = vertical ? originX : originY;\n for (const lane of lanes) {\n moves.set(lane.id, vertical ? { x: cursor, y: originY } : { x: originX, y: cursor });\n cursor += (vertical ? ((lane as any).width ?? 320) : ((lane as any).height ?? 160)) + gap;\n }\n return nodes.map((n) => (moves.has(n.id) ? { ...n, position: moves.get(n.id)! } : n));\n}\n\n/** Evenly distribute a selection's gaps along an axis (needs 3+ nodes). */\nexport function distributeNodes(nodes: FlowNode[], axis: \"h\" | \"v\"): FlowNode[] {\n if (nodes.length < 3) return nodes;\n const size = (n: FlowNode) => (axis === \"h\" ? nodeW(n) : nodeH(n));\n const coord = (n: FlowNode) => (axis === \"h\" ? n.position.x : n.position.y);\n const sorted = [...nodes].sort((a, b) => coord(a) - coord(b));\n const start = coord(sorted[0]);\n const last = sorted[sorted.length - 1];\n const end = coord(last) + size(last);\n const totalSize = sorted.reduce((s, n) => s + size(n), 0);\n const gap = (end - start - totalSize) / (sorted.length - 1);\n const posById = new Map<string, number>();\n let cursor = start;\n for (const n of sorted) {\n posById.set(n.id, cursor);\n cursor += size(n) + gap;\n }\n return nodes.map((n) => {\n const p = posById.get(n.id)!;\n return { ...n, position: axis === \"h\" ? { ...n.position, x: p } : { ...n.position, y: p } };\n });\n}\n","import type { FlowNode } from \"../../types\";\n\nexport type HelperLineChange = { id: string; position?: { x: number; y: number } };\n\nexport type HelperLinesResult = {\n /** Y of a horizontal guide line (flow coords), if the drag aligns on Y. */\n horizontal?: number;\n /** X of a vertical guide line (flow coords), if the drag aligns on X. */\n vertical?: number;\n /** The snapped position to apply to the dragged node. */\n snapPosition: { x?: number; y?: number };\n};\n\nconst w = (n: FlowNode): number => (n as any).width ?? (n as any).measured?.width ?? 0;\nconst h = (n: FlowNode): number => (n as any).height ?? (n as any).measured?.height ?? 0;\n\n/**\n * Compute alignment guide lines (and a snapped position) for a node being\n * dragged to `change.position`, against the other nodes. Standard \"helper\n * lines\" algorithm: match the dragged node's left/right/top/bottom edges to any\n * other node's edges within `distance`, snapping to the nearest. Pure + testable.\n */\nexport function getHelperLines(change: HelperLineChange, nodes: FlowNode[], distance = 6): HelperLinesResult {\n const result: HelperLinesResult = { snapPosition: { x: undefined, y: undefined } };\n const a = nodes.find((n) => n.id === change.id);\n if (!a || !change.position) return result;\n\n const A = {\n left: change.position.x,\n right: change.position.x + w(a),\n top: change.position.y,\n bottom: change.position.y + h(a),\n width: w(a),\n height: h(a),\n };\n let vDist = distance;\n let hDist = distance;\n\n for (const b of nodes) {\n if (b.id === a.id) continue;\n const B = { left: b.position.x, right: b.position.x + w(b), top: b.position.y, bottom: b.position.y + h(b) };\n\n // Vertical guides (X alignment).\n const ll = Math.abs(A.left - B.left);\n if (ll < vDist) { result.snapPosition.x = B.left; result.vertical = B.left; vDist = ll; }\n const rr = Math.abs(A.right - B.right);\n if (rr < vDist) { result.snapPosition.x = B.right - A.width; result.vertical = B.right; vDist = rr; }\n const lr = Math.abs(A.left - B.right);\n if (lr < vDist) { result.snapPosition.x = B.right; result.vertical = B.right; vDist = lr; }\n const rl = Math.abs(A.right - B.left);\n if (rl < vDist) { result.snapPosition.x = B.left - A.width; result.vertical = B.left; vDist = rl; }\n\n // Horizontal guides (Y alignment).\n const tt = Math.abs(A.top - B.top);\n if (tt < hDist) { result.snapPosition.y = B.top; result.horizontal = B.top; hDist = tt; }\n const bb = Math.abs(A.bottom - B.bottom);\n if (bb < hDist) { result.snapPosition.y = B.bottom - A.height; result.horizontal = B.bottom; hDist = bb; }\n const tb = Math.abs(A.top - B.bottom);\n if (tb < hDist) { result.snapPosition.y = B.bottom; result.horizontal = B.bottom; hDist = tb; }\n const bt = Math.abs(A.bottom - B.top);\n if (bt < hDist) { result.snapPosition.y = B.top - A.height; result.horizontal = B.top; hDist = bt; }\n }\n\n return result;\n}\n","import { ViewportPortal } from \"@xyflow/react\";\n\n/**\n * HelperLines — alignment guides drawn during a drag. Rendered in flow\n * coordinate space (ViewportPortal), so the lines track pan/zoom. Positions come\n * from `getHelperLines`.\n */\nexport function HelperLines({ horizontal, vertical }: { horizontal?: number; vertical?: number }) {\n if (horizontal === undefined && vertical === undefined) return null;\n return (\n <ViewportPortal>\n {vertical !== undefined && (\n <div\n className=\"ff-helper-line\"\n style={{ position: \"absolute\", transform: `translateX(${vertical}px)`, top: -5000, height: 10000, width: 1, pointerEvents: \"none\" }}\n />\n )}\n {horizontal !== undefined && (\n <div\n className=\"ff-helper-line\"\n style={{ position: \"absolute\", transform: `translateY(${horizontal}px)`, left: -5000, width: 10000, height: 1, pointerEvents: \"none\" }}\n />\n )}\n </ViewportPortal>\n );\n}\n","import { useEffect, useState } from \"react\";\n\n/** The resolved mode React Flow and our own `ff-` tokens both understand. */\nexport type FlowColorMode = \"light\" | \"dark\";\n\n/**\n * What a host may PASS. React Flow's own `ColorMode` includes `\"system\"`, and\n * it is meaningful here rather than something to cast away: it means \"follow\n * the environment\", which is the same job `undefined` now does.\n */\nexport type FlowColorModeInput = FlowColorMode | \"system\";\n\n/**\n * Read the app's theme off the document, the way every host in this suite\n * signals it.\n *\n * Checked in the order a host actually sets them: an explicit `data-theme`\n * beats a `.dark` class (a host that writes both, like the showcase, is\n * consistent either way), and only when neither is present does the OS\n * preference decide.\n */\nfunction readDocumentTheme(): FlowColorMode {\n if (typeof document === \"undefined\") return \"light\";\n\n const root = document.documentElement;\n const attr = root.getAttribute(\"data-theme\");\n if (attr === \"dark\" || attr === \"light\") return attr;\n if (root.classList.contains(\"dark\")) return \"dark\";\n\n return typeof window !== \"undefined\" && window.matchMedia?.(\"(prefers-color-scheme: dark)\").matches\n ? \"dark\"\n : \"light\";\n}\n\n/**\n * The colour mode the canvas should actually use.\n *\n * **Why this exists.** `colorMode` used to be passed straight through to React\n * Flow, so a host that did not supply one got React Flow's own default —\n * `light` — no matter what the surrounding app was doing. Our `ff-` styles\n * still looked right, because they hang off an ancestor `.dark`, which is\n * exactly what made the bug hard to see: the nodes we style were fine while\n * React Flow's own layer stayed light underneath. Any node whose kind is not\n * registered falls back to React Flow's default node, and on a dark page that\n * is a white box with unreadable text. Edges, handles, the selection rectangle\n * and the controls were light too.\n *\n * So an unset `colorMode` now means \"follow the app\", not \"light\". Passing one\n * explicitly still wins — a canvas deliberately pinned light on a dark page is\n * a real thing, and this does not take it away.\n *\n * The subscription matters as much as the initial read: a theme toggle changes\n * an attribute on `<html>`, which triggers no React render on its own, so\n * without an observer the canvas would be correct on load and wrong the moment\n * someone flipped the switch.\n */\nexport function useResolvedColorMode(explicit?: FlowColorModeInput): FlowColorMode {\n // Start light on the server and on first paint. Reading the DOM in the\n // initialiser would differ between server and client markup and trip\n // hydration; the effect below corrects it before anything is visible.\n const [resolved, setResolved] = useState<FlowColorMode>(\"light\");\n\n // `\"system\"` is treated exactly like an unset prop: both mean \"follow the\n // environment\", and collapsing them here keeps one resolution path.\n const pinned = explicit === \"light\" || explicit === \"dark\" ? explicit : undefined;\n\n useEffect(() => {\n if (pinned) return;\n if (typeof document === \"undefined\") return;\n\n const sync = () => setResolved(readDocumentTheme());\n sync();\n\n const observer = new MutationObserver(sync);\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: [\"class\", \"data-theme\"],\n });\n\n const media = window.matchMedia?.(\"(prefers-color-scheme: dark)\");\n media?.addEventListener?.(\"change\", sync);\n\n return () => {\n observer.disconnect();\n media?.removeEventListener?.(\"change\", sync);\n };\n }, [pinned]);\n\n return pinned ?? resolved;\n}\n","import {\n type CSSProperties,\n type ReactNode,\n type WheelEvent as ReactWheelEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n ReactFlow,\n Background,\n BackgroundVariant,\n Controls,\n MiniMap,\n type DefaultEdgeOptions,\n type Edge,\n type EdgeTypes,\n type FitViewOptions,\n type NodeTypes,\n type ReactFlowProps,\n} from \"@xyflow/react\";\nimport \"@xyflow/react/dist/style.css\";\nimport { defaultNodeTypes } from \"../nodes\";\nimport { createConnectionValidator, type ConnectionValidatorOptions } from \"../../registry/connection\";\nimport { sortNodesParentFirst } from \"../FlowEditor/graph-ops\";\nimport { getHelperLines } from \"./helper-lines\";\nimport { HelperLines } from \"./HelperLines\";\nimport type { FlowNode } from \"../../types\";\nimport { useResolvedColorMode } from \"./use-resolved-color-mode\";\n\n/**\n * With wheel-zoom off, Shift+wheel still zooms — and must not ALSO scroll the\n * page while it does. React Flow's own `preventScrolling` is all-or-nothing, so\n * the modifier case is handled here: swallow the gesture that zooms, leave the\n * one that doesn't alone.\n *\n * Capture phase, so it lands before React Flow's own wheel handling.\n */\nfunction preventScrollWhileZooming(event: ReactWheelEvent<HTMLDivElement>): void {\n if (event.shiftKey) event.preventDefault();\n}\n\n/**\n * The three React Flow props that together decide what the wheel does.\n *\n * Extracted because they only make sense as a set, and getting the set wrong is\n * invisible in a screenshot: the canvas looks fine and feels broken. This is\n * the unit worth testing — mounting a canvas to assert it would be testing\n * d3-zoom through jsdom.\n *\n * - **on** (default): no modifier needed, and the page never scrolls under a\n * wheel that is zooming.\n * - **off**: zoom moves to Shift+wheel and the bare wheel goes back to the\n * page. `preventScrolling` alone cannot express that — left true it swallows\n * the bare wheel (page frozen, nothing zooms), left false it lets Shift+wheel\n * zoom *and* scroll at once — so the handler covers the modifier case.\n */\nexport function wheelZoomProps(zoomOnWheel: boolean): {\n zoomActivationKeyCode: string | null;\n preventScrolling: boolean;\n onWheelCapture?: (event: ReactWheelEvent<HTMLDivElement>) => void;\n} {\n return zoomOnWheel\n ? { zoomActivationKeyCode: null, preventScrolling: true }\n : {\n zoomActivationKeyCode: \"Shift\",\n preventScrolling: false,\n onWheelCapture: preventScrollWhileZooming,\n };\n}\n\nexport type FlowCanvasProps = Omit<ReactFlowProps<FlowNode, Edge>, \"nodes\" | \"edges\" | \"height\"> & {\n nodes: FlowNode[];\n edges: Edge[];\n /** Background variant. Default: \"dots\". */\n background?: BackgroundVariant | \"none\";\n /** Show pan/zoom/fit controls. Default true. */\n showControls?: boolean;\n /** Show minimap. Default false (turn on for big graphs). */\n showMinimap?: boolean;\n /** Pixel height; FlowCanvas expects a sized container. Default 600. */\n height?: number | string;\n /**\n * Enforce port-type compatibility on new connections. `true` (default) uses\n * the built-in validator: a connection is refused only when both ports\n * declare a concrete, differing `type` (so untyped graphs are unaffected),\n * and self-loops are blocked. Pass options to tune the rule, or `false` to\n * disable. An `isValidConnection` you pass yourself always takes precedence.\n */\n validateConnections?: boolean | ConnectionValidatorOptions;\n /** Show alignment guide lines while dragging, and snap to them. Default off. */\n showHelperLines?: boolean;\n /**\n * A bare mouse wheel over the canvas zooms it. Default **true**.\n *\n * Turn it off for a canvas embedded mid-page, where a reader scrolling past\n * would otherwise get trapped zooming. With it off the wheel scrolls the page\n * and **Shift+wheel** zooms instead.\n *\n * Either way, a wheel gesture that zooms never also scrolls the page — the\n * two happening at once is the thing that makes an embedded canvas feel\n * broken.\n */\n zoomOnWheel?: boolean;\n /** Optional toolbar / palette etc. rendered above the canvas. */\n toolbar?: ReactNode;\n className?: string;\n style?: CSSProperties;\n};\n\nconst DEFAULT_FIT_VIEW: FitViewOptions = { padding: 0.2 };\nconst DEFAULT_EDGE_OPTIONS: DefaultEdgeOptions = {\n type: \"smoothstep\",\n animated: false,\n};\n\n/**\n * FlowCanvas — themed React Flow surface with the kit's nodes registered\n * by default. Pass your own `nodeTypes` to extend; the kit's defaults are\n * merged behind yours.\n *\n * Hosts wire `onNodesChange` / `onEdgesChange` / `onConnect` themselves\n * (xyflow's standard pattern). The surrounding `useFlowState` hook in\n * `runtime/use-flow-state.ts` is a convenience that wires those for you.\n */\nexport function FlowCanvas({\n nodes,\n edges,\n background = BackgroundVariant.Dots,\n showControls = true,\n showMinimap = false,\n height = 600,\n validateConnections = true,\n isValidConnection,\n colorMode,\n showHelperLines = false,\n zoomOnWheel = true,\n onNodesChange,\n toolbar,\n nodeTypes,\n edgeTypes,\n className,\n style,\n ...rest\n}: FlowCanvasProps) {\n const mergedNodeTypes = useMemo<NodeTypes>(\n () => ({ ...defaultNodeTypes, ...(nodeTypes ?? {}) }),\n [nodeTypes],\n );\n\n // Read nodes live through a ref so the validator (built once) always sees the\n // current graph without being rebuilt on every node change.\n const nodesRef = useRef(nodes);\n nodesRef.current = nodes;\n const builtinValidator = useMemo(\n () =>\n validateConnections === false\n ? undefined\n : createConnectionValidator(\n () => nodesRef.current,\n validateConnections === true ? undefined : validateConnections,\n ),\n [validateConnections],\n );\n // A caller-supplied predicate wins; otherwise fall back to port-type validation.\n const resolvedIsValidConnection = isValidConnection ?? builtinValidator;\n\n const mergedEdgeTypes = useMemo<EdgeTypes | undefined>(\n () => (edgeTypes ? { ...edgeTypes } : undefined),\n [edgeTypes],\n );\n\n // xyflow requires a parent node to precede its children in the array; grouping\n // (swimlanes) can produce any order, so normalize it here at the boundary.\n const orderedNodes = useMemo(() => sortNodesParentFirst(nodes), [nodes]);\n\n // Helper lines: on a single-node drag, snap to aligned edges + show guides.\n const [helperLines, setHelperLines] = useState<{ horizontal?: number; vertical?: number }>({});\n const handleNodesChange = useCallback(\n (changes: any[]) => {\n if (showHelperLines) {\n const pos = changes.filter((c) => c.type === \"position\" && c.position);\n if (pos.length === 1 && pos[0].dragging) {\n const lines = getHelperLines(pos[0], nodesRef.current);\n if (lines.snapPosition.x !== undefined) pos[0].position.x = lines.snapPosition.x;\n if (lines.snapPosition.y !== undefined) pos[0].position.y = lines.snapPosition.y;\n setHelperLines({ horizontal: lines.horizontal, vertical: lines.vertical });\n } else {\n setHelperLines({});\n }\n }\n onNodesChange?.(changes as any);\n },\n [showHelperLines, onNodesChange],\n );\n\n /**\n * An unset `colorMode` means \"follow the app\", NOT \"light\".\n *\n * It used to pass straight through to React Flow, whose own default is\n * light — so on a dark page React Flow's layer stayed light underneath our\n * `ff-` styles, which look right because they hang off an ancestor `.dark`.\n * Any node kind without a registered type falls back to React Flow's default\n * node: a white box with unreadable text on a dark canvas. Passing a mode\n * explicitly still wins.\n */\n const resolvedColorMode = useResolvedColorMode(colorMode);\n\n return (\n <div\n className={[\n \"ff-canvas\",\n // colorMode drives BOTH react-flow's chrome (below) and our `ff-` styles\n // via the shared `.dark` class / light opt-out — one theme signal.\n resolvedColorMode === \"dark\" ? \"dark\" : \"\",\n resolvedColorMode === \"light\" ? \"ff-canvas--light\" : \"\",\n className ?? \"\",\n ]\n .filter(Boolean)\n .join(\" \")}\n style={{ height, ...style }}\n >\n {toolbar && <div className=\"ff-canvas__toolbar\">{toolbar}</div>}\n <div className=\"ff-canvas__surface\">\n <ReactFlow\n nodes={orderedNodes}\n edges={edges}\n onNodesChange={handleNodesChange}\n colorMode={resolvedColorMode}\n nodeTypes={mergedNodeTypes}\n edgeTypes={mergedEdgeTypes}\n fitView\n fitViewOptions={DEFAULT_FIT_VIEW}\n defaultEdgeOptions={DEFAULT_EDGE_OPTIONS}\n proOptions={{ hideAttribution: true }}\n // Wheel zooms by default; `zoomOnWheel={false}` moves that onto\n // Shift+wheel and gives the bare wheel back to the page. The three\n // props only make sense as a set — see wheelZoomProps.\n {...wheelZoomProps(zoomOnWheel)}\n isValidConnection={resolvedIsValidConnection}\n {...rest}\n >\n {background !== \"none\" && (\n <Background variant={background as BackgroundVariant} gap={20} size={1} color=\"rgba(0,0,0,0.18)\" />\n )}\n {showControls && <Controls className=\"ff-controls\" position=\"bottom-right\" />}\n {showMinimap && <MiniMap className=\"ff-minimap\" pannable zoomable />}\n {showHelperLines && <HelperLines horizontal={helperLines.horizontal} vertical={helperLines.vertical} />}\n </ReactFlow>\n </div>\n </div>\n );\n}\n","import { useMemo, type CSSProperties, type ReactNode } from \"react\";\nimport { FlowCanvas } from \"../canvas\";\nimport { buildNodeTypes } from \"../../registry\";\nimport { categoryAccent, getNodeKind } from \"../../registry/registry\";\nimport type { FlowGraph, FlowNode } from \"../../types\";\n\n/** Outcome of one node in a run, for annotating the graph after the fact. */\nexport type FlowNodeStatus = \"ok\" | \"running\" | \"failed\" | \"skipped\" | \"pending\";\n\nexport interface FlowViewerClassNames {\n root?: string;\n list?: string;\n row?: string;\n rowIndex?: string;\n rowTitle?: string;\n rowDescription?: string;\n rowStatus?: string;\n}\n\nexport interface FlowViewerProps {\n /** The graph to show. */\n graph: FlowGraph;\n /**\n * `canvas` draws the graph. `list` renders the nodes as rows — for a docs\n * page, a narrow column, print, or an audit view, where a pan-zoom surface is\n * the wrong shape and often not usable at all.\n */\n variant?: \"canvas\" | \"list\";\n /** Canvas height. Ignored by `list`. Default 480. */\n height?: number | string;\n /** Canvas minimap. Default false. */\n showMinimap?: boolean;\n /** Canvas pan/zoom/fit controls. Default true. */\n showControls?: boolean;\n /**\n * Per-node run outcome, keyed by node id. Lets the same component serve\n * \"here is the workflow\" and \"here is what happened on Tuesday\".\n */\n statuses?: Record<string, FlowNodeStatus>;\n /** Controlled selection. */\n selectedNodeId?: string | null;\n /** Omit and nothing is clickable — a viewer with no handler is inert. */\n onSelectNode?: (node: FlowNode) => void;\n className?: string;\n classNames?: FlowViewerClassNames;\n style?: CSSProperties;\n /** Rendered when the graph has no nodes. */\n empty?: ReactNode;\n}\n\nconst STATUS_LABEL: Record<FlowNodeStatus, string> = {\n ok: \"ok\",\n running: \"running\",\n failed: \"failed\",\n skipped: \"skipped\",\n pending: \"pending\",\n};\n\n/**\n * FlowViewer — a workflow, read-only.\n *\n * **Read-only by construction, not by configuration.** There is no prop that\n * makes this editable, because a viewer that can be switched into an editor is\n * a viewer somebody eventually switches into an editor by accident. Before this\n * existed the only way to show a flow was `FlowEditor` (the whole editor) or\n * `FlowCanvas` plus four React Flow flags a consumer had to know to pass —\n * assembly, not an affordance, and nothing stopped the next person shipping a\n * fully editable canvas where they wanted a picture.\n *\n * Node titles come from the registry, so `overrideNodeKind()` renames apply\n * here too.\n */\nexport function FlowViewer({\n graph,\n variant = \"canvas\",\n height = 480,\n showMinimap = false,\n showControls = true,\n statuses,\n selectedNodeId = null,\n onSelectNode,\n className,\n classNames = {},\n style,\n empty,\n}: FlowViewerProps) {\n const nodeTypes = useMemo(() => buildNodeTypes(), []);\n\n const rows = useMemo(\n () =>\n graph.nodes.map((node, index) => {\n const kind = getNodeKind(node.data?.kind ?? node.type ?? \"\");\n return {\n node,\n index,\n // The node's own label is the name the AUTHOR gave THIS node (\"Summarize\");\n // the kind label is the generic type name (\"LLM Call\"). Specific wins.\n title: node.data?.label ?? kind?.label ?? node.data?.kind ?? node.id,\n description: kind?.description ?? null,\n accent: kind?.accent ?? categoryAccent(kind?.category ?? \"custom\"),\n status: statuses?.[node.id] ?? null,\n };\n }),\n [graph.nodes, statuses],\n );\n\n if (graph.nodes.length === 0) {\n return (\n <div className={cx(\"ff-viewer ff-viewer--empty\", className, classNames.root)} style={style}>\n {empty ?? <span className=\"ff-viewer__empty\">This flow has no nodes.</span>}\n </div>\n );\n }\n\n if (variant === \"list\") {\n return (\n <div\n className={cx(\"ff-viewer ff-viewer--list\", className, classNames.root)}\n style={style}\n data-flow-viewer=\"list\"\n >\n <ol className={cx(\"ff-viewer__list\", classNames.list)}>\n {rows.map(({ node, index, title, description, accent, status }) => {\n const selected = node.id === selectedNodeId;\n const Row = onSelectNode ? \"button\" : \"div\";\n\n return (\n <li key={node.id}>\n <Row\n {...(onSelectNode\n ? { type: \"button\" as const, onClick: () => onSelectNode(node) }\n : {})}\n className={cx(\n \"ff-viewer__row\",\n selected && \"ff-viewer__row--selected\",\n onSelectNode && \"ff-viewer__row--interactive\",\n classNames.row,\n )}\n data-flow-viewer-node={node.id}\n data-flow-viewer-status={status ?? undefined}\n aria-current={selected || undefined}\n >\n <span\n className={cx(\"ff-viewer__index\", classNames.rowIndex)}\n style={{ backgroundColor: accent }}\n aria-hidden\n >\n {index + 1}\n </span>\n\n <span className=\"ff-viewer__body\">\n <span className={cx(\"ff-viewer__title\", classNames.rowTitle)}>{title}</span>\n {description && (\n <span className={cx(\"ff-viewer__desc\", classNames.rowDescription)}>\n {description}\n </span>\n )}\n </span>\n\n {status && (\n <span\n className={cx(\n \"ff-viewer__status\",\n `ff-viewer__status--${status}`,\n classNames.rowStatus,\n )}\n >\n {STATUS_LABEL[status]}\n </span>\n )}\n </Row>\n </li>\n );\n })}\n </ol>\n </div>\n );\n }\n\n return (\n <div\n className={cx(\"ff-viewer ff-viewer--canvas\", className, classNames.root)}\n style={style}\n data-flow-viewer=\"canvas\"\n >\n <FlowCanvas\n nodes={graph.nodes}\n edges={graph.edges}\n nodeTypes={nodeTypes}\n height={height}\n showControls={showControls}\n showMinimap={showMinimap}\n // The read-only contract. Every mutation path React Flow offers is\n // closed here rather than left to the caller to remember.\n nodesDraggable={false}\n nodesConnectable={false}\n nodesFocusable={Boolean(onSelectNode)}\n edgesFocusable={false}\n elementsSelectable={Boolean(onSelectNode)}\n deleteKeyCode={null}\n selectionKeyCode={null}\n multiSelectionKeyCode={null}\n connectOnClick={false}\n // A canvas embedded mid-page must not trap a reader's scroll.\n zoomOnScroll={false}\n onNodeClick={onSelectNode ? (_, node) => onSelectNode(node as FlowNode) : undefined}\n fitView\n />\n </div>\n );\n}\n\nfunction cx(...parts: Array<string | false | null | undefined>): string {\n return parts.filter(Boolean).join(\" \");\n}\n"]}
1
+ {"version":3,"sources":["../src/components/nodes/NodeShell.tsx","../src/components/nodes/TriggerNode.tsx","../src/components/nodes/ActionNode.tsx","../src/components/nodes/DecisionNode.tsx","../src/components/nodes/OutputNode.tsx","../src/components/nodes/SubgraphNode.tsx","../src/components/nodes/index.ts","../src/components/FlowEditor/graph-ops.ts","../src/components/canvas/helper-lines.ts","../src/components/canvas/HelperLines.tsx","../src/components/canvas/use-resolved-color-mode.ts","../src/components/canvas/FlowCanvas.tsx","../src/components/FlowViewer/FlowViewer.tsx"],"names":["jsx","memo","jsxs","reconnectEdge","cx","useState","useMemo","index"],"mappings":"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","file":"chunk-HMEI2LFU.js","sourcesContent":["import { type ReactNode, memo } from \"react\";\nimport { Handle, Position, type NodeProps } from \"@xyflow/react\";\nimport type { FlowNode, NodeRunStatus, PortDescriptor } from \"../../types\";\n\nexport type NodeShellProps = {\n /** Required: the xyflow node this is rendering. */\n node: NodeProps<FlowNode>;\n /** Accent color for the title bar / status ring. */\n accent: string;\n /** Tag/label shown to the left of the title (e.g. \"TRIGGER\", \"ACTION\"). */\n tag: string;\n /** Optional icon glyph (single-character string is fine). */\n icon?: ReactNode;\n /** Whether to show input handles on the left. Defaults true. */\n showInputs?: boolean;\n /** Whether to show output handles on the right. Defaults true. */\n showOutputs?: boolean;\n /** Body content under the title bar. */\n children?: ReactNode;\n};\n\n/**\n * Shared chrome for every kit node — title bar, accent border, status ring,\n * port handles. Specific node kinds compose this with their body content.\n */\nfunction NodeShellInner({\n node,\n accent,\n tag,\n icon,\n showInputs = true,\n showOutputs = true,\n children,\n}: NodeShellProps) {\n const data = node.data;\n const status: NodeRunStatus = data.status ?? \"idle\";\n const inputs = data.inputs ?? defaultInputs(showInputs);\n const outputs = data.outputs ?? defaultOutputs(showOutputs);\n\n return (\n <div\n className={[\"ff-node\", `ff-node--status-${status}`, node.selected ? \"ff-node--selected\" : \"\"].filter(Boolean).join(\" \")}\n style={{ borderColor: node.selected ? accent : undefined }}\n >\n <header className=\"ff-node__header\" style={{ background: accent }}>\n <span className=\"ff-node__icon\" aria-hidden>{icon ?? null}</span>\n <span className=\"ff-node__tag\">{tag}</span>\n <span className=\"ff-node__label\">{data.label}</span>\n {status !== \"idle\" && <StatusDot status={status} />}\n </header>\n\n {data.description && <p className=\"ff-node__desc\">{data.description}</p>}\n {children && <div className=\"ff-node__body\">{children}</div>}\n {data.statusText && <p className=\"ff-node__status-text\">{data.statusText}</p>}\n\n {inputs.map((p, i) => (\n <Handle\n key={p.id}\n type=\"target\"\n position={Position.Left}\n id={p.id}\n style={portStyle(i, inputs.length)}\n title={p.label ?? p.id}\n />\n ))}\n {outputs.map((p, i) => (\n <Handle\n key={p.id}\n type=\"source\"\n position={Position.Right}\n id={p.id}\n style={portStyle(i, outputs.length)}\n title={p.label ?? p.id}\n />\n ))}\n </div>\n );\n}\n\nexport const NodeShell = memo(NodeShellInner);\n\nfunction defaultInputs(show: boolean): PortDescriptor[] {\n return show ? [{ id: \"in\" }] : [];\n}\nfunction defaultOutputs(show: boolean): PortDescriptor[] {\n return show ? [{ id: \"out\" }] : [];\n}\n\nfunction portStyle(i: number, total: number): React.CSSProperties {\n if (total <= 1) return {};\n const slot = (100 / (total + 1)) * (i + 1);\n return { top: `${slot}%` };\n}\n\nfunction StatusDot({ status }: { status: NodeRunStatus }) {\n return <span className={`ff-node__dot ff-node__dot--${status}`} aria-label={`status ${status}`} />;\n}\n","import { memo } from \"react\";\nimport type { NodeProps } from \"@xyflow/react\";\nimport type { FlowNode } from \"../../types\";\nimport { NodeShell } from \"./NodeShell\";\n\n/** Entry-point node — outputs only, no inputs. */\nfunction TriggerNodeInner(props: NodeProps<FlowNode>) {\n return <NodeShell node={props} accent=\"#10b981\" tag=\"TRIGGER\" icon=\"⚡\" showInputs={false} />;\n}\nexport const TriggerNode = memo(TriggerNodeInner);\n","import { memo } from \"react\";\nimport type { NodeProps } from \"@xyflow/react\";\nimport type { FlowNode } from \"../../types\";\nimport { NodeShell } from \"./NodeShell\";\n\n/** General-purpose work node — inputs and outputs. */\nfunction ActionNodeInner(props: NodeProps<FlowNode>) {\n return <NodeShell node={props} accent=\"#3b82f6\" tag=\"ACTION\" icon=\"▸\" />;\n}\nexport const ActionNode = memo(ActionNodeInner);\n","import { memo } from \"react\";\nimport type { NodeProps } from \"@xyflow/react\";\nimport type { FlowNode, PortDescriptor } from \"../../types\";\nimport { NodeShell } from \"./NodeShell\";\n\nconst DEFAULT_BRANCHES: PortDescriptor[] = [\n { id: \"true\", label: \"true\" },\n { id: \"false\", label: \"false\" },\n];\n\n/** Branching node — multiple typed outputs, one input. */\nfunction DecisionNodeInner(props: NodeProps<FlowNode>) {\n // If the host hasn't customised outputs, default to a true/false split.\n if (!props.data.outputs) {\n props = { ...props, data: { ...props.data, outputs: DEFAULT_BRANCHES } };\n }\n return <NodeShell node={props} accent=\"#f59e0b\" tag=\"DECISION\" icon=\"◇\" />;\n}\nexport const DecisionNode = memo(DecisionNodeInner);\n","import { memo } from \"react\";\nimport type { NodeProps } from \"@xyflow/react\";\nimport type { FlowNode } from \"../../types\";\nimport { NodeShell } from \"./NodeShell\";\n\n/** Terminal node — receives the workflow's final result; no outputs. */\nfunction OutputNodeInner(props: NodeProps<FlowNode>) {\n return <NodeShell node={props} accent=\"#a855f7\" tag=\"OUTPUT\" icon=\"●\" showOutputs={false} />;\n}\nexport const OutputNode = memo(OutputNodeInner);\n","import { memo } from \"react\";\nimport type { NodeProps } from \"@xyflow/react\";\nimport type { FlowNode, SubgraphNodeData } from \"../../types\";\nimport { NodeShell } from \"./NodeShell\";\n\n/**\n * SubgraphNode — collapses a group of nodes behind a single facade with\n * inputs and outputs that map to the inner graph's boundary ports. The\n * runtime treats it like an action node: when running, it dispatches to\n * the registered \"subgraph\" executor (host decides expand vs inline).\n *\n * v0.1 just renders the facade. Expand/collapse interactions and inner-\n * graph editing are deferred — host apps can implement those by toggling\n * `data.collapsed` and rendering a nested <FlowCanvas> when expanded.\n */\nfunction SubgraphNodeInner(props: NodeProps<FlowNode>) {\n const data = props.data as SubgraphNodeData;\n const childCount = data.childIds?.length ?? 0;\n return (\n <NodeShell node={props} accent=\"#0ea5e9\" tag=\"SUBGRAPH\" icon=\"❐\">\n <div className=\"ff-subgraph__meta\">\n <span>{childCount} node{childCount === 1 ? \"\" : \"s\"}</span>\n <span>{data.collapsed === false ? \"expanded\" : \"collapsed\"}</span>\n </div>\n </NodeShell>\n );\n}\nexport const SubgraphNode = memo(SubgraphNodeInner);\n","import type { NodeTypes } from \"@xyflow/react\";\nimport { TriggerNode } from \"./TriggerNode\";\nimport { ActionNode } from \"./ActionNode\";\nimport { DecisionNode } from \"./DecisionNode\";\nimport { OutputNode } from \"./OutputNode\";\nimport { NoteNode } from \"./NoteNode\";\nimport { SubgraphNode } from \"./SubgraphNode\";\n\nexport { TriggerNode, ActionNode, DecisionNode, OutputNode, NoteNode, SubgraphNode };\nexport { LaneNode } from \"./LaneNode\";\nexport { NodeShell, type NodeShellProps } from \"./NodeShell\";\n\n/**\n * Default xyflow `nodeTypes` map covering the kit. Spread into your own:\n *\n * <FlowCanvas nodeTypes={{ ...defaultNodeTypes, custom: MyNode }} ... />\n */\nexport const defaultNodeTypes: NodeTypes = {\n trigger: TriggerNode,\n action: ActionNode,\n decision: DecisionNode,\n output: OutputNode,\n note: NoteNode,\n subgraph: SubgraphNode,\n};\n","import { reconnectEdge as xyReconnectEdge, type Connection, type Edge } from \"@xyflow/react\";\nimport type { FlowGraph, FlowNode } from \"../../types\";\n\n/**\n * Remove nodes AND every edge attached to them.\n *\n * Deleting a node without pruning its edges leaves danglers that point at\n * nothing — they survive a round-trip through the schema and blow up the\n * runner, so the two always move together.\n */\nexport function removeNodes(graph: FlowGraph, ids: string[]): FlowGraph {\n if (ids.length === 0) return graph;\n const doomed = new Set(ids);\n\n return {\n nodes: graph.nodes.filter((n) => !doomed.has(n.id)),\n edges: graph.edges.filter((e) => !doomed.has(e.source) && !doomed.has(e.target)),\n };\n}\n\n/** Remove edges by id, leaving nodes untouched. */\nexport function removeEdges(edges: Edge[], ids: string[]): Edge[] {\n if (ids.length === 0) return edges;\n const doomed = new Set(ids);\n\n return edges.filter((e) => !doomed.has(e.id));\n}\n\n/**\n * Set (or clear) an edge's label.\n *\n * An empty/whitespace label is removed rather than stored as `\"\"` — xyflow\n * renders an empty label as an empty chip on the wire, and a blank key would\n * survive export into the workflow schema.\n */\nexport function setEdgeLabel(edges: Edge[], id: string, label: string | undefined): Edge[] {\n const next = label?.trim();\n return edges.map((e) => {\n if (e.id !== id) return e;\n if (!next) {\n const { label: _drop, ...rest } = e;\n return rest as Edge;\n }\n return { ...e, label: next };\n });\n}\n\n/** Copy a node with a fresh id, offset so it doesn't sit exactly on top. */\nexport function duplicateNode(node: FlowNode, id: string, offset = 40): FlowNode {\n return {\n ...node,\n id,\n position: { x: node.position.x + offset, y: node.position.y + offset },\n // Deep copy so the clone's config edits don't mutate the original.\n data: JSON.parse(JSON.stringify(node.data ?? {})),\n } as FlowNode;\n}\n\n/**\n * Clone a set of nodes AND the edges internal to that set, remapping every id.\n * This is the piece `duplicateNode` lacks: a copy/paste (or duplicate-selection)\n * that preserves the wiring *between* the copied nodes. Edges with an endpoint\n * outside the set are dropped (they'd dangle). A `parentId` pointing inside the\n * set is remapped; one pointing outside is detached.\n */\nexport function cloneSubgraph(\n nodes: FlowNode[],\n edges: Edge[],\n opts: { makeId: () => string; offset?: number },\n): { nodes: FlowNode[]; edges: Edge[]; idMap: Map<string, string> } {\n const offset = opts.offset ?? 40;\n const idMap = new Map<string, string>();\n for (const n of nodes) idMap.set(n.id, opts.makeId());\n\n const clonedNodes = nodes.map((n) => {\n const cloned = duplicateNode(n, idMap.get(n.id)!, offset) as any;\n const parentId = (n as any).parentId;\n if (parentId && idMap.has(parentId)) cloned.parentId = idMap.get(parentId);\n else if (parentId) delete cloned.parentId;\n return cloned as FlowNode;\n });\n\n const clonedEdges = edges\n .filter((e) => idMap.has(e.source) && idMap.has(e.target))\n .map((e) => ({ ...e, id: opts.makeId(), source: idMap.get(e.source)!, target: idMap.get(e.target)! }));\n\n return { nodes: clonedNodes, edges: clonedEdges, idMap };\n}\n\n/**\n * Rewire one edge's endpoint(s) — wraps xyflow's `reconnectEdge`. Keeps the\n * edge's id (`shouldReplaceId: false`) so its label and identity survive the\n * rewire instead of being regenerated from the new endpoints.\n */\nexport function reconnectEdge(edges: Edge[], oldEdge: Edge, newConnection: Connection): Edge[] {\n return xyReconnectEdge(oldEdge, newConnection, edges, { shouldReplaceId: false });\n}\n\nexport type AlignEdge = \"left\" | \"hcenter\" | \"right\" | \"top\" | \"vcenter\" | \"bottom\";\n\nconst nodeW = (n: FlowNode): number => (n as any).width ?? (n as any).measured?.width ?? 0;\nconst nodeH = (n: FlowNode): number => (n as any).height ?? (n as any).measured?.height ?? 0;\n\n/** Align a selection to a shared edge/center of its bounding box. */\nexport function alignNodes(nodes: FlowNode[], edge: AlignEdge): FlowNode[] {\n if (nodes.length < 2) return nodes;\n const minL = Math.min(...nodes.map((n) => n.position.x));\n const maxR = Math.max(...nodes.map((n) => n.position.x + nodeW(n)));\n const minT = Math.min(...nodes.map((n) => n.position.y));\n const maxB = Math.max(...nodes.map((n) => n.position.y + nodeH(n)));\n const cx = (minL + maxR) / 2;\n const cy = (minT + maxB) / 2;\n return nodes.map((n) => {\n let { x, y } = n.position;\n if (edge === \"left\") x = minL;\n else if (edge === \"right\") x = maxR - nodeW(n);\n else if (edge === \"hcenter\") x = cx - nodeW(n) / 2;\n else if (edge === \"top\") y = minT;\n else if (edge === \"bottom\") y = maxB - nodeH(n);\n else if (edge === \"vcenter\") y = cy - nodeH(n) / 2;\n return { ...n, position: { x, y } };\n });\n}\n\n/**\n * Order nodes so every parent precedes its children — xyflow misrenders (and\n * warns) when a child appears before its `parentId` in the array. Stable\n * otherwise. Apply at the render boundary once grouping is in play.\n */\nexport function sortNodesParentFirst<T extends { id: string; parentId?: string }>(nodes: T[]): T[] {\n const byId = new Map(nodes.map((n) => [n.id, n] as const));\n const seen = new Set<string>();\n const out: T[] = [];\n const visit = (n: T) => {\n if (seen.has(n.id)) return;\n const pid = (n as any).parentId as string | undefined;\n if (pid && byId.has(pid) && !seen.has(pid)) visit(byId.get(pid)!);\n seen.add(n.id);\n out.push(n);\n };\n for (const n of nodes) visit(n);\n return out;\n}\n\n/** Absolute position of a node, accounting for one level of parent nesting. */\nfunction absolutePosition(node: FlowNode, nodes: FlowNode[]): { x: number; y: number } {\n const pid = (node as any).parentId as string | undefined;\n if (!pid) return node.position;\n const parent = nodes.find((n) => n.id === pid);\n return parent ? { x: node.position.x + parent.position.x, y: node.position.y + parent.position.y } : node.position;\n}\n\n/**\n * Put a node inside a lane/container: set `parentId` + `extent:'parent'` and\n * convert its position to be relative to the lane. Idempotent-safe; a no-op if\n * either id is missing or they're the same node.\n */\nexport function assignToLane(nodes: FlowNode[], nodeId: string, laneId: string): FlowNode[] {\n if (nodeId === laneId) return nodes;\n const node = nodes.find((n) => n.id === nodeId);\n const lane = nodes.find((n) => n.id === laneId);\n if (!node || !lane) return nodes;\n const abs = absolutePosition(node, nodes);\n const laneAbs = absolutePosition(lane, nodes);\n const rel = { x: abs.x - laneAbs.x, y: abs.y - laneAbs.y };\n return nodes.map((n) => (n.id === nodeId ? ({ ...n, parentId: laneId, extent: \"parent\", position: rel } as FlowNode) : n));\n}\n\n/** Take a node out of its lane: drop `parentId`/`extent`, restore absolute position. */\nexport function removeFromLane(nodes: FlowNode[], nodeId: string): FlowNode[] {\n const node = nodes.find((n) => n.id === nodeId);\n if (!node || !(node as any).parentId) return nodes;\n const abs = absolutePosition(node, nodes);\n return nodes.map((n) => {\n if (n.id !== nodeId) return n;\n const { parentId: _p, extent: _e, ...rest } = n as any;\n return { ...rest, position: abs } as FlowNode;\n });\n}\n\n/**\n * Stack lanes into contiguous rows (horizontal) or columns (vertical) — the\n * \"fixed rows/columns\" behavior. `isLane` picks which nodes are lanes; they're\n * ordered by their current cross-axis position and repacked from the first\n * lane's origin. Each lane keeps its own size (independently resizable).\n */\nexport function stackLanes(\n nodes: FlowNode[],\n isLane: (n: FlowNode) => boolean,\n opts: { orientation?: \"horizontal\" | \"vertical\"; gap?: number } = {},\n): FlowNode[] {\n const orientation = opts.orientation ?? \"horizontal\";\n const gap = opts.gap ?? 12;\n const vertical = orientation === \"vertical\";\n const lanes = nodes.filter(isLane).sort((a, b) => (vertical ? a.position.x - b.position.x : a.position.y - b.position.y));\n if (lanes.length === 0) return nodes;\n const originX = lanes[0].position.x;\n const originY = lanes[0].position.y;\n const moves = new Map<string, { x: number; y: number }>();\n let cursor = vertical ? originX : originY;\n for (const lane of lanes) {\n moves.set(lane.id, vertical ? { x: cursor, y: originY } : { x: originX, y: cursor });\n cursor += (vertical ? ((lane as any).width ?? 320) : ((lane as any).height ?? 160)) + gap;\n }\n return nodes.map((n) => (moves.has(n.id) ? { ...n, position: moves.get(n.id)! } : n));\n}\n\n/** Evenly distribute a selection's gaps along an axis (needs 3+ nodes). */\nexport function distributeNodes(nodes: FlowNode[], axis: \"h\" | \"v\"): FlowNode[] {\n if (nodes.length < 3) return nodes;\n const size = (n: FlowNode) => (axis === \"h\" ? nodeW(n) : nodeH(n));\n const coord = (n: FlowNode) => (axis === \"h\" ? n.position.x : n.position.y);\n const sorted = [...nodes].sort((a, b) => coord(a) - coord(b));\n const start = coord(sorted[0]);\n const last = sorted[sorted.length - 1];\n const end = coord(last) + size(last);\n const totalSize = sorted.reduce((s, n) => s + size(n), 0);\n const gap = (end - start - totalSize) / (sorted.length - 1);\n const posById = new Map<string, number>();\n let cursor = start;\n for (const n of sorted) {\n posById.set(n.id, cursor);\n cursor += size(n) + gap;\n }\n return nodes.map((n) => {\n const p = posById.get(n.id)!;\n return { ...n, position: axis === \"h\" ? { ...n.position, x: p } : { ...n.position, y: p } };\n });\n}\n","import type { FlowNode } from \"../../types\";\n\nexport type HelperLineChange = { id: string; position?: { x: number; y: number } };\n\nexport type HelperLinesResult = {\n /** Y of a horizontal guide line (flow coords), if the drag aligns on Y. */\n horizontal?: number;\n /** X of a vertical guide line (flow coords), if the drag aligns on X. */\n vertical?: number;\n /** The snapped position to apply to the dragged node. */\n snapPosition: { x?: number; y?: number };\n};\n\nconst w = (n: FlowNode): number => (n as any).width ?? (n as any).measured?.width ?? 0;\nconst h = (n: FlowNode): number => (n as any).height ?? (n as any).measured?.height ?? 0;\n\n/**\n * Compute alignment guide lines (and a snapped position) for a node being\n * dragged to `change.position`, against the other nodes. Standard \"helper\n * lines\" algorithm: match the dragged node's left/right/top/bottom edges to any\n * other node's edges within `distance`, snapping to the nearest. Pure + testable.\n */\nexport function getHelperLines(change: HelperLineChange, nodes: FlowNode[], distance = 6): HelperLinesResult {\n const result: HelperLinesResult = { snapPosition: { x: undefined, y: undefined } };\n const a = nodes.find((n) => n.id === change.id);\n if (!a || !change.position) return result;\n\n const A = {\n left: change.position.x,\n right: change.position.x + w(a),\n top: change.position.y,\n bottom: change.position.y + h(a),\n width: w(a),\n height: h(a),\n };\n let vDist = distance;\n let hDist = distance;\n\n for (const b of nodes) {\n if (b.id === a.id) continue;\n const B = { left: b.position.x, right: b.position.x + w(b), top: b.position.y, bottom: b.position.y + h(b) };\n\n // Vertical guides (X alignment).\n const ll = Math.abs(A.left - B.left);\n if (ll < vDist) { result.snapPosition.x = B.left; result.vertical = B.left; vDist = ll; }\n const rr = Math.abs(A.right - B.right);\n if (rr < vDist) { result.snapPosition.x = B.right - A.width; result.vertical = B.right; vDist = rr; }\n const lr = Math.abs(A.left - B.right);\n if (lr < vDist) { result.snapPosition.x = B.right; result.vertical = B.right; vDist = lr; }\n const rl = Math.abs(A.right - B.left);\n if (rl < vDist) { result.snapPosition.x = B.left - A.width; result.vertical = B.left; vDist = rl; }\n\n // Horizontal guides (Y alignment).\n const tt = Math.abs(A.top - B.top);\n if (tt < hDist) { result.snapPosition.y = B.top; result.horizontal = B.top; hDist = tt; }\n const bb = Math.abs(A.bottom - B.bottom);\n if (bb < hDist) { result.snapPosition.y = B.bottom - A.height; result.horizontal = B.bottom; hDist = bb; }\n const tb = Math.abs(A.top - B.bottom);\n if (tb < hDist) { result.snapPosition.y = B.bottom; result.horizontal = B.bottom; hDist = tb; }\n const bt = Math.abs(A.bottom - B.top);\n if (bt < hDist) { result.snapPosition.y = B.top - A.height; result.horizontal = B.top; hDist = bt; }\n }\n\n return result;\n}\n","import { ViewportPortal } from \"@xyflow/react\";\n\n/**\n * HelperLines — alignment guides drawn during a drag. Rendered in flow\n * coordinate space (ViewportPortal), so the lines track pan/zoom. Positions come\n * from `getHelperLines`.\n */\nexport function HelperLines({ horizontal, vertical }: { horizontal?: number; vertical?: number }) {\n if (horizontal === undefined && vertical === undefined) return null;\n return (\n <ViewportPortal>\n {vertical !== undefined && (\n <div\n className=\"ff-helper-line\"\n style={{ position: \"absolute\", transform: `translateX(${vertical}px)`, top: -5000, height: 10000, width: 1, pointerEvents: \"none\" }}\n />\n )}\n {horizontal !== undefined && (\n <div\n className=\"ff-helper-line\"\n style={{ position: \"absolute\", transform: `translateY(${horizontal}px)`, left: -5000, width: 10000, height: 1, pointerEvents: \"none\" }}\n />\n )}\n </ViewportPortal>\n );\n}\n","import { useEffect, useState } from \"react\";\n\n/** The resolved mode React Flow and our own `ff-` tokens both understand. */\nexport type FlowColorMode = \"light\" | \"dark\";\n\n/**\n * What a host may PASS. React Flow's own `ColorMode` includes `\"system\"`, and\n * it is meaningful here rather than something to cast away: it means \"follow\n * the environment\", which is the same job `undefined` now does.\n */\nexport type FlowColorModeInput = FlowColorMode | \"system\";\n\n/**\n * Read the app's theme off the document, the way every host in this suite\n * signals it.\n *\n * Checked in the order a host actually sets them: an explicit `data-theme`\n * beats a `.dark` class (a host that writes both, like the showcase, is\n * consistent either way), and only when neither is present does the OS\n * preference decide.\n */\nfunction readDocumentTheme(): FlowColorMode {\n if (typeof document === \"undefined\") return \"light\";\n\n const root = document.documentElement;\n const attr = root.getAttribute(\"data-theme\");\n if (attr === \"dark\" || attr === \"light\") return attr;\n if (root.classList.contains(\"dark\")) return \"dark\";\n\n return typeof window !== \"undefined\" && window.matchMedia?.(\"(prefers-color-scheme: dark)\").matches\n ? \"dark\"\n : \"light\";\n}\n\n/**\n * The colour mode the canvas should actually use.\n *\n * **Why this exists.** `colorMode` used to be passed straight through to React\n * Flow, so a host that did not supply one got React Flow's own default —\n * `light` — no matter what the surrounding app was doing. Our `ff-` styles\n * still looked right, because they hang off an ancestor `.dark`, which is\n * exactly what made the bug hard to see: the nodes we style were fine while\n * React Flow's own layer stayed light underneath. Any node whose kind is not\n * registered falls back to React Flow's default node, and on a dark page that\n * is a white box with unreadable text. Edges, handles, the selection rectangle\n * and the controls were light too.\n *\n * So an unset `colorMode` now means \"follow the app\", not \"light\". Passing one\n * explicitly still wins — a canvas deliberately pinned light on a dark page is\n * a real thing, and this does not take it away.\n *\n * The subscription matters as much as the initial read: a theme toggle changes\n * an attribute on `<html>`, which triggers no React render on its own, so\n * without an observer the canvas would be correct on load and wrong the moment\n * someone flipped the switch.\n */\nexport function useResolvedColorMode(explicit?: FlowColorModeInput): FlowColorMode {\n // Start light on the server and on first paint. Reading the DOM in the\n // initialiser would differ between server and client markup and trip\n // hydration; the effect below corrects it before anything is visible.\n const [resolved, setResolved] = useState<FlowColorMode>(\"light\");\n\n // `\"system\"` is treated exactly like an unset prop: both mean \"follow the\n // environment\", and collapsing them here keeps one resolution path.\n const pinned = explicit === \"light\" || explicit === \"dark\" ? explicit : undefined;\n\n useEffect(() => {\n if (pinned) return;\n if (typeof document === \"undefined\") return;\n\n const sync = () => setResolved(readDocumentTheme());\n sync();\n\n const observer = new MutationObserver(sync);\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: [\"class\", \"data-theme\"],\n });\n\n const media = window.matchMedia?.(\"(prefers-color-scheme: dark)\");\n media?.addEventListener?.(\"change\", sync);\n\n return () => {\n observer.disconnect();\n media?.removeEventListener?.(\"change\", sync);\n };\n }, [pinned]);\n\n return pinned ?? resolved;\n}\n","import {\n type CSSProperties,\n type ReactNode,\n type WheelEvent as ReactWheelEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n ReactFlow,\n Background,\n BackgroundVariant,\n Controls,\n MiniMap,\n type DefaultEdgeOptions,\n type Edge,\n type EdgeTypes,\n type FitViewOptions,\n type NodeTypes,\n type ReactFlowProps,\n} from \"@xyflow/react\";\nimport \"@xyflow/react/dist/style.css\";\nimport { defaultNodeTypes } from \"../nodes\";\nimport { createConnectionValidator, type ConnectionValidatorOptions } from \"../../registry/connection\";\nimport { sortNodesParentFirst } from \"../FlowEditor/graph-ops\";\nimport { getHelperLines } from \"./helper-lines\";\nimport { HelperLines } from \"./HelperLines\";\nimport type { FlowNode } from \"../../types\";\nimport { useResolvedColorMode } from \"./use-resolved-color-mode\";\n\n/**\n * With wheel-zoom off, Shift+wheel still zooms — and must not ALSO scroll the\n * page while it does. React Flow's own `preventScrolling` is all-or-nothing, so\n * the modifier case is handled here: swallow the gesture that zooms, leave the\n * one that doesn't alone.\n *\n * Capture phase, so it lands before React Flow's own wheel handling.\n */\nfunction preventScrollWhileZooming(event: ReactWheelEvent<HTMLDivElement>): void {\n if (event.shiftKey) event.preventDefault();\n}\n\n/**\n * The three React Flow props that together decide what the wheel does.\n *\n * Extracted because they only make sense as a set, and getting the set wrong is\n * invisible in a screenshot: the canvas looks fine and feels broken. This is\n * the unit worth testing — mounting a canvas to assert it would be testing\n * d3-zoom through jsdom.\n *\n * - **on** (default): no modifier needed, and the page never scrolls under a\n * wheel that is zooming.\n * - **off**: zoom moves to Shift+wheel and the bare wheel goes back to the\n * page. `preventScrolling` alone cannot express that — left true it swallows\n * the bare wheel (page frozen, nothing zooms), left false it lets Shift+wheel\n * zoom *and* scroll at once — so the handler covers the modifier case.\n */\nexport function wheelZoomProps(zoomOnWheel: boolean): {\n zoomActivationKeyCode: string | null;\n preventScrolling: boolean;\n onWheelCapture?: (event: ReactWheelEvent<HTMLDivElement>) => void;\n} {\n return zoomOnWheel\n ? { zoomActivationKeyCode: null, preventScrolling: true }\n : {\n zoomActivationKeyCode: \"Shift\",\n preventScrolling: false,\n onWheelCapture: preventScrollWhileZooming,\n };\n}\n\nexport type FlowCanvasProps = Omit<ReactFlowProps<FlowNode, Edge>, \"nodes\" | \"edges\" | \"height\"> & {\n nodes: FlowNode[];\n edges: Edge[];\n /** Background variant. Default: \"dots\". */\n background?: BackgroundVariant | \"none\";\n /** Show pan/zoom/fit controls. Default true. */\n showControls?: boolean;\n /** Show minimap. Default false (turn on for big graphs). */\n showMinimap?: boolean;\n /** Pixel height; FlowCanvas expects a sized container. Default 600. */\n height?: number | string;\n /**\n * Enforce port-type compatibility on new connections. `true` (default) uses\n * the built-in validator: a connection is refused only when both ports\n * declare a concrete, differing `type` (so untyped graphs are unaffected),\n * and self-loops are blocked. Pass options to tune the rule, or `false` to\n * disable. An `isValidConnection` you pass yourself always takes precedence.\n */\n validateConnections?: boolean | ConnectionValidatorOptions;\n /** Show alignment guide lines while dragging, and snap to them. Default off. */\n showHelperLines?: boolean;\n /**\n * A bare mouse wheel over the canvas zooms it. Default **true**.\n *\n * Turn it off for a canvas embedded mid-page, where a reader scrolling past\n * would otherwise get trapped zooming. With it off the wheel scrolls the page\n * and **Shift+wheel** zooms instead.\n *\n * Either way, a wheel gesture that zooms never also scrolls the page — the\n * two happening at once is the thing that makes an embedded canvas feel\n * broken.\n */\n zoomOnWheel?: boolean;\n /** Optional toolbar / palette etc. rendered above the canvas. */\n toolbar?: ReactNode;\n className?: string;\n style?: CSSProperties;\n};\n\nconst DEFAULT_FIT_VIEW: FitViewOptions = { padding: 0.2 };\nconst DEFAULT_EDGE_OPTIONS: DefaultEdgeOptions = {\n type: \"smoothstep\",\n animated: false,\n};\n\n/**\n * FlowCanvas — themed React Flow surface with the kit's nodes registered\n * by default. Pass your own `nodeTypes` to extend; the kit's defaults are\n * merged behind yours.\n *\n * Hosts wire `onNodesChange` / `onEdgesChange` / `onConnect` themselves\n * (xyflow's standard pattern). The surrounding `useFlowState` hook in\n * `runtime/use-flow-state.ts` is a convenience that wires those for you.\n */\nexport function FlowCanvas({\n nodes,\n edges,\n background = BackgroundVariant.Dots,\n showControls = true,\n showMinimap = false,\n height = 600,\n validateConnections = true,\n isValidConnection,\n colorMode,\n showHelperLines = false,\n zoomOnWheel = true,\n onNodesChange,\n toolbar,\n nodeTypes,\n edgeTypes,\n className,\n style,\n ...rest\n}: FlowCanvasProps) {\n const mergedNodeTypes = useMemo<NodeTypes>(\n () => ({ ...defaultNodeTypes, ...(nodeTypes ?? {}) }),\n [nodeTypes],\n );\n\n // Read nodes live through a ref so the validator (built once) always sees the\n // current graph without being rebuilt on every node change.\n const nodesRef = useRef(nodes);\n nodesRef.current = nodes;\n const builtinValidator = useMemo(\n () =>\n validateConnections === false\n ? undefined\n : createConnectionValidator(\n () => nodesRef.current,\n validateConnections === true ? undefined : validateConnections,\n ),\n [validateConnections],\n );\n // A caller-supplied predicate wins; otherwise fall back to port-type validation.\n const resolvedIsValidConnection = isValidConnection ?? builtinValidator;\n\n const mergedEdgeTypes = useMemo<EdgeTypes | undefined>(\n () => (edgeTypes ? { ...edgeTypes } : undefined),\n [edgeTypes],\n );\n\n // xyflow requires a parent node to precede its children in the array; grouping\n // (swimlanes) can produce any order, so normalize it here at the boundary.\n const orderedNodes = useMemo(() => sortNodesParentFirst(nodes), [nodes]);\n\n // Helper lines: on a single-node drag, snap to aligned edges + show guides.\n const [helperLines, setHelperLines] = useState<{ horizontal?: number; vertical?: number }>({});\n const handleNodesChange = useCallback(\n (changes: any[]) => {\n if (showHelperLines) {\n const pos = changes.filter((c) => c.type === \"position\" && c.position);\n if (pos.length === 1 && pos[0].dragging) {\n const lines = getHelperLines(pos[0], nodesRef.current);\n if (lines.snapPosition.x !== undefined) pos[0].position.x = lines.snapPosition.x;\n if (lines.snapPosition.y !== undefined) pos[0].position.y = lines.snapPosition.y;\n setHelperLines({ horizontal: lines.horizontal, vertical: lines.vertical });\n } else {\n setHelperLines({});\n }\n }\n onNodesChange?.(changes as any);\n },\n [showHelperLines, onNodesChange],\n );\n\n /**\n * An unset `colorMode` means \"follow the app\", NOT \"light\".\n *\n * It used to pass straight through to React Flow, whose own default is\n * light — so on a dark page React Flow's layer stayed light underneath our\n * `ff-` styles, which look right because they hang off an ancestor `.dark`.\n * Any node kind without a registered type falls back to React Flow's default\n * node: a white box with unreadable text on a dark canvas. Passing a mode\n * explicitly still wins.\n */\n const resolvedColorMode = useResolvedColorMode(colorMode);\n\n return (\n <div\n className={[\n \"ff-canvas\",\n // colorMode drives BOTH react-flow's chrome (below) and our `ff-` styles\n // via the shared `.dark` class / light opt-out — one theme signal.\n resolvedColorMode === \"dark\" ? \"dark\" : \"\",\n resolvedColorMode === \"light\" ? \"ff-canvas--light\" : \"\",\n className ?? \"\",\n ]\n .filter(Boolean)\n .join(\" \")}\n style={{ height, ...style }}\n >\n {toolbar && <div className=\"ff-canvas__toolbar\">{toolbar}</div>}\n <div className=\"ff-canvas__surface\">\n <ReactFlow\n nodes={orderedNodes}\n edges={edges}\n onNodesChange={handleNodesChange}\n colorMode={resolvedColorMode}\n nodeTypes={mergedNodeTypes}\n edgeTypes={mergedEdgeTypes}\n fitView\n fitViewOptions={DEFAULT_FIT_VIEW}\n defaultEdgeOptions={DEFAULT_EDGE_OPTIONS}\n proOptions={{ hideAttribution: true }}\n // Wheel zooms by default; `zoomOnWheel={false}` moves that onto\n // Shift+wheel and gives the bare wheel back to the page. The three\n // props only make sense as a set — see wheelZoomProps.\n {...wheelZoomProps(zoomOnWheel)}\n isValidConnection={resolvedIsValidConnection}\n {...rest}\n >\n {background !== \"none\" && (\n <Background variant={background as BackgroundVariant} gap={20} size={1} color=\"rgba(0,0,0,0.18)\" />\n )}\n {showControls && <Controls className=\"ff-controls\" position=\"bottom-right\" />}\n {showMinimap && <MiniMap className=\"ff-minimap\" pannable zoomable />}\n {showHelperLines && <HelperLines horizontal={helperLines.horizontal} vertical={helperLines.vertical} />}\n </ReactFlow>\n </div>\n </div>\n );\n}\n","import { useMemo, type CSSProperties, type ReactNode } from \"react\";\nimport { FlowCanvas } from \"../canvas\";\nimport { buildNodeTypes } from \"../../registry\";\nimport { categoryAccent, getNodeKind } from \"../../registry/registry\";\nimport type { FlowGraph, FlowNode } from \"../../types\";\n\n/** Outcome of one node in a run, for annotating the graph after the fact. */\nexport type FlowNodeStatus = \"ok\" | \"running\" | \"failed\" | \"skipped\" | \"pending\";\n\nexport interface FlowViewerClassNames {\n root?: string;\n list?: string;\n row?: string;\n rowIndex?: string;\n rowTitle?: string;\n rowDescription?: string;\n rowStatus?: string;\n}\n\nexport interface FlowViewerProps {\n /** The graph to show. */\n graph: FlowGraph;\n /**\n * `canvas` draws the graph. `list` renders the nodes as rows — for a docs\n * page, a narrow column, print, or an audit view, where a pan-zoom surface is\n * the wrong shape and often not usable at all.\n */\n variant?: \"canvas\" | \"list\";\n /** Canvas height. Ignored by `list`. Default 480. */\n height?: number | string;\n /** Canvas minimap. Default false. */\n showMinimap?: boolean;\n /** Canvas pan/zoom/fit controls. Default true. */\n showControls?: boolean;\n /**\n * Per-node run outcome, keyed by node id. Lets the same component serve\n * \"here is the workflow\" and \"here is what happened on Tuesday\".\n */\n statuses?: Record<string, FlowNodeStatus>;\n /** Controlled selection. */\n selectedNodeId?: string | null;\n /** Omit and nothing is clickable — a viewer with no handler is inert. */\n onSelectNode?: (node: FlowNode) => void;\n className?: string;\n classNames?: FlowViewerClassNames;\n style?: CSSProperties;\n /** Rendered when the graph has no nodes. */\n empty?: ReactNode;\n}\n\nconst STATUS_LABEL: Record<FlowNodeStatus, string> = {\n ok: \"ok\",\n running: \"running\",\n failed: \"failed\",\n skipped: \"skipped\",\n pending: \"pending\",\n};\n\n/**\n * FlowViewer — a workflow, read-only.\n *\n * **Read-only by construction, not by configuration.** There is no prop that\n * makes this editable, because a viewer that can be switched into an editor is\n * a viewer somebody eventually switches into an editor by accident. Before this\n * existed the only way to show a flow was `FlowEditor` (the whole editor) or\n * `FlowCanvas` plus four React Flow flags a consumer had to know to pass —\n * assembly, not an affordance, and nothing stopped the next person shipping a\n * fully editable canvas where they wanted a picture.\n *\n * Node titles come from the registry, so `overrideNodeKind()` renames apply\n * here too.\n */\nexport function FlowViewer({\n graph,\n variant = \"canvas\",\n height = 480,\n showMinimap = false,\n showControls = true,\n statuses,\n selectedNodeId = null,\n onSelectNode,\n className,\n classNames = {},\n style,\n empty,\n}: FlowViewerProps) {\n const nodeTypes = useMemo(() => buildNodeTypes(), []);\n\n const rows = useMemo(\n () =>\n graph.nodes.map((node, index) => {\n const kind = getNodeKind(node.data?.kind ?? node.type ?? \"\");\n return {\n node,\n index,\n // The node's own label is the name the AUTHOR gave THIS node (\"Summarize\");\n // the kind label is the generic type name (\"LLM Call\"). Specific wins.\n title: node.data?.label ?? kind?.label ?? node.data?.kind ?? node.id,\n description: kind?.description ?? null,\n accent: kind?.accent ?? categoryAccent(kind?.category ?? \"custom\"),\n status: statuses?.[node.id] ?? null,\n };\n }),\n [graph.nodes, statuses],\n );\n\n if (graph.nodes.length === 0) {\n return (\n <div className={cx(\"ff-viewer ff-viewer--empty\", className, classNames.root)} style={style}>\n {empty ?? <span className=\"ff-viewer__empty\">This flow has no nodes.</span>}\n </div>\n );\n }\n\n if (variant === \"list\") {\n return (\n <div\n className={cx(\"ff-viewer ff-viewer--list\", className, classNames.root)}\n style={style}\n data-flow-viewer=\"list\"\n >\n <ol className={cx(\"ff-viewer__list\", classNames.list)}>\n {rows.map(({ node, index, title, description, accent, status }) => {\n const selected = node.id === selectedNodeId;\n const Row = onSelectNode ? \"button\" : \"div\";\n\n return (\n <li key={node.id}>\n <Row\n {...(onSelectNode\n ? { type: \"button\" as const, onClick: () => onSelectNode(node) }\n : {})}\n className={cx(\n \"ff-viewer__row\",\n selected && \"ff-viewer__row--selected\",\n onSelectNode && \"ff-viewer__row--interactive\",\n classNames.row,\n )}\n data-flow-viewer-node={node.id}\n data-flow-viewer-status={status ?? undefined}\n aria-current={selected || undefined}\n >\n <span\n className={cx(\"ff-viewer__index\", classNames.rowIndex)}\n style={{ backgroundColor: accent }}\n aria-hidden\n >\n {index + 1}\n </span>\n\n <span className=\"ff-viewer__body\">\n <span className={cx(\"ff-viewer__title\", classNames.rowTitle)}>{title}</span>\n {description && (\n <span className={cx(\"ff-viewer__desc\", classNames.rowDescription)}>\n {description}\n </span>\n )}\n </span>\n\n {status && (\n <span\n className={cx(\n \"ff-viewer__status\",\n `ff-viewer__status--${status}`,\n classNames.rowStatus,\n )}\n >\n {STATUS_LABEL[status]}\n </span>\n )}\n </Row>\n </li>\n );\n })}\n </ol>\n </div>\n );\n }\n\n return (\n <div\n className={cx(\"ff-viewer ff-viewer--canvas\", className, classNames.root)}\n style={style}\n data-flow-viewer=\"canvas\"\n >\n <FlowCanvas\n nodes={graph.nodes}\n edges={graph.edges}\n nodeTypes={nodeTypes}\n height={height}\n showControls={showControls}\n showMinimap={showMinimap}\n // The read-only contract. Every mutation path React Flow offers is\n // closed here rather than left to the caller to remember.\n nodesDraggable={false}\n nodesConnectable={false}\n nodesFocusable={Boolean(onSelectNode)}\n edgesFocusable={false}\n elementsSelectable={Boolean(onSelectNode)}\n deleteKeyCode={null}\n selectionKeyCode={null}\n multiSelectionKeyCode={null}\n connectOnClick={false}\n // A canvas embedded mid-page must not trap a reader's scroll.\n zoomOnScroll={false}\n onNodeClick={onSelectNode ? (_, node) => onSelectNode(node as FlowNode) : undefined}\n fitView\n />\n </div>\n );\n}\n\nfunction cx(...parts: Array<string | false | null | undefined>): string {\n return parts.filter(Boolean).join(\" \");\n}\n"]}