@genfeedai/workflow-ui 0.2.5 → 0.2.7

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 (66) hide show
  1. package/dist/canvas.mjs +19 -17
  2. package/dist/canvas.mjs.map +1 -0
  3. package/dist/{chunk-MGLAKMDP.mjs → chunk-2BHILUF7.mjs} +2 -0
  4. package/dist/chunk-2BHILUF7.mjs.map +1 -0
  5. package/dist/{chunk-U4QPE4CY.mjs → chunk-2C2AAXJP.mjs} +2 -0
  6. package/dist/chunk-2C2AAXJP.mjs.map +1 -0
  7. package/dist/{chunk-ZSITTZ4S.mjs → chunk-3GWH2ZOH.mjs} +5 -3
  8. package/dist/chunk-3GWH2ZOH.mjs.map +1 -0
  9. package/dist/{chunk-XRC3O5GK.mjs → chunk-4JOFNZW6.mjs} +2 -0
  10. package/dist/chunk-4JOFNZW6.mjs.map +1 -0
  11. package/dist/{chunk-2FUPL67V.mjs → chunk-55JFUNLR.mjs} +253 -237
  12. package/dist/chunk-55JFUNLR.mjs.map +1 -0
  13. package/dist/{chunk-GPYIIWD5.mjs → chunk-7DJHFOIW.mjs} +3 -1
  14. package/dist/chunk-7DJHFOIW.mjs.map +1 -0
  15. package/dist/{chunk-QQVHGJ2G.mjs → chunk-AZJFDWBF.mjs} +2 -0
  16. package/dist/chunk-AZJFDWBF.mjs.map +1 -0
  17. package/dist/{chunk-C6MQBJFC.mjs → chunk-G3HCTMAZ.mjs} +3 -1
  18. package/dist/chunk-G3HCTMAZ.mjs.map +1 -0
  19. package/dist/{chunk-IYFWAJBB.mjs → chunk-HMTYPFOT.mjs} +3 -1
  20. package/dist/chunk-HMTYPFOT.mjs.map +1 -0
  21. package/dist/{chunk-7LV4UAUS.mjs → chunk-IKR6GVZ4.mjs} +2 -0
  22. package/dist/chunk-IKR6GVZ4.mjs.map +1 -0
  23. package/dist/{chunk-YUIK4AHM.mjs → chunk-JSF4FHBH.mjs} +3 -1
  24. package/dist/chunk-JSF4FHBH.mjs.map +1 -0
  25. package/dist/{chunk-OJWVEEMM.mjs → chunk-R5L7WB7F.mjs} +4 -2
  26. package/dist/chunk-R5L7WB7F.mjs.map +1 -0
  27. package/dist/{chunk-53XDE62A.mjs → chunk-RY6OZJ7A.mjs} +8 -6
  28. package/dist/chunk-RY6OZJ7A.mjs.map +1 -0
  29. package/dist/{chunk-B4EAAKYF.mjs → chunk-SBB2YW3Y.mjs} +2 -0
  30. package/dist/chunk-SBB2YW3Y.mjs.map +1 -0
  31. package/dist/{chunk-FWJIAW2E.mjs → chunk-SHU7JPQY.mjs} +7 -5
  32. package/dist/chunk-SHU7JPQY.mjs.map +1 -0
  33. package/dist/chunk-SRPSHHHV.mjs +3 -0
  34. package/dist/chunk-SRPSHHHV.mjs.map +1 -0
  35. package/dist/{chunk-ESVULCFY.mjs → chunk-TOFB4BTA.mjs} +3 -1
  36. package/dist/chunk-TOFB4BTA.mjs.map +1 -0
  37. package/dist/{chunk-ORVDYXDP.mjs → chunk-VKXTPLM7.mjs} +6 -4
  38. package/dist/chunk-VKXTPLM7.mjs.map +1 -0
  39. package/dist/{chunk-VVQ4CH77.mjs → chunk-X3XNTD4R.mjs} +5 -2
  40. package/dist/chunk-X3XNTD4R.mjs.map +1 -0
  41. package/dist/chunk-YYFM6P4C.mjs +3 -0
  42. package/dist/chunk-YYFM6P4C.mjs.map +1 -0
  43. package/dist/hooks.mjs +13 -11
  44. package/dist/hooks.mjs.map +1 -0
  45. package/dist/index.mjs +27 -25
  46. package/dist/index.mjs.map +1 -0
  47. package/dist/lib.mjs +6 -4
  48. package/dist/lib.mjs.map +1 -0
  49. package/dist/nodes.mjs +15 -13
  50. package/dist/nodes.mjs.map +1 -0
  51. package/dist/panels.mjs +5 -3
  52. package/dist/panels.mjs.map +1 -0
  53. package/dist/provider.mjs +5 -3
  54. package/dist/provider.mjs.map +1 -0
  55. package/dist/stores.mjs +8 -6
  56. package/dist/stores.mjs.map +1 -0
  57. package/dist/toolbar.mjs +7 -5
  58. package/dist/toolbar.mjs.map +1 -0
  59. package/dist/ui.mjs +4 -2
  60. package/dist/ui.mjs.map +1 -0
  61. package/dist/workflowStore-XYPHB6DS.mjs +4 -0
  62. package/dist/workflowStore-XYPHB6DS.mjs.map +1 -0
  63. package/package.json +24 -24
  64. package/dist/chunk-LDN7IX4Y.mjs +0 -1
  65. package/dist/chunk-MLJJBBTB.mjs +0 -1
  66. package/dist/workflowStore-N2F7WIG3.mjs +0 -2
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hooks/useAIGenNode.ts","../src/hooks/useAIGenNodeHeader.tsx","../src/hooks/useAutoLoadModelSchema.ts","../src/hooks/useRequiredInputs.ts","../src/hooks/useCanGenerate.ts","../src/hooks/useModelSelection.ts","../src/hooks/useNodeExecution.ts","../src/hooks/useMediaUpload.ts","../src/hooks/usePromptAutocomplete.ts"],"names":["useMemo","useCallback","NODE_DEFINITIONS","useRef","useState"],"mappings":"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","file":"chunk-SHU7JPQY.mjs","sourcesContent":["import type { SelectedModel, WorkflowNodeData } from '@genfeedai/types';\nimport { useCallback, useMemo } from 'react';\nimport { extractEnumValues, supportsImageInput } from '../lib/schemaUtils';\nimport type { SchemaInputs } from '../nodes/SchemaInputs';\nimport { useWorkflowStore } from '../stores/workflowStore';\n\ninterface UseAIGenNodeOptions {\n nodeId: string;\n selectedModel: SelectedModel | undefined;\n schemaParams: Record<string, unknown> | undefined;\n}\n\nexport function useAIGenNode<TNodeData extends WorkflowNodeData>({\n nodeId,\n selectedModel,\n schemaParams,\n}: UseAIGenNodeOptions) {\n const updateNodeData = useWorkflowStore((state) => state.updateNodeData);\n\n const schemaProperties = useMemo(() => {\n const schema = selectedModel?.inputSchema as\n | { properties?: Record<string, unknown> }\n | undefined;\n return schema?.properties as Parameters<typeof SchemaInputs>[0]['schema'];\n }, [selectedModel?.inputSchema]);\n\n const enumValues = useMemo(\n () =>\n extractEnumValues(\n selectedModel?.componentSchemas as\n | Record<string, { enum?: unknown[]; type?: string }>\n | undefined,\n ),\n [selectedModel?.componentSchemas],\n );\n\n const modelSupportsImageInput = useMemo(\n () => supportsImageInput(selectedModel?.inputSchema),\n [selectedModel?.inputSchema],\n );\n\n const componentSchemas = selectedModel?.componentSchemas as\n | Record<string, { enum?: unknown[]; type?: string }>\n | undefined;\n\n const handleSchemaParamChange = useCallback(\n (key: string, value: unknown) => {\n // Get fresh state to avoid stale closure issues with rapid changes\n const currentNode = useWorkflowStore.getState().getNodeById(nodeId);\n const currentData = currentNode?.data as TNodeData | undefined;\n updateNodeData<TNodeData>(nodeId, {\n schemaParams: {\n ...(((currentData as Record<string, unknown> | undefined)\n ?.schemaParams as Record<string, unknown> | undefined) ?? {}),\n [key]: value,\n },\n } as Partial<TNodeData>);\n },\n [nodeId, updateNodeData],\n );\n\n return {\n componentSchemas,\n enumValues,\n handleSchemaParamChange,\n modelSupportsImageInput,\n schemaProperties,\n };\n}\n","import { ChevronDown, Expand, Play, Square } from 'lucide-react';\nimport { type ReactNode, useMemo } from 'react';\nimport { Button } from '../ui/button';\n\ninterface UseAIGenNodeHeaderOptions {\n modelDisplayName: string;\n isProcessing: boolean;\n canGenerate: boolean;\n hasOutput: boolean;\n onModelBrowse: () => void;\n onGenerate: () => void;\n onStop: () => void;\n onExpand: () => void;\n}\n\nexport function useAIGenNodeHeader({\n modelDisplayName,\n isProcessing,\n canGenerate,\n hasOutput,\n onModelBrowse,\n onGenerate,\n onStop,\n onExpand,\n}: UseAIGenNodeHeaderOptions): {\n titleElement: ReactNode;\n headerActions: ReactNode;\n} {\n const titleElement = useMemo(\n () => (\n <button\n className={`flex flex-1 items-center gap-1 text-sm font-medium text-left text-foreground ${isProcessing ? 'opacity-50 cursor-default' : 'hover:text-foreground/80 cursor-pointer'}`}\n onClick={() => !isProcessing && onModelBrowse()}\n title=\"Browse models\"\n disabled={isProcessing}\n >\n <span className=\"truncate\">{modelDisplayName}</span>\n <ChevronDown className=\"h-3 w-3 shrink-0\" />\n </button>\n ),\n [modelDisplayName, isProcessing, onModelBrowse],\n );\n\n const headerActions = useMemo(\n () => (\n <>\n {hasOutput && (\n <Button\n variant=\"ghost\"\n size=\"icon-sm\"\n onClick={onExpand}\n title=\"Expand preview\"\n >\n <Expand className=\"h-3 w-3\" />\n </Button>\n )}\n {isProcessing ? (\n <Button variant=\"destructive\" size=\"sm\" onClick={onStop}>\n <Square className=\"h-4 w-4 fill-current\" />\n Generating\n </Button>\n ) : (\n <Button\n variant={canGenerate ? 'default' : 'secondary'}\n size=\"sm\"\n onClick={onGenerate}\n disabled={!canGenerate}\n >\n <Play className=\"h-4 w-4 fill-current\" />\n Generate\n </Button>\n )}\n </>\n ),\n [hasOutput, isProcessing, canGenerate, onGenerate, onStop, onExpand],\n );\n\n return { headerActions, titleElement };\n}\n","import type { ProviderModel, SelectedModel } from '@genfeedai/types';\nimport { useEffect, useRef } from 'react';\nimport { useWorkflowUIConfig } from '../provider/WorkflowUIProvider';\n\ninterface UseAutoLoadModelSchemaOptions<TModel extends string> {\n /** Current model type from node data */\n currentModel: TModel | undefined;\n /** Selected model with full schema (if already loaded) */\n selectedModel: SelectedModel | undefined;\n /** Map from internal model type to API model ID */\n modelIdMap: Record<TModel, string>;\n /** Callback when model is loaded from API */\n onModelSelect: (model: ProviderModel) => void;\n}\n\n/**\n * Hook that auto-loads model schema for a node when the selectedModel is not set\n * but a model type is already selected.\n *\n * This handles the case where a node has a default model but hasn't loaded\n * the full schema yet.\n *\n * Uses the WorkflowUIProvider's modelSchema service to fetch the schema.\n * Falls back to no-op if the service is not configured.\n */\nexport function useAutoLoadModelSchema<TModel extends string>({\n currentModel,\n selectedModel,\n modelIdMap,\n onModelSelect,\n}: UseAutoLoadModelSchemaOptions<TModel>): void {\n const { modelSchema } = useWorkflowUIConfig();\n // Track if we've already attempted to load the default model schema\n const hasAttemptedSchemaLoad = useRef(false);\n\n useEffect(() => {\n // Only run once per node, and only if we have a model but no selectedModel\n if (\n hasAttemptedSchemaLoad.current ||\n selectedModel ||\n !currentModel ||\n !modelSchema\n ) {\n return;\n }\n\n const modelId = modelIdMap[currentModel];\n if (!modelId) return;\n\n const controller = new AbortController();\n let isCancelled = false;\n\n const loadSchema = async () => {\n try {\n const model = await modelSchema.fetchModelSchema(\n modelId,\n controller.signal,\n );\n\n if (model && !isCancelled) {\n hasAttemptedSchemaLoad.current = true;\n onModelSelect(model);\n }\n } catch {\n // Ignore abort errors and other failures - allows retry on next effect run\n }\n };\n\n loadSchema();\n\n return () => {\n isCancelled = true;\n controller.abort();\n };\n }, [currentModel, selectedModel, modelIdMap, onModelSelect, modelSchema]);\n}\n","import type { NodeType } from '@genfeedai/types';\nimport { NODE_DEFINITIONS } from '@genfeedai/types';\nimport { useMemo } from 'react';\nimport { useWorkflowStore } from '../stores/workflowStore';\n\ninterface RequiredInputsResult {\n /** Whether all required inputs have connections */\n hasRequiredInputs: boolean;\n /** List of missing required input handle IDs */\n missingInputs: string[];\n /** Map of handle ID to whether it's connected */\n connectionStatus: Map<string, boolean>;\n}\n\n/**\n * Hook that checks if all required inputs for a node are connected.\n * Uses edge connections, not actual data values.\n *\n * @param nodeId - The node ID to check\n * @param nodeType - The node type (to look up required inputs from NODE_DEFINITIONS)\n * @returns Object with hasRequiredInputs boolean and details about missing inputs\n */\nexport function useRequiredInputs(\n nodeId: string,\n nodeType: NodeType,\n): RequiredInputsResult {\n const edges = useWorkflowStore((state) => state.edges);\n\n return useMemo(() => {\n const nodeDef = NODE_DEFINITIONS[nodeType];\n if (!nodeDef) {\n return {\n connectionStatus: new Map(),\n hasRequiredInputs: true,\n missingInputs: [],\n };\n }\n\n // Get edges that target this node\n const incomingEdges = edges.filter((e) => e.target === nodeId);\n const connectedHandles = new Set(\n incomingEdges.map((e) => e.targetHandle).filter(Boolean),\n );\n\n // Check each input handle\n const connectionStatus = new Map<string, boolean>();\n const missingInputs: string[] = [];\n\n for (const input of nodeDef.inputs) {\n const isConnected = connectedHandles.has(input.id);\n connectionStatus.set(input.id, isConnected);\n\n if (input.required && !isConnected) {\n missingInputs.push(input.id);\n }\n }\n\n return {\n connectionStatus,\n hasRequiredInputs: missingInputs.length === 0,\n missingInputs,\n };\n }, [nodeId, nodeType, edges]);\n}\n","import type { NodeType, WorkflowEdge, WorkflowNode } from '@genfeedai/types';\nimport { NODE_DEFINITIONS } from '@genfeedai/types';\nimport { useCallback, useMemo } from 'react';\nimport { useShallow } from 'zustand/react/shallow';\nimport {\n CONNECTION_FIELDS,\n validateRequiredSchemaFields,\n} from '../lib/schemaValidation';\nimport { useWorkflowStore } from '../stores/workflowStore';\nimport { useRequiredInputs } from './useRequiredInputs';\n\ninterface MissingItem {\n type: 'connection' | 'data' | 'schema';\n field: string;\n message: string;\n}\n\ninterface CanGenerateResult {\n /** Whether all validation passes and generation can proceed */\n canGenerate: boolean;\n /** List of missing items with details */\n missingItems: MissingItem[];\n /** Whether all required connections exist */\n hasRequiredConnections: boolean;\n /** Whether all connected nodes have actual data */\n hasConnectedData: boolean;\n /** Whether all required schema fields are filled */\n hasRequiredSchemaFields: boolean;\n}\n\ninterface UseCanGenerateOptions {\n /** The node ID to validate */\n nodeId: string;\n /** The node type (to look up required inputs from NODE_DEFINITIONS) */\n nodeType: NodeType;\n /** The model's input schema with required array */\n inputSchema?: Record<string, unknown>;\n /** Current schema parameter values */\n schemaParams?: Record<string, unknown>;\n}\n\n/**\n * Extract output value from a node based on handle type.\n */\nfunction extractOutputValue(\n node: WorkflowNode,\n handleType: string | null | undefined,\n): string | undefined {\n const data = node.data as Record<string, unknown>;\n if (handleType === 'text') {\n return (data.outputText ?? data.prompt) as string | undefined;\n } else if (handleType === 'image') {\n return (data.outputImage ?? data.image) as string | undefined;\n } else if (handleType === 'video') {\n return (data.outputVideo ?? data.video) as string | undefined;\n } else if (handleType === 'audio') {\n return (data.outputAudio ?? data.audio) as string | undefined;\n }\n return undefined;\n}\n\n/**\n * Hook that performs comprehensive validation for the Generate button.\n *\n * Validates:\n * 1. Required connections exist (from NODE_DEFINITIONS)\n * 2. Connected nodes have actual data values (not just edges)\n * 3. Required schema fields from model inputSchema are filled\n *\n * @returns Object with canGenerate boolean and detailed breakdown\n */\nexport function useCanGenerate({\n nodeId,\n nodeType,\n inputSchema,\n schemaParams,\n}: UseCanGenerateOptions): CanGenerateResult {\n const { hasRequiredInputs, missingInputs } = useRequiredInputs(\n nodeId,\n nodeType,\n );\n const getConnectedInputs = useWorkflowStore(\n (state) => state.getConnectedInputs,\n );\n\n // Optimized selector: only get edges targeting this node\n // Uses useShallow to prevent re-renders when unrelated edges change\n const incomingEdgesSelector = useCallback(\n (state: { edges: WorkflowEdge[] }) =>\n state.edges.filter((e) => e.target === nodeId),\n [nodeId],\n );\n const incomingEdges = useWorkflowStore(useShallow(incomingEdgesSelector));\n\n // Optimized selector: only get source nodes connected to this node\n // Returns a stable object with just the output data we need\n const connectedOutputsSelector = useCallback(\n (state: { nodes: WorkflowNode[] }) => {\n const outputs: Record<string, string | undefined> = {};\n for (const edge of incomingEdges) {\n const sourceNode = state.nodes.find((n) => n.id === edge.source);\n if (sourceNode) {\n outputs[edge.source] = extractOutputValue(\n sourceNode,\n edge.sourceHandle,\n );\n }\n }\n return outputs;\n },\n [incomingEdges],\n );\n useWorkflowStore(useShallow(connectedOutputsSelector));\n\n return useMemo(() => {\n const missingItems: MissingItem[] = [];\n\n // 1. Check required connections exist\n for (const inputId of missingInputs) {\n missingItems.push({\n field: inputId,\n message: `Missing connection: ${inputId}`,\n type: 'connection',\n });\n }\n\n // 2. Check connected nodes targeting required handles have actual data\n const connectedInputs = getConnectedInputs(nodeId);\n const nodeDef = NODE_DEFINITIONS[nodeType];\n const requiredHandleIds = new Set(\n nodeDef?.inputs.filter((h) => h.required).map((h) => h.id) ?? [],\n );\n let hasRequiredData = true;\n let hasConnectedData = true;\n\n if (hasRequiredInputs) {\n for (const edge of incomingEdges) {\n const handleId = edge.targetHandle;\n if (!handleId) continue;\n\n if (!connectedInputs.has(handleId)) {\n hasConnectedData = false;\n if (requiredHandleIds.has(handleId)) {\n hasRequiredData = false;\n }\n }\n }\n }\n\n // 3. Validate required schema fields\n const schemaValidation = validateRequiredSchemaFields(\n inputSchema,\n schemaParams ?? {},\n CONNECTION_FIELDS,\n );\n\n for (const field of schemaValidation.missingFields) {\n missingItems.push({\n field,\n message: `Required field: ${field}`,\n type: 'schema',\n });\n }\n\n const canGenerate =\n hasRequiredInputs && hasRequiredData && schemaValidation.isValid;\n\n return {\n canGenerate,\n hasConnectedData,\n hasRequiredConnections: hasRequiredInputs,\n hasRequiredSchemaFields: schemaValidation.isValid,\n missingItems,\n };\n }, [\n nodeId,\n nodeType,\n hasRequiredInputs,\n missingInputs,\n inputSchema,\n schemaParams,\n getConnectedInputs,\n incomingEdges,\n ]);\n}\n","import type { ProviderModel, WorkflowNodeData } from '@genfeedai/types';\nimport { useCallback } from 'react';\nimport { getSchemaDefaults } from '../lib/schemaUtils';\nimport { useWorkflowStore } from '../stores/workflowStore';\n\ntype ModelMap = Record<string, string>;\n\ninterface SelectedModelData {\n provider: string;\n modelId: string;\n displayName: string;\n inputSchema: Record<string, unknown> | undefined;\n componentSchemas: Record<string, unknown> | undefined;\n}\n\ninterface UseModelSelectionOptions<TModel extends string> {\n /** Node ID to update */\n nodeId: string;\n /** Map of provider model IDs to internal model types */\n modelMap: ModelMap;\n /** Fallback internal model if not found in map */\n fallbackModel: TModel;\n}\n\n/**\n * Hook for handling model selection in AI generator nodes.\n * Consolidates the common pattern from ImageGenNode and VideoGenNode.\n *\n * @returns handleModelSelect callback to pass to ModelBrowserModal\n */\nexport function useModelSelection<\n TModel extends string,\n TNodeData extends WorkflowNodeData & { model?: TModel },\n>({ nodeId, modelMap, fallbackModel }: UseModelSelectionOptions<TModel>) {\n const updateNodeData = useWorkflowStore((state) => state.updateNodeData);\n\n const handleModelSelect = useCallback(\n (model: ProviderModel) => {\n const internalModel = (modelMap[model.id] ?? fallbackModel) as TModel;\n\n // Extract defaults from the new model's schema\n const schemaDefaults = getSchemaDefaults(model.inputSchema);\n\n const selectedModel: SelectedModelData = {\n componentSchemas: model.componentSchemas,\n displayName: model.displayName,\n inputSchema: model.inputSchema,\n modelId: model.id,\n provider: model.provider,\n };\n\n updateNodeData<TNodeData>(nodeId, {\n model: internalModel,\n provider: model.provider,\n schemaParams: schemaDefaults,\n selectedModel,\n } as Partial<TNodeData>);\n },\n [nodeId, modelMap, fallbackModel, updateNodeData],\n );\n\n return { handleModelSelect };\n}\n","import { NodeStatusEnum } from '@genfeedai/types';\nimport { useCallback } from 'react';\nimport { useExecutionStore } from '../stores/executionStore';\nimport { useWorkflowStore } from '../stores/workflowStore';\n\n/**\n * Hook for triggering and stopping node execution\n *\n * Encapsulates the common pattern of:\n * 1. Setting node status to processing\n * 2. Triggering execution\n * 3. Stopping execution and resetting status\n *\n * @param nodeId - The ID of the node to execute\n * @returns handleGenerate - Callback to trigger node execution\n * @returns handleStop - Callback to stop node execution\n */\nexport function useNodeExecution(nodeId: string) {\n const updateNodeData = useWorkflowStore((state) => state.updateNodeData);\n const executeNode = useExecutionStore((state) => state.executeNode);\n const stopNodeExecution = useExecutionStore(\n (state) => state.stopNodeExecution,\n );\n\n const handleGenerate = useCallback(() => {\n updateNodeData(nodeId, { status: NodeStatusEnum.PROCESSING });\n executeNode(nodeId);\n }, [nodeId, executeNode, updateNodeData]);\n\n const handleStop = useCallback(() => {\n stopNodeExecution(nodeId);\n }, [nodeId, stopNodeExecution]);\n\n return { handleGenerate, handleStop };\n}\n","import type { WorkflowNodeData } from '@genfeedai/types';\nimport { useCallback, useRef, useState } from 'react';\nimport { getImageDimensions, getVideoMetadata } from '../lib/media';\nimport { useWorkflowUIConfig } from '../provider/WorkflowUIProvider';\nimport { useWorkflowStore } from '../stores/workflowStore';\n\ninterface UseMediaUploadOptions<T extends WorkflowNodeData> {\n nodeId: string;\n mediaType: 'image' | 'video';\n initialUrl?: string;\n getMetadata: (src: string) => Promise<Record<string, unknown>>;\n buildUploadUpdate: (\n url: string,\n filename: string,\n metadata: Record<string, unknown>,\n ) => Partial<T>;\n buildUrlUpdate: (\n url: string,\n metadata: Record<string, unknown> | null,\n ) => Partial<T>;\n buildRemoveUpdate: () => Partial<T>;\n}\n\n/**\n * Read a file as base64 data URL and apply metadata + update.\n */\nfunction readFileAsBase64<T extends WorkflowNodeData>(\n file: File,\n nodeId: string,\n getMetadata: (src: string) => Promise<Record<string, unknown>>,\n buildUploadUpdate: (\n url: string,\n filename: string,\n metadata: Record<string, unknown>,\n ) => Partial<T>,\n updateNodeData: <U extends WorkflowNodeData>(\n id: string,\n data: Partial<U>,\n ) => void,\n onComplete?: () => void,\n): void {\n const reader = new FileReader();\n reader.onload = async (event) => {\n const dataUrl = event.target?.result as string;\n const metadata = await getMetadata(dataUrl);\n updateNodeData<T>(nodeId, buildUploadUpdate(dataUrl, file.name, metadata));\n onComplete?.();\n };\n reader.readAsDataURL(file);\n}\n\nexport function useMediaUpload<T extends WorkflowNodeData>({\n nodeId,\n mediaType,\n initialUrl = '',\n getMetadata,\n buildUploadUpdate,\n buildUrlUpdate,\n buildRemoveUpdate,\n}: UseMediaUploadOptions<T>) {\n const updateNodeData = useWorkflowStore((state) => state.updateNodeData);\n const workflowId = useWorkflowStore((state) => state.workflowId);\n const { fileUpload } = useWorkflowUIConfig();\n const fileInputRef = useRef<HTMLInputElement>(null);\n const [showUrlInput, setShowUrlInput] = useState(false);\n const [urlValue, setUrlValue] = useState(initialUrl);\n const [isUploading, setIsUploading] = useState(false);\n\n // Refs for builder functions to keep callbacks stable\n const getMetadataRef = useRef(getMetadata);\n getMetadataRef.current = getMetadata;\n const buildUploadUpdateRef = useRef(buildUploadUpdate);\n buildUploadUpdateRef.current = buildUploadUpdate;\n const buildUrlUpdateRef = useRef(buildUrlUpdate);\n buildUrlUpdateRef.current = buildUrlUpdate;\n const buildRemoveUpdateRef = useRef(buildRemoveUpdate);\n buildRemoveUpdateRef.current = buildRemoveUpdate;\n\n const handleFileSelect = useCallback(\n async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n\n if (workflowId && fileUpload) {\n setIsUploading(true);\n try {\n const result = await fileUpload.uploadFile(\n `/files/workflows/${workflowId}/input/${mediaType}`,\n file,\n );\n\n const metadata = await getMetadataRef.current(result.url);\n updateNodeData<T>(\n nodeId,\n buildUploadUpdateRef.current(result.url, result.filename, metadata),\n );\n } catch (_error) {\n // Fallback to Base64 if upload fails\n readFileAsBase64<T>(\n file,\n nodeId,\n getMetadataRef.current,\n buildUploadUpdateRef.current,\n updateNodeData,\n );\n } finally {\n setIsUploading(false);\n }\n } else {\n // Workflow not saved yet or no upload service - use Base64\n readFileAsBase64<T>(\n file,\n nodeId,\n getMetadataRef.current,\n buildUploadUpdateRef.current,\n updateNodeData,\n );\n }\n },\n [nodeId, updateNodeData, workflowId, mediaType, fileUpload],\n );\n\n const handleRemove = useCallback(() => {\n updateNodeData<T>(nodeId, buildRemoveUpdateRef.current());\n setUrlValue('');\n }, [nodeId, updateNodeData]);\n\n const handleUrlSubmit = useCallback(async () => {\n if (!urlValue.trim()) return;\n\n try {\n let metadata: Record<string, unknown>;\n if (mediaType === 'image') {\n metadata = await getImageDimensions(urlValue);\n } else {\n const meta = await getVideoMetadata(urlValue);\n metadata = {\n duration: meta.duration,\n height: meta.dimensions.height,\n width: meta.dimensions.width,\n };\n }\n updateNodeData<T>(nodeId, buildUrlUpdateRef.current(urlValue, metadata));\n } catch (_error) {\n updateNodeData<T>(nodeId, buildUrlUpdateRef.current(urlValue, null));\n }\n setShowUrlInput(false);\n }, [nodeId, updateNodeData, urlValue, mediaType]);\n\n const handleUrlKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === 'Enter') {\n handleUrlSubmit();\n } else if (e.key === 'Escape') {\n setShowUrlInput(false);\n setUrlValue(initialUrl);\n }\n },\n [handleUrlSubmit, initialUrl],\n );\n\n return {\n fileInputRef,\n handleFileSelect,\n handleRemove,\n handleUrlKeyDown,\n handleUrlSubmit,\n isUploading,\n setShowUrlInput,\n setUrlValue,\n showUrlInput,\n urlValue,\n };\n}\n","import type { AvailableVariable } from '@genfeedai/types';\nimport type { RefObject } from 'react';\nimport { useCallback, useMemo, useState } from 'react';\n\ninterface UsePromptAutocompleteOptions {\n availableVariables: AvailableVariable[];\n textareaRef: RefObject<HTMLTextAreaElement | null>;\n localTemplate: string;\n setLocalTemplate: (value: string) => void;\n onTemplateCommit?: (newTemplate: string) => void;\n}\n\ninterface UsePromptAutocompleteReturn {\n showAutocomplete: boolean;\n autocompletePosition: { top: number; left: number };\n filteredAutocompleteVars: AvailableVariable[];\n selectedAutocompleteIndex: number;\n handleChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;\n handleKeyDown: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void;\n handleAutocompleteSelect: (varName: string) => void;\n closeAutocomplete: () => void;\n}\n\nexport function usePromptAutocomplete({\n availableVariables,\n textareaRef,\n localTemplate,\n setLocalTemplate,\n onTemplateCommit,\n}: UsePromptAutocompleteOptions): UsePromptAutocompleteReturn {\n const [showAutocomplete, setShowAutocomplete] = useState(false);\n const [autocompletePosition, setAutocompletePosition] = useState({\n left: 0,\n top: 0,\n });\n const [autocompleteFilter, setAutocompleteFilter] = useState('');\n const [selectedAutocompleteIndex, setSelectedAutocompleteIndex] = useState(0);\n\n const filteredAutocompleteVars = useMemo(() => {\n return availableVariables.filter((v) =>\n v.name.toLowerCase().includes(autocompleteFilter.toLowerCase()),\n );\n }, [availableVariables, autocompleteFilter]);\n\n const handleAutocompleteSelect = useCallback(\n (varName: string) => {\n if (!textareaRef.current) return;\n\n const cursorPos = textareaRef.current.selectionStart;\n const textBeforeCursor = localTemplate.slice(0, cursorPos);\n const textAfterCursor = localTemplate.slice(cursorPos);\n\n const match = textBeforeCursor.match(/@(\\w*)$/);\n if (!match) return;\n\n const atPosition = cursorPos - match[0].length;\n const newTemplate = `${localTemplate.slice(0, atPosition)}@${varName}${textAfterCursor}`;\n\n setLocalTemplate(newTemplate);\n onTemplateCommit?.(newTemplate);\n setShowAutocomplete(false);\n\n const newCursorPos = atPosition + varName.length + 1;\n setTimeout(() => {\n if (textareaRef.current) {\n textareaRef.current.focus();\n textareaRef.current.setSelectionRange(newCursorPos, newCursorPos);\n }\n }, 0);\n },\n [localTemplate, textareaRef, setLocalTemplate, onTemplateCommit],\n );\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n const newValue = e.target.value;\n setLocalTemplate(newValue);\n\n const cursorPos = e.target.selectionStart;\n const textBeforeCursor = newValue.slice(0, cursorPos);\n const match = textBeforeCursor.match(/@(\\w*)$/);\n\n if (match && textareaRef.current) {\n setAutocompleteFilter(match[1] || '');\n setSelectedAutocompleteIndex(0);\n\n const lineHeight = 20;\n const lines = textBeforeCursor.split('\\n');\n const currentLine = lines.length - 1;\n const top = currentLine * lineHeight + 30;\n const left = 10;\n\n setAutocompletePosition({ left, top });\n setShowAutocomplete(true);\n } else {\n setShowAutocomplete(false);\n }\n },\n [textareaRef, setLocalTemplate],\n );\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (!showAutocomplete) return;\n\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n setSelectedAutocompleteIndex(\n (prev) => (prev + 1) % filteredAutocompleteVars.length,\n );\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n setSelectedAutocompleteIndex(\n (prev) =>\n (prev - 1 + filteredAutocompleteVars.length) %\n filteredAutocompleteVars.length,\n );\n } else if (e.key === 'Enter' || e.key === 'Tab') {\n if (filteredAutocompleteVars.length > 0) {\n e.preventDefault();\n handleAutocompleteSelect(\n filteredAutocompleteVars[selectedAutocompleteIndex].name,\n );\n }\n } else if (e.key === 'Escape') {\n e.preventDefault();\n e.stopPropagation();\n setShowAutocomplete(false);\n }\n },\n [\n showAutocomplete,\n filteredAutocompleteVars,\n selectedAutocompleteIndex,\n handleAutocompleteSelect,\n ],\n );\n\n const closeAutocomplete = useCallback(() => {\n setShowAutocomplete(false);\n }, []);\n\n return {\n autocompletePosition,\n closeAutocomplete,\n filteredAutocompleteVars,\n handleAutocompleteSelect,\n handleChange,\n handleKeyDown,\n selectedAutocompleteIndex,\n showAutocomplete,\n };\n}\n"]}
@@ -0,0 +1,3 @@
1
+
2
+ //# sourceMappingURL=chunk-SRPSHHHV.mjs.map
3
+ //# sourceMappingURL=chunk-SRPSHHHV.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-SRPSHHHV.mjs"}
@@ -1,4 +1,4 @@
1
- import { useWorkflowStore } from './chunk-GPYIIWD5.mjs';
1
+ import { useWorkflowStore } from './chunk-7DJHFOIW.mjs';
2
2
  import { useMemo, useCallback } from 'react';
3
3
 
4
4
  function useCommentNavigation(nodeId) {
@@ -56,3 +56,5 @@ function useCommentNavigation(nodeId) {
56
56
  }
57
57
 
58
58
  export { useCommentNavigation };
59
+ //# sourceMappingURL=chunk-TOFB4BTA.mjs.map
60
+ //# sourceMappingURL=chunk-TOFB4BTA.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hooks/useCommentNavigation.ts"],"names":[],"mappings":";;;AAcO,SAAS,qBAAqB,MAAA,EAA0C;AAC7E,EAAA,MAAM,KAAA,GAAQ,gBAAA,CAAiB,CAAC,KAAA,KAAU,MAAM,KAAK,CAAA;AACrD,EAAA,MAAM,oBAAA,GAAuB,gBAAA;AAAA,IAC3B,CAAC,UAAU,KAAA,CAAM;AAAA,GACnB;AACA,EAAA,MAAM,iBAAA,GAAoB,gBAAA;AAAA,IACxB,CAAC,UAAU,KAAA,CAAM;AAAA,GACnB;AACA,EAAA,MAAM,mBAAA,GAAsB,gBAAA;AAAA,IAC1B,CAAC,UAAU,KAAA,CAAM;AAAA,GACnB;AAEA,EAAA,MAAM,WAAA,GAAc,QAAQ,MAAM;AAChC,IAAA,MAAM,OAAO,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,MAAM,CAAA;AAC9C,IAAA,MAAM,OAAO,IAAA,EAAM,IAAA;AACnB,IAAA,OAAO,IAAA,EAAM,OAAA,EAAS,IAAA,EAAK,IAAK,IAAA;AAAA,EAClC,CAAA,EAAG,CAAC,KAAA,EAAO,MAAM,CAAC,CAAA;AAElB,EAAA,MAAM,iBAAA,GAAoB,QAAQ,MAAM;AACtC,IAAA,OAAO,oBAAA,EAAqB;AAAA,EAC9B,CAAA,EAAG,CAAC,oBAAoB,CAAC,CAAA;AAEzB,EAAA,MAAM,YAAA,GAAe,QAAQ,MAAM;AACjC,IAAA,OAAO,kBAAkB,SAAA,CAAU,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,MAAM,CAAA;AAAA,EAC3D,CAAA,EAAG,CAAC,iBAAA,EAAmB,MAAM,CAAC,CAAA;AAE9B,EAAA,MAAM,UAAA,GAAa,WAAA;AAAA,IACjB,CAAC,WAAA,KAAwB;AACvB,MAAA,MAAM,UAAA,GAAa,kBAAkB,WAAW,CAAA;AAChD,MAAA,IAAI,UAAA,EAAY;AACd,QAAA,iBAAA,CAAkB,WAAW,EAAE,CAAA;AAC/B,QAAA,mBAAA,CAAoB,WAAW,EAAE,CAAA;AAAA,MACnC;AAAA,IACF,CAAA;AAAA,IACA,CAAC,iBAAA,EAAmB,iBAAA,EAAmB,mBAAmB;AAAA,GAC5D;AAEA,EAAA,MAAM,UAAA,GAAa,YAAY,MAAM;AACnC,IAAA,IAAI,iBAAA,CAAkB,WAAW,CAAA,EAAG;AACpC,IAAA,MAAM,WACJ,YAAA,IAAgB,CAAA,GAAI,iBAAA,CAAkB,MAAA,GAAS,IAAI,YAAA,GAAe,CAAA;AACpE,IAAA,UAAA,CAAW,QAAQ,CAAA;AAAA,EACrB,GAAG,CAAC,YAAA,EAAc,iBAAA,CAAkB,MAAA,EAAQ,UAAU,CAAC,CAAA;AAEvD,EAAA,MAAM,MAAA,GAAS,YAAY,MAAM;AAC/B,IAAA,IAAI,iBAAA,CAAkB,WAAW,CAAA,EAAG;AACpC,IAAA,MAAM,QAAA,GAAA,CAAY,YAAA,GAAe,CAAA,IAAK,iBAAA,CAAkB,MAAA;AACxD,IAAA,UAAA,CAAW,QAAQ,CAAA;AAAA,EACrB,GAAG,CAAC,YAAA,EAAc,iBAAA,CAAkB,MAAA,EAAQ,UAAU,CAAC,CAAA;AAEvD,EAAA,IAAI,CAAC,WAAA,IAAe,YAAA,KAAiB,EAAA,EAAI;AACvC,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO;AAAA,IACL,cAAc,YAAA,GAAe,CAAA;AAAA;AAAA,IAC7B,MAAA;AAAA,IACA,UAAA;AAAA,IACA,YAAY,iBAAA,CAAkB;AAAA,GAChC;AACF","file":"chunk-TOFB4BTA.mjs","sourcesContent":["import { useCallback, useMemo } from 'react';\nimport { useWorkflowStore } from '../stores/workflowStore';\n\nexport interface CommentNavigation {\n currentIndex: number;\n totalCount: number;\n onPrevious: () => void;\n onNext: () => void;\n}\n\n/**\n * Hook that provides navigation props for nodes with comments.\n * Returns null if the node has no comment.\n */\nexport function useCommentNavigation(nodeId: string): CommentNavigation | null {\n const nodes = useWorkflowStore((state) => state.nodes);\n const getNodesWithComments = useWorkflowStore(\n (state) => state.getNodesWithComments,\n );\n const markCommentViewed = useWorkflowStore(\n (state) => state.markCommentViewed,\n );\n const setNavigationTarget = useWorkflowStore(\n (state) => state.setNavigationTarget,\n );\n\n const nodeComment = useMemo(() => {\n const node = nodes.find((n) => n.id === nodeId);\n const data = node?.data as { comment?: string } | undefined;\n return data?.comment?.trim() || null;\n }, [nodes, nodeId]);\n\n const nodesWithComments = useMemo(() => {\n return getNodesWithComments();\n }, [getNodesWithComments]);\n\n const currentIndex = useMemo(() => {\n return nodesWithComments.findIndex((n) => n.id === nodeId);\n }, [nodesWithComments, nodeId]);\n\n const navigateTo = useCallback(\n (targetIndex: number) => {\n const targetNode = nodesWithComments[targetIndex];\n if (targetNode) {\n markCommentViewed(targetNode.id);\n setNavigationTarget(targetNode.id);\n }\n },\n [nodesWithComments, markCommentViewed, setNavigationTarget],\n );\n\n const onPrevious = useCallback(() => {\n if (nodesWithComments.length === 0) return;\n const newIndex =\n currentIndex <= 0 ? nodesWithComments.length - 1 : currentIndex - 1;\n navigateTo(newIndex);\n }, [currentIndex, nodesWithComments.length, navigateTo]);\n\n const onNext = useCallback(() => {\n if (nodesWithComments.length === 0) return;\n const newIndex = (currentIndex + 1) % nodesWithComments.length;\n navigateTo(newIndex);\n }, [currentIndex, nodesWithComments.length, navigateTo]);\n\n if (!nodeComment || currentIndex === -1) {\n return null;\n }\n\n return {\n currentIndex: currentIndex + 1, // 1-based for display\n onNext,\n onPrevious,\n totalCount: nodesWithComments.length,\n };\n}\n"]}
@@ -1,7 +1,7 @@
1
- import { useWorkflowUIConfig } from './chunk-YUIK4AHM.mjs';
2
- import { selectNodes, selectEdges, selectRemoveNode, selectDuplicateNode, selectAddNode, useContextMenuStore, selectToggleNodeLock, selectCreateGroup, selectWorkflowId, selectSetSelectedNodeIds, selectUpdateNodeData } from './chunk-7LV4UAUS.mjs';
3
- import { useSettingsStore } from './chunk-OJWVEEMM.mjs';
4
- import { useWorkflowStore } from './chunk-GPYIIWD5.mjs';
1
+ import { useWorkflowUIConfig } from './chunk-JSF4FHBH.mjs';
2
+ import { selectNodes, selectEdges, selectRemoveNode, selectDuplicateNode, selectAddNode, useContextMenuStore, selectToggleNodeLock, selectCreateGroup, selectWorkflowId, selectSetSelectedNodeIds, selectUpdateNodeData } from './chunk-IKR6GVZ4.mjs';
3
+ import { useSettingsStore } from './chunk-R5L7WB7F.mjs';
4
+ import { useWorkflowStore } from './chunk-7DJHFOIW.mjs';
5
5
  import { useEffect, useState, useCallback, useRef, useMemo } from 'react';
6
6
  import { nanoid } from 'nanoid';
7
7
  import { useReactFlow } from '@xyflow/react';
@@ -1338,3 +1338,5 @@ function useContextMenu() {
1338
1338
  }
1339
1339
 
1340
1340
  export { ContextMenu, useCanvasKeyboardShortcuts, useContextMenu, useNodeActions, usePaneActions };
1341
+ //# sourceMappingURL=chunk-VKXTPLM7.mjs.map
1342
+ //# sourceMappingURL=chunk-VKXTPLM7.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hooks/useCanvasKeyboardShortcuts.ts","../src/hooks/useNodeActions.ts","../src/lib/autoLayout.ts","../src/hooks/usePaneActions.ts","../src/components/context-menu/menus/edgeMenu.tsx","../src/components/context-menu/ContextMenuSeparator.tsx","../src/components/context-menu/ContextMenuItem.tsx","../src/components/context-menu/ContextMenu.tsx","../src/components/context-menu/menus/nodeMenu.tsx","../src/components/context-menu/menus/paneMenu.tsx","../src/components/context-menu/menus/selectionMenu.tsx","../src/hooks/useContextMenu.ts"],"names":["useCallback","jsx","useState","useRef","useEffect","Trash2","Image","Scissors","Copy","Lock","LockOpen","useReactFlow"],"mappings":"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","file":"chunk-VKXTPLM7.mjs","sourcesContent":["import type { NodeType, WorkflowNode } from '@genfeedai/types';\nimport type { FitViewOptions } from '@xyflow/react';\nimport { useEffect } from 'react';\nimport { useWorkflowStore } from '../stores/workflowStore';\nimport type { NodeGroup } from '../types/groups';\n\ninterface UseCanvasKeyboardShortcutsParams {\n selectedNodeIds: string[];\n groups: NodeGroup[];\n nodes: WorkflowNode[];\n toggleNodeLock: (nodeId: string) => void;\n createGroup: (nodeIds: string[]) => string;\n deleteGroup: (groupId: string) => void;\n unlockAllNodes: () => void;\n addNode: (type: NodeType, position: { x: number; y: number }) => string;\n togglePalette: () => void;\n fitView: (options?: FitViewOptions) => void;\n openShortcutHelp: () => void;\n openNodeSearch: () => void;\n deleteSelectedElements: () => void;\n}\n\n/**\n * Hook that handles keyboard shortcuts for the workflow canvas\n *\n * Shortcuts:\n * - M: Toggle sidebar/palette\n * - L: Toggle lock on selected nodes\n * - F: Fit view to selection (or all if none selected)\n * - ?: Show shortcut help modal\n * - Ctrl/Cmd+F: Open node search\n * - Ctrl/Cmd+G: Create group from selection\n * - Ctrl/Cmd+Shift+G: Ungroup selected nodes\n * - Ctrl/Cmd+Shift+L: Unlock all nodes\n * - Shift+I: Add image generator node\n * - Shift+V: Add video generator node\n * - Shift+P: Add prompt node\n * - Shift+L: Add LLM node\n * - Ctrl/Cmd+Z: Undo\n * - Ctrl/Cmd+Shift+Z: Redo\n */\nexport function useCanvasKeyboardShortcuts({\n selectedNodeIds,\n groups,\n nodes,\n toggleNodeLock,\n createGroup,\n deleteGroup,\n unlockAllNodes,\n addNode,\n togglePalette,\n fitView,\n openShortcutHelp,\n openNodeSearch,\n deleteSelectedElements,\n}: UseCanvasKeyboardShortcutsParams) {\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n // Ignore if typing in input\n if (\n e.target instanceof HTMLInputElement ||\n e.target instanceof HTMLTextAreaElement ||\n (e.target as HTMLElement)?.contentEditable === 'true' ||\n (e.target as HTMLElement)?.closest?.(\n '[role=\"textbox\"], [role=\"combobox\"], [role=\"searchbox\"]',\n )\n ) {\n return;\n }\n\n const isMod = e.ctrlKey || e.metaKey;\n\n // Delete/Backspace - Delete selected elements\n if (e.key === 'Delete' || e.key === 'Backspace') {\n e.preventDefault();\n deleteSelectedElements();\n return;\n }\n\n // M - Toggle sidebar (Todoist style)\n if (e.key === 'm' && !isMod && !e.shiftKey) {\n e.preventDefault();\n togglePalette();\n }\n\n // F - Fit view to selection (or all nodes if none selected)\n if (e.key === 'f' && !isMod && !e.shiftKey) {\n e.preventDefault();\n if (selectedNodeIds.length > 0) {\n // Fit to selected nodes\n const selectedNodes = nodes.filter((n) =>\n selectedNodeIds.includes(n.id),\n );\n fitView({ duration: 200, nodes: selectedNodes, padding: 0.3 });\n } else {\n // Fit to all nodes\n fitView({ duration: 200, padding: 0.2 });\n }\n }\n\n // ? - Show shortcut help modal\n if (e.key === '?' && e.shiftKey && !isMod) {\n e.preventDefault();\n openShortcutHelp();\n }\n\n // Ctrl/Cmd+F - Open node search\n if (e.key === 'f' && isMod && !e.shiftKey) {\n e.preventDefault();\n openNodeSearch();\n }\n\n // L - Toggle lock on selected nodes\n if (e.key === 'l' && !isMod && !e.shiftKey) {\n e.preventDefault();\n for (const nodeId of selectedNodeIds) {\n toggleNodeLock(nodeId);\n }\n }\n\n // Ctrl+G - Create group from selected nodes\n if (e.key === 'g' && isMod && !e.shiftKey) {\n e.preventDefault();\n if (selectedNodeIds.length > 1) {\n createGroup(selectedNodeIds);\n }\n }\n\n // Ctrl+Shift+G - Ungroup (delete group containing selected nodes)\n if (e.key === 'g' && isMod && e.shiftKey) {\n e.preventDefault();\n for (const nodeId of selectedNodeIds) {\n const group = groups.find((g) => g.nodeIds.includes(nodeId));\n if (group) {\n deleteGroup(group.id);\n break;\n }\n }\n }\n\n // Ctrl+Shift+L - Unlock all nodes\n if (e.key === 'l' && isMod && e.shiftKey) {\n e.preventDefault();\n unlockAllNodes();\n }\n\n // Shift+I - Add image generator node at viewport center\n if (e.key === 'I' && e.shiftKey && !isMod) {\n e.preventDefault();\n const position = {\n x: window.innerWidth / 2 - 150,\n y: window.innerHeight / 2 - 150,\n };\n addNode('imageGen', position);\n }\n\n // Shift+V - Add video generator node at viewport center\n if (e.key === 'V' && e.shiftKey && !isMod) {\n e.preventDefault();\n const position = {\n x: window.innerWidth / 2 - 150,\n y: window.innerHeight / 2 - 150,\n };\n addNode('videoGen', position);\n }\n\n // Shift+P - Add prompt node at viewport center\n if (e.key === 'P' && e.shiftKey && !isMod) {\n e.preventDefault();\n const position = {\n x: window.innerWidth / 2 - 150,\n y: window.innerHeight / 2 - 150,\n };\n addNode('prompt', position);\n }\n\n // Shift+L - Add LLM node at viewport center\n if ((e.key === 'L' || e.key === 'l') && e.shiftKey && !isMod) {\n e.preventDefault();\n const position = {\n x: window.innerWidth / 2 - 150,\n y: window.innerHeight / 2 - 150,\n };\n addNode('llm', position);\n }\n\n // Cmd/Ctrl+Z - Undo\n if (e.key === 'z' && isMod && !e.shiftKey) {\n e.preventDefault();\n useWorkflowStore.temporal.getState().undo();\n }\n\n // Cmd/Ctrl+Shift+Z - Redo\n if (e.key === 'z' && isMod && e.shiftKey) {\n e.preventDefault();\n useWorkflowStore.temporal.getState().redo();\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [\n selectedNodeIds,\n toggleNodeLock,\n createGroup,\n deleteGroup,\n unlockAllNodes,\n groups,\n nodes,\n addNode,\n togglePalette,\n fitView,\n openShortcutHelp,\n openNodeSearch,\n deleteSelectedElements,\n ]);\n}\n","import type {\n WorkflowEdge,\n WorkflowNode,\n WorkflowNodeData,\n} from '@genfeedai/types';\nimport { nanoid } from 'nanoid';\nimport { useCallback, useState } from 'react';\nimport {\n selectDuplicateNode,\n selectEdges,\n selectNodes,\n selectRemoveNode,\n} from '../stores/workflow/selectors';\nimport { useWorkflowStore } from '../stores/workflowStore';\n\ninterface ClipboardData {\n nodes: WorkflowNode[];\n edges: WorkflowEdge[];\n isCut: boolean;\n}\n\n/**\n * Create remapped nodes and edges from clipboard data at the given position offset.\n * Shared by both `pasteNodes` and `getPasteData`.\n */\nfunction createPastePayload(\n clipboard: ClipboardData,\n offsetX: number,\n offsetY: number,\n): { nodes: WorkflowNode[]; edges: WorkflowEdge[] } {\n const { nodes: clipboardNodes, edges: clipboardEdges } = clipboard;\n\n // Create a map from old IDs to new IDs\n const idMap = new Map<string, string>();\n for (const node of clipboardNodes) {\n idMap.set(node.id, nanoid(8));\n }\n\n // Calculate the top-left corner of the copied nodes for offset calculation\n const minX = Math.min(...clipboardNodes.map((n) => n.position.x));\n const minY = Math.min(...clipboardNodes.map((n) => n.position.y));\n\n // Create new nodes with remapped IDs and offset positions\n const newNodes: WorkflowNode[] = clipboardNodes.map((node) => ({\n ...node,\n data: {\n ...node.data,\n error: undefined,\n jobId: null,\n status: 'idle',\n } as WorkflowNodeData,\n id: idMap.get(node.id)!,\n position: {\n x: node.position.x - minX + offsetX,\n y: node.position.y - minY + offsetY,\n },\n selected: true,\n }));\n\n // Remap edges to use new node IDs\n const newEdges: WorkflowEdge[] = clipboardEdges.map((edge) => ({\n ...edge,\n id: nanoid(8),\n source: idMap.get(edge.source)!,\n target: idMap.get(edge.target)!,\n }));\n\n return { edges: newEdges, nodes: newNodes };\n}\n\nexport function useNodeActions() {\n const nodes = useWorkflowStore(selectNodes);\n const edges = useWorkflowStore(selectEdges);\n const removeNode = useWorkflowStore(selectRemoveNode);\n const duplicateNode = useWorkflowStore(selectDuplicateNode);\n const [clipboard, setClipboard] = useState<ClipboardData | null>(null);\n\n const deleteNode = useCallback(\n (nodeId: string) => {\n removeNode(nodeId);\n },\n [removeNode],\n );\n\n const duplicate = useCallback(\n (nodeId: string) => {\n return duplicateNode(nodeId);\n },\n [duplicateNode],\n );\n\n const copyNode = useCallback(\n (nodeId: string) => {\n const node = nodes.find((n) => n.id === nodeId);\n if (node) {\n // Copy the node and any edges between copied nodes (just one node here)\n setClipboard({ edges: [], isCut: false, nodes: [node] });\n }\n },\n [nodes],\n );\n\n const copyMultipleNodes = useCallback(\n (nodeIds: string[]) => {\n const nodeSet = new Set(nodeIds);\n const nodesToCopy = nodes.filter((n) => nodeSet.has(n.id));\n // Copy edges that connect nodes within the selection\n const edgesToCopy = edges.filter(\n (e) => nodeSet.has(e.source) && nodeSet.has(e.target),\n );\n if (nodesToCopy.length > 0) {\n setClipboard({ edges: edgesToCopy, isCut: false, nodes: nodesToCopy });\n }\n },\n [nodes, edges],\n );\n\n const cutNode = useCallback(\n (nodeId: string) => {\n const node = nodes.find((n) => n.id === nodeId);\n if (node) {\n setClipboard({ edges: [], isCut: true, nodes: [node] });\n removeNode(nodeId);\n }\n },\n [nodes, removeNode],\n );\n\n const cutMultipleNodes = useCallback(\n (nodeIds: string[]) => {\n const nodeSet = new Set(nodeIds);\n const nodesToCut = nodes.filter((n) => nodeSet.has(n.id));\n const edgesToCut = edges.filter(\n (e) => nodeSet.has(e.source) && nodeSet.has(e.target),\n );\n if (nodesToCut.length > 0) {\n setClipboard({ edges: edgesToCut, isCut: true, nodes: nodesToCut });\n for (const nodeId of nodeIds) {\n removeNode(nodeId);\n }\n }\n },\n [nodes, edges, removeNode],\n );\n\n const deleteMultipleNodes = useCallback(\n (nodeIds: string[]) => {\n for (const nodeId of nodeIds) {\n removeNode(nodeId);\n }\n },\n [removeNode],\n );\n\n const duplicateMultipleNodes = useCallback(\n (nodeIds: string[]) => {\n const newIds: string[] = [];\n for (const nodeId of nodeIds) {\n const newId = duplicateNode(nodeId);\n if (newId) {\n newIds.push(newId);\n }\n }\n return newIds;\n },\n [duplicateNode],\n );\n\n /**\n * Paste nodes from clipboard at the given position offset.\n * Returns the new node IDs if paste was successful.\n */\n const pasteNodes = useCallback(\n (\n offsetX: number,\n offsetY: number,\n ): { nodeIds: string[]; edgeIds: string[] } | null => {\n if (!clipboard || clipboard.nodes.length === 0) return null;\n\n const payload = createPastePayload(clipboard, offsetX, offsetY);\n\n // Clear cut clipboard after paste (cut is one-time)\n if (clipboard.isCut) {\n setClipboard(null);\n }\n\n return {\n edgeIds: payload.edges.map((e) => e.id),\n nodeIds: payload.nodes.map((n) => n.id),\n };\n },\n [clipboard],\n );\n\n /**\n * Get nodes and edges to paste with remapped IDs.\n * Used by the context menu to actually add them to the store.\n */\n const getPasteData = useCallback(\n (\n offsetX: number,\n offsetY: number,\n ): { nodes: WorkflowNode[]; edges: WorkflowEdge[] } | null => {\n if (!clipboard || clipboard.nodes.length === 0) return null;\n\n const payload = createPastePayload(clipboard, offsetX, offsetY);\n\n // Clear cut clipboard after paste (cut is one-time)\n if (clipboard.isCut) {\n setClipboard(null);\n }\n\n return payload;\n },\n [clipboard],\n );\n\n return {\n clipboard,\n copyMultipleNodes,\n copyNode,\n cutMultipleNodes,\n cutNode,\n deleteMultipleNodes,\n deleteNode,\n duplicate,\n duplicateMultipleNodes,\n getPasteData,\n pasteNodes,\n };\n}\n","import Dagre from '@dagrejs/dagre';\nimport type { NodeType } from '@genfeedai/types';\nimport { NODE_DEFINITIONS } from '@genfeedai/types';\nimport type { Edge, Node } from '@xyflow/react';\n\ninterface LayoutOptions {\n direction?: 'TB' | 'LR' | 'BT' | 'RL';\n nodeSpacing?: number;\n rankSpacing?: number;\n}\n\nconst DEFAULT_NODE_WIDTH = 280;\nconst DEFAULT_NODE_HEIGHT = 200;\nconst MIN_GAP = 40;\n\ninterface Rect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/**\n * Get node bounding box from current position\n */\nfunction getNodeRect(node: Node): Rect {\n return {\n height: node.measured?.height ?? DEFAULT_NODE_HEIGHT,\n width: node.measured?.width ?? DEFAULT_NODE_WIDTH,\n x: node.position.x,\n y: node.position.y,\n };\n}\n\n/**\n * Get the index of an input handle on a node (used for vertical ordering)\n */\nfunction getInputHandleIndex(nodeType: string, handleId: string): number {\n const nodeDef = NODE_DEFINITIONS[nodeType as NodeType];\n if (!nodeDef) return 0;\n const index = nodeDef.inputs.findIndex((h) => h.id === handleId);\n return index === -1 ? 0 : index;\n}\n\n/**\n * Check if two rectangles overlap (including gap)\n */\nfunction rectsOverlap(a: Rect, b: Rect, gap: number): boolean {\n return (\n a.x < b.x + b.width + gap &&\n a.x + a.width + gap > b.x &&\n a.y < b.y + b.height + gap &&\n a.y + a.height + gap > b.y\n );\n}\n\n/**\n * Calculate overlap amount on each axis\n */\nfunction getOverlap(a: Rect, b: Rect, gap: number): { x: number; y: number } {\n const aCenterX = a.x + a.width / 2;\n const aCenterY = a.y + a.height / 2;\n const bCenterX = b.x + b.width / 2;\n const bCenterY = b.y + b.height / 2;\n\n const dx = bCenterX - aCenterX;\n const dy = bCenterY - aCenterY;\n\n const minDistX = (a.width + b.width) / 2 + gap;\n const minDistY = (a.height + b.height) / 2 + gap;\n\n const overlapX = minDistX - Math.abs(dx);\n const overlapY = minDistY - Math.abs(dy);\n\n return { x: overlapX, y: overlapY };\n}\n\n/**\n * Reorder nodes vertically based on which handle they connect to on the target.\n * This minimizes edge crossings by placing nodes that connect to top handles\n * above nodes that connect to bottom handles.\n */\nfunction reorderByHandlePosition(nodes: Node[], edges: Edge[]): Node[] {\n const nodeMap = new Map(nodes.map((n) => [n.id, n]));\n\n // Group edges by target node\n const edgesByTarget = new Map<string, Edge[]>();\n for (const edge of edges) {\n const existing = edgesByTarget.get(edge.target) ?? [];\n existing.push(edge);\n edgesByTarget.set(edge.target, existing);\n }\n\n // For each target, reorder its source nodes based on handle index\n for (const [targetId, targetEdges] of edgesByTarget) {\n if (targetEdges.length < 2) continue;\n\n const targetNode = nodeMap.get(targetId);\n if (!targetNode) continue;\n\n // Get source nodes with their target handle indices\n const sourceInfos: {\n nodeId: string;\n handleIndex: number;\n currentY: number;\n }[] = [];\n\n for (const edge of targetEdges) {\n const sourceNode = nodeMap.get(edge.source);\n if (!sourceNode) continue;\n\n const handleIndex = getInputHandleIndex(\n targetNode.type as string,\n edge.targetHandle ?? '',\n );\n sourceInfos.push({\n currentY: sourceNode.position.y,\n handleIndex,\n nodeId: edge.source,\n });\n }\n\n if (sourceInfos.length < 2) continue;\n\n // Sort by handle index (top handles first)\n sourceInfos.sort((a, b) => a.handleIndex - b.handleIndex);\n\n // Get the Y positions sorted (top positions first)\n const sortedYPositions = sourceInfos\n .map((s) => s.currentY)\n .sort((a, b) => a - b);\n\n // Assign Y positions: node connecting to top handle gets top Y position\n for (let i = 0; i < sourceInfos.length; i++) {\n const node = nodeMap.get(sourceInfos[i].nodeId);\n if (node) {\n node.position.y = sortedYPositions[i];\n }\n }\n }\n\n return nodes;\n}\n\n/**\n * Resolve all overlaps using iterative collision detection\n * Based on xyflow's recommended naive O(n^2) approach\n * https://xyflow.com/blog/node-collision-detection-algorithms\n */\nfunction resolveCollisions(nodes: Node[]): Node[] {\n const maxIterations = 100;\n let iteration = 0;\n let hasCollision = true;\n\n while (hasCollision && iteration < maxIterations) {\n hasCollision = false;\n iteration++;\n\n for (let i = 0; i < nodes.length; i++) {\n for (let j = i + 1; j < nodes.length; j++) {\n const nodeA = nodes[i];\n const nodeB = nodes[j];\n\n const rectA = getNodeRect(nodeA);\n const rectB = getNodeRect(nodeB);\n\n if (rectsOverlap(rectA, rectB, MIN_GAP)) {\n hasCollision = true;\n\n const overlap = getOverlap(rectA, rectB, MIN_GAP);\n\n const aCenterX = rectA.x + rectA.width / 2;\n const aCenterY = rectA.y + rectA.height / 2;\n const bCenterX = rectB.x + rectB.width / 2;\n const bCenterY = rectB.y + rectB.height / 2;\n\n if (overlap.x < overlap.y && overlap.x > 0) {\n const pushX = overlap.x / 2;\n if (bCenterX >= aCenterX) {\n nodeA.position.x -= pushX;\n nodeB.position.x += pushX;\n } else {\n nodeA.position.x += pushX;\n nodeB.position.x -= pushX;\n }\n } else if (overlap.y > 0) {\n const pushY = overlap.y / 2;\n if (bCenterY >= aCenterY) {\n nodeA.position.y -= pushY;\n nodeB.position.y += pushY;\n } else {\n nodeA.position.y += pushY;\n nodeB.position.y -= pushY;\n }\n }\n }\n }\n }\n }\n\n return nodes;\n}\n\n/**\n * Auto-layout nodes using dagre algorithm with collision resolution\n * @param nodes - React Flow nodes\n * @param edges - React Flow edges\n * @param options - Layout configuration\n * @returns Nodes with updated positions\n */\nexport function getLayoutedNodes(\n nodes: Node[],\n edges: Edge[],\n options: LayoutOptions = {},\n): Node[] {\n if (nodes.length === 0) return nodes;\n\n const { direction = 'LR', nodeSpacing = 50, rankSpacing = 120 } = options;\n\n const graph = new Dagre.graphlib.Graph().setDefaultEdgeLabel(() => ({}));\n\n graph.setGraph({\n acyclicer: 'greedy',\n marginx: 50,\n marginy: 50,\n nodesep: nodeSpacing,\n rankdir: direction,\n ranker: 'network-simplex',\n ranksep: rankSpacing,\n });\n\n // Add nodes with their actual measured dimensions\n for (const node of nodes) {\n const width = node.measured?.width ?? DEFAULT_NODE_WIDTH;\n const height = node.measured?.height ?? DEFAULT_NODE_HEIGHT;\n graph.setNode(node.id, { height, width });\n }\n\n // Add edges\n for (const edge of edges) {\n graph.setEdge(edge.source, edge.target);\n }\n\n Dagre.layout(graph);\n\n // Apply dagre positions (dagre returns center coordinates)\n const layoutedNodes = nodes.map((node) => {\n const nodeWithPosition = graph.node(node.id);\n const width = node.measured?.width ?? DEFAULT_NODE_WIDTH;\n const height = node.measured?.height ?? DEFAULT_NODE_HEIGHT;\n\n return {\n ...node,\n position: {\n x: nodeWithPosition.x - width / 2,\n y: nodeWithPosition.y - height / 2,\n },\n };\n });\n\n // Reorder nodes to minimize edge crossings based on handle positions\n reorderByHandlePosition(layoutedNodes, edges);\n\n // Resolve any remaining overlaps with collision detection\n return resolveCollisions(layoutedNodes);\n}\n","import type { NodeType } from '@genfeedai/types';\nimport { useReactFlow } from '@xyflow/react';\nimport { useCallback } from 'react';\nimport { getLayoutedNodes } from '../lib/autoLayout';\nimport { useSettingsStore } from '../stores/settingsStore';\nimport { selectAddNode } from '../stores/workflow/selectors';\nimport { useWorkflowStore } from '../stores/workflowStore';\n\nexport function usePaneActions() {\n const addNode = useWorkflowStore(selectAddNode);\n const reactFlow = useReactFlow();\n\n const addNodeAtPosition = useCallback(\n (type: string, screenX: number, screenY: number) => {\n const position = reactFlow.screenToFlowPosition({\n x: screenX,\n y: screenY,\n });\n addNode(type as NodeType, position);\n },\n [addNode, reactFlow],\n );\n\n const selectAll = useCallback(() => {\n reactFlow.setNodes((nds) =>\n nds.map((node) => ({\n ...node,\n selected: true,\n })),\n );\n }, [reactFlow]);\n\n const fitView = useCallback(() => {\n reactFlow.fitView({ padding: 0.2 });\n }, [reactFlow]);\n\n const autoLayout = useCallback(\n (direction: 'TB' | 'LR' = 'LR') => {\n const edgeStyle = useSettingsStore.getState().edgeStyle;\n // Use React Flow's internal nodes which have measured dimensions populated\n const currentNodes = reactFlow.getNodes();\n const currentEdges = reactFlow.getEdges();\n const layoutedNodes = getLayoutedNodes(currentNodes, currentEdges, {\n direction,\n });\n reactFlow.setNodes(layoutedNodes);\n\n // Normalize all edges to use consistent style\n reactFlow.setEdges((eds) =>\n eds.map((edge) => ({\n ...edge,\n type: edgeStyle,\n })),\n );\n\n // Fit view after layout with a small delay to allow DOM update\n setTimeout(() => {\n reactFlow.fitView({ padding: 0.2 });\n }, 50);\n },\n [reactFlow],\n );\n\n return {\n addNodeAtPosition,\n autoLayout,\n fitView,\n selectAll,\n };\n}\n","import { Trash2 } from 'lucide-react';\nimport type { ContextMenuItemConfig } from '../ContextMenu';\n\ninterface EdgeMenuOptions {\n edgeId: string;\n onDelete: (edgeId: string) => void;\n}\n\nexport function getEdgeMenuItems({\n edgeId,\n onDelete,\n}: EdgeMenuOptions): ContextMenuItemConfig[] {\n return [\n {\n danger: true,\n icon: <Trash2 className=\"w-4 h-4\" />,\n id: 'delete',\n label: 'Delete Connection',\n onClick: () => onDelete(edgeId),\n },\n ];\n}\n","'use client';\n\nexport function ContextMenuSeparator() {\n return <div className=\"h-px bg-[var(--border)] my-1\" />;\n}\n","'use client';\n\nimport { ChevronRight } from 'lucide-react';\nimport { type ReactNode, useCallback, useRef, useState } from 'react';\nimport type { ContextMenuItemConfig } from './ContextMenu';\nimport { ContextMenuSeparator } from './ContextMenuSeparator';\n\nexport interface ContextMenuItemProps {\n id: string;\n label?: string;\n icon?: ReactNode;\n shortcut?: string;\n disabled?: boolean;\n danger?: boolean;\n submenu?: ContextMenuItemConfig[];\n onClick: () => void;\n onClose?: () => void;\n isSelected?: boolean;\n}\n\nexport function ContextMenuItem({\n label,\n icon,\n shortcut,\n disabled,\n danger,\n submenu,\n onClick,\n onClose,\n isSelected,\n}: ContextMenuItemProps) {\n const [showSubmenu, setShowSubmenu] = useState(false);\n const itemRef = useRef<HTMLDivElement>(null);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const handleMouseEnter = useCallback(() => {\n if (submenu && !disabled) {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n setShowSubmenu(true);\n }\n }, [submenu, disabled]);\n\n const handleMouseLeave = useCallback(() => {\n if (submenu) {\n timeoutRef.current = setTimeout(() => {\n setShowSubmenu(false);\n }, 100);\n }\n }, [submenu]);\n\n const handleSubmenuClick = useCallback(\n (item: ContextMenuItemConfig) => {\n if (!item.disabled && item.onClick) {\n item.onClick();\n onClose?.();\n }\n },\n [onClose],\n );\n\n const hasSubmenu = submenu && submenu.length > 0;\n\n return (\n <div\n ref={itemRef}\n className=\"relative\"\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n <button\n onClick={hasSubmenu ? undefined : onClick}\n disabled={disabled}\n className={`\n w-full flex items-center gap-3 px-3 py-2 text-left text-sm rounded-md\n transition-colors outline-none\n ${isSelected || showSubmenu ? 'bg-[var(--secondary)]' : ''}\n ${disabled ? 'opacity-50 cursor-not-allowed' : 'hover:bg-[var(--secondary)] cursor-pointer'}\n ${danger && !disabled ? 'text-red-400 hover:text-red-300' : 'text-[var(--foreground)]'}\n `}\n >\n {icon && (\n <span\n className={`w-4 h-4 flex items-center justify-center ${danger ? 'text-red-400' : 'text-[var(--muted-foreground)]'}`}\n >\n {icon}\n </span>\n )}\n {label && <span className=\"flex-1\">{label}</span>}\n {shortcut && !hasSubmenu && (\n <span className=\"text-xs text-[var(--muted-foreground)] ml-4\">\n {shortcut}\n </span>\n )}\n {hasSubmenu && (\n <ChevronRight className=\"w-4 h-4 text-[var(--muted-foreground)]\" />\n )}\n </button>\n\n {/* Submenu */}\n {hasSubmenu && showSubmenu && (\n <div\n className=\"absolute left-full top-0 ml-1 min-w-[200px] py-1 bg-[var(--card)] border border-[var(--border)] rounded-lg shadow-lg backdrop-blur-sm z-50\"\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n {submenu.map((item) => {\n if (item.separator) {\n return <ContextMenuSeparator key={item.id} />;\n }\n\n return (\n <button\n key={item.id}\n onClick={() => handleSubmenuClick(item)}\n disabled={item.disabled}\n className={`\n w-full flex items-center gap-3 px-3 py-2 text-left text-sm rounded-md\n transition-colors outline-none\n ${item.disabled ? 'opacity-50 cursor-not-allowed' : 'hover:bg-[var(--secondary)] cursor-pointer'}\n ${item.danger && !item.disabled ? 'text-red-400 hover:text-red-300' : 'text-[var(--foreground)]'}\n `}\n >\n {item.icon && (\n <span\n className={`w-4 h-4 flex items-center justify-center ${item.danger ? 'text-red-400' : 'text-[var(--muted-foreground)]'}`}\n >\n {item.icon}\n </span>\n )}\n {item.label && <span className=\"flex-1\">{item.label}</span>}\n {item.shortcut && (\n <span className=\"text-xs text-[var(--muted-foreground)] ml-4\">\n {item.shortcut}\n </span>\n )}\n </button>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n","'use client';\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { ContextMenuItem } from './ContextMenuItem';\nimport { ContextMenuSeparator } from './ContextMenuSeparator';\n\nexport interface ContextMenuItemConfig {\n id: string;\n label?: string;\n icon?: React.ReactNode;\n shortcut?: string;\n disabled?: boolean;\n danger?: boolean;\n separator?: boolean;\n submenu?: ContextMenuItemConfig[];\n onClick?: () => void;\n}\n\n/** Helper to create a separator item */\nexport function createSeparator(id: string): ContextMenuItemConfig {\n return { id, separator: true };\n}\n\ninterface ContextMenuProps {\n x: number;\n y: number;\n items: ContextMenuItemConfig[];\n onClose: () => void;\n}\n\nexport function ContextMenu({ x, y, items, onClose }: ContextMenuProps) {\n const menuRef = useRef<HTMLDivElement>(null);\n const [selectedIndex, setSelectedIndex] = useState(-1);\n const [position, setPosition] = useState({ x, y });\n\n // Calculate position to keep menu on screen\n useEffect(() => {\n if (menuRef.current) {\n const rect = menuRef.current.getBoundingClientRect();\n const padding = 8;\n\n let newX = x;\n let newY = y;\n\n // Check right edge\n if (x + rect.width + padding > window.innerWidth) {\n newX = x - rect.width;\n }\n\n // Check bottom edge\n if (y + rect.height + padding > window.innerHeight) {\n newY = y - rect.height;\n }\n\n // Ensure not off left/top\n newX = Math.max(padding, newX);\n newY = Math.max(padding, newY);\n\n setPosition({ x: newX, y: newY });\n }\n }, [x, y]);\n\n // Close on click outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (menuRef.current && !menuRef.current.contains(event.target as Node)) {\n onClose();\n }\n };\n\n // Delay to avoid immediate close from the same click that opened the menu\n const timeoutId = setTimeout(() => {\n document.addEventListener('mousedown', handleClickOutside);\n }, 0);\n\n return () => {\n clearTimeout(timeoutId);\n document.removeEventListener('mousedown', handleClickOutside);\n };\n }, [onClose]);\n\n // Keyboard navigation\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n const selectableIndices = items\n .map((item, index) => (!item.separator && !item.disabled ? index : -1))\n .filter((index) => index !== -1);\n\n switch (event.key) {\n case 'Escape':\n event.preventDefault();\n onClose();\n break;\n case 'ArrowDown':\n event.preventDefault();\n if (selectableIndices.length > 0) {\n const currentSelectableIndex =\n selectableIndices.indexOf(selectedIndex);\n const nextIndex =\n currentSelectableIndex === -1\n ? 0\n : (currentSelectableIndex + 1) % selectableIndices.length;\n setSelectedIndex(selectableIndices[nextIndex]);\n }\n break;\n case 'ArrowUp':\n event.preventDefault();\n if (selectableIndices.length > 0) {\n const currentSelectableIndex =\n selectableIndices.indexOf(selectedIndex);\n const prevIndex =\n currentSelectableIndex === -1\n ? selectableIndices.length - 1\n : (currentSelectableIndex - 1 + selectableIndices.length) %\n selectableIndices.length;\n setSelectedIndex(selectableIndices[prevIndex]);\n }\n break;\n case 'Enter':\n event.preventDefault();\n if (selectedIndex >= 0 && selectedIndex < items.length) {\n const item = items[selectedIndex];\n if (!item.separator && !item.disabled && item.onClick) {\n item.onClick();\n onClose();\n }\n }\n break;\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [items, selectedIndex, onClose]);\n\n const handleItemClick = useCallback(\n (item: ContextMenuItemConfig) => {\n if (!item.disabled && item.onClick) {\n item.onClick();\n onClose();\n }\n },\n [onClose],\n );\n\n return (\n <div\n ref={menuRef}\n className=\"fixed z-50 min-w-[200px] py-1 bg-[var(--card)] border border-[var(--border)] rounded-lg shadow-lg backdrop-blur-sm\"\n style={{ left: position.x, top: position.y }}\n >\n {items.map((item, index) => {\n if (item.separator) {\n return <ContextMenuSeparator key={item.id} />;\n }\n\n return (\n <ContextMenuItem\n key={item.id}\n id={item.id}\n label={item.label}\n icon={item.icon}\n shortcut={item.shortcut}\n disabled={item.disabled}\n danger={item.danger}\n submenu={item.submenu}\n onClick={() => handleItemClick(item)}\n onClose={onClose}\n isSelected={index === selectedIndex}\n />\n );\n })}\n </div>\n );\n}\n","import {\n Copy,\n Image,\n Lock,\n LockOpen,\n Palette,\n Scissors,\n Trash2,\n} from 'lucide-react';\nimport { type ContextMenuItemConfig, createSeparator } from '../ContextMenu';\n\ntype NodeColor =\n | 'none'\n | 'purple'\n | 'blue'\n | 'green'\n | 'yellow'\n | 'orange'\n | 'red'\n | 'pink'\n | 'gray';\n\nconst NODE_COLOR_VALUES: Record<NodeColor, string | null> = {\n blue: '#3b82f6',\n gray: '#6b7280',\n green: '#22c55e',\n none: null,\n orange: '#f97316',\n pink: '#ec4899',\n purple: '#a855f7',\n red: '#ef4444',\n yellow: '#eab308',\n};\n\nconst NODE_COLOR_LABELS: Record<NodeColor, string> = {\n blue: 'Blue',\n gray: 'Gray',\n green: 'Green',\n none: 'Default',\n orange: 'Orange',\n pink: 'Pink',\n purple: 'Purple',\n red: 'Red',\n yellow: 'Yellow',\n};\n\nconst NODE_COLORS: NodeColor[] = [\n 'none',\n 'purple',\n 'blue',\n 'green',\n 'yellow',\n 'orange',\n 'red',\n 'pink',\n 'gray',\n];\n\ninterface NodeMenuOptions {\n nodeId: string;\n isLocked: boolean;\n hasMediaOutput: boolean;\n currentColor?: string;\n onDuplicate: (nodeId: string) => void;\n onLock: (nodeId: string) => void;\n onUnlock: (nodeId: string) => void;\n onCut: (nodeId: string) => void;\n onCopy: (nodeId: string) => void;\n onDelete: (nodeId: string) => void;\n onSetAsThumbnail?: (nodeId: string) => void;\n onSetColor?: (nodeId: string, color: string | null) => void;\n}\n\nexport function getNodeMenuItems({\n nodeId,\n isLocked,\n hasMediaOutput,\n currentColor,\n onDuplicate,\n onLock,\n onUnlock,\n onCut,\n onCopy,\n onDelete,\n onSetAsThumbnail,\n onSetColor,\n}: NodeMenuOptions): ContextMenuItemConfig[] {\n const items: ContextMenuItemConfig[] = [\n {\n icon: <Copy className=\"w-4 h-4\" />,\n id: 'duplicate',\n label: 'Duplicate',\n onClick: () => onDuplicate(nodeId),\n shortcut: '⌘D',\n },\n ];\n\n // Add \"Set as Thumbnail\" option for nodes with media output\n if (hasMediaOutput && onSetAsThumbnail) {\n items.push({\n icon: <Image className=\"w-4 h-4\" />,\n id: 'setThumbnail',\n label: 'Set as Thumbnail',\n onClick: () => onSetAsThumbnail(nodeId),\n });\n }\n\n // Add color picker submenu\n if (onSetColor) {\n const colorSubmenu: ContextMenuItemConfig[] = NODE_COLORS.map((color) => {\n const colorValue = NODE_COLOR_VALUES[color];\n const isSelected =\n colorValue === currentColor || (color === 'none' && !currentColor);\n return {\n icon: (\n <div\n className=\"w-4 h-4 rounded-sm border border-border\"\n style={{ backgroundColor: colorValue || 'transparent' }}\n />\n ),\n id: `color-${color}`,\n label: `${isSelected ? '✓ ' : ''}${NODE_COLOR_LABELS[color]}`,\n onClick: () => onSetColor(nodeId, colorValue),\n };\n });\n\n items.push({\n icon: <Palette className=\"w-4 h-4\" />,\n id: 'setColor',\n label: 'Set Color',\n submenu: colorSubmenu,\n });\n }\n\n items.push(createSeparator('separator-1'));\n\n items.push(\n isLocked\n ? {\n icon: <LockOpen className=\"w-4 h-4\" />,\n id: 'unlock',\n label: 'Unlock Node',\n onClick: () => onUnlock(nodeId),\n shortcut: 'L',\n }\n : {\n icon: <Lock className=\"w-4 h-4\" />,\n id: 'lock',\n label: 'Lock Node',\n onClick: () => onLock(nodeId),\n shortcut: 'L',\n },\n );\n\n items.push(createSeparator('separator-2'));\n\n items.push(\n {\n icon: <Scissors className=\"w-4 h-4\" />,\n id: 'cut',\n label: 'Cut',\n onClick: () => onCut(nodeId),\n shortcut: '⌘X',\n },\n {\n icon: <Copy className=\"w-4 h-4\" />,\n id: 'copy',\n label: 'Copy',\n onClick: () => onCopy(nodeId),\n shortcut: '⌘C',\n },\n );\n\n items.push(createSeparator('separator-3'));\n\n items.push({\n danger: true,\n icon: <Trash2 className=\"w-4 h-4\" />,\n id: 'delete',\n label: 'Delete',\n onClick: () => onDelete(nodeId),\n shortcut: '⌫',\n });\n\n return items;\n}\n","import { getNodesByCategory, type NodeCategory } from '@genfeedai/types';\nimport {\n ArrowLeftFromLine,\n ArrowRightToLine,\n AudioLines,\n Brain,\n CheckCircle,\n Clipboard,\n Crop,\n FileText,\n FileVideo,\n Film,\n GitBranch,\n Grid3X3,\n Image,\n Layers,\n LayoutGrid,\n type LucideIcon,\n Maximize,\n Maximize2,\n MessageSquare,\n Mic,\n Monitor,\n Navigation,\n Pencil,\n Scissors,\n Sparkles,\n Subtitles,\n Video,\n Volume2,\n Wand2,\n} from 'lucide-react';\nimport { type ContextMenuItemConfig, createSeparator } from '../ContextMenu';\n\n// Icon mapping from node definition icon strings to Lucide components\nconst NODE_ICONS: Record<string, LucideIcon> = {\n ArrowLeftFromLine,\n ArrowRightToLine,\n AudioLines,\n Brain,\n CheckCircle,\n Crop,\n FileText,\n FileVideo,\n Film,\n GitBranch,\n Grid3X3,\n Image,\n Layers,\n Maximize,\n Maximize2,\n MessageSquare,\n Mic,\n Navigation,\n Pencil,\n Scissors,\n Sparkles,\n Subtitles,\n Video,\n Volume2,\n Wand2,\n};\n\nconst CATEGORY_LABELS: Record<NodeCategory, string> = {\n ai: 'AI Generation',\n composition: 'Composition',\n input: 'Input',\n output: 'Output',\n processing: 'Processing',\n};\n\nconst CATEGORY_ICONS: Record<NodeCategory, LucideIcon> = {\n ai: Sparkles,\n composition: GitBranch,\n input: Image,\n output: Monitor,\n processing: Wand2,\n};\n\ninterface PaneMenuOptions {\n screenX: number;\n screenY: number;\n hasClipboard: boolean;\n onAddNode: (type: string, screenX: number, screenY: number) => void;\n onPaste: () => void;\n onSelectAll: () => void;\n onFitView: () => void;\n onAutoLayout: () => void;\n}\n\nexport function getPaneMenuItems({\n screenX,\n screenY,\n hasClipboard,\n onAddNode,\n onPaste,\n onSelectAll,\n onFitView,\n onAutoLayout,\n}: PaneMenuOptions): ContextMenuItemConfig[] {\n const nodesByCategory = getNodesByCategory();\n // Filter out categories with no nodes (e.g., deprecated 'output' category)\n const categories = (\n ['input', 'ai', 'processing', 'output', 'composition'] as NodeCategory[]\n ).filter((cat) => nodesByCategory[cat].length > 0);\n\n // Generate category submenus with all nodes\n const addNodeItems: ContextMenuItemConfig[] = categories.map((category) => {\n const CategoryIcon = CATEGORY_ICONS[category];\n const nodes = nodesByCategory[category];\n\n return {\n icon: <CategoryIcon className=\"w-4 h-4\" />,\n id: `add-${category}`,\n label: CATEGORY_LABELS[category],\n submenu: nodes.map((node) => {\n const NodeIcon = NODE_ICONS[node.icon] ?? Sparkles;\n return {\n icon: <NodeIcon className=\"w-4 h-4\" />,\n id: `add-${node.type}`,\n label: node.label,\n onClick: () => onAddNode(node.type, screenX, screenY),\n };\n }),\n };\n });\n\n return [\n ...addNodeItems,\n createSeparator('separator-1'),\n {\n disabled: !hasClipboard,\n icon: <Clipboard className=\"w-4 h-4\" />,\n id: 'paste',\n label: 'Paste',\n onClick: onPaste,\n shortcut: '⌘V',\n },\n createSeparator('separator-2'),\n {\n id: 'select-all',\n label: 'Select All',\n onClick: onSelectAll,\n shortcut: '⌘A',\n },\n {\n icon: <Maximize className=\"w-4 h-4\" />,\n id: 'fit-view',\n label: 'Fit View',\n onClick: onFitView,\n shortcut: 'F',\n },\n {\n icon: <LayoutGrid className=\"w-4 h-4\" />,\n id: 'auto-layout',\n label: 'Auto-layout Nodes',\n onClick: onAutoLayout,\n shortcut: 'L',\n },\n ];\n}\n","import {\n AlignHorizontalJustifyCenter,\n AlignVerticalJustifyCenter,\n Copy,\n Group,\n Lock,\n LockOpen,\n Trash2,\n} from 'lucide-react';\nimport { type ContextMenuItemConfig, createSeparator } from '../ContextMenu';\n\ninterface SelectionMenuOptions {\n nodeIds: string[];\n onGroup: (nodeIds: string[]) => void;\n onDuplicateAll: (nodeIds: string[]) => void;\n onLockAll: (nodeIds: string[]) => void;\n onUnlockAll: (nodeIds: string[]) => void;\n onAlignHorizontal: (nodeIds: string[]) => void;\n onAlignVertical: (nodeIds: string[]) => void;\n onDeleteAll: (nodeIds: string[]) => void;\n}\n\nexport function getSelectionMenuItems({\n nodeIds,\n onGroup,\n onDuplicateAll,\n onLockAll,\n onUnlockAll,\n onAlignHorizontal,\n onAlignVertical,\n onDeleteAll,\n}: SelectionMenuOptions): ContextMenuItemConfig[] {\n const count = nodeIds.length;\n\n return [\n {\n icon: <Group className=\"w-4 h-4\" />,\n id: 'group',\n label: 'Create Group',\n onClick: () => onGroup(nodeIds),\n shortcut: '⌘G',\n },\n {\n icon: <Copy className=\"w-4 h-4\" />,\n id: 'duplicate-all',\n label: `Duplicate ${count} Nodes`,\n onClick: () => onDuplicateAll(nodeIds),\n shortcut: '⌘D',\n },\n createSeparator('separator-1'),\n {\n icon: <Lock className=\"w-4 h-4\" />,\n id: 'lock-all',\n label: 'Lock All',\n onClick: () => onLockAll(nodeIds),\n shortcut: 'L',\n },\n {\n icon: <LockOpen className=\"w-4 h-4\" />,\n id: 'unlock-all',\n label: 'Unlock All',\n onClick: () => onUnlockAll(nodeIds),\n },\n createSeparator('separator-2'),\n {\n icon: <AlignHorizontalJustifyCenter className=\"w-4 h-4\" />,\n id: 'align-horizontal',\n label: 'Align Horizontally',\n onClick: () => onAlignHorizontal(nodeIds),\n },\n {\n icon: <AlignVerticalJustifyCenter className=\"w-4 h-4\" />,\n id: 'align-vertical',\n label: 'Align Vertically',\n onClick: () => onAlignVertical(nodeIds),\n },\n createSeparator('separator-3'),\n {\n danger: true,\n icon: <Trash2 className=\"w-4 h-4\" />,\n id: 'delete-all',\n label: `Delete ${count} Nodes`,\n onClick: () => onDeleteAll(nodeIds),\n shortcut: '⌫',\n },\n ];\n}\n","import type { WorkflowNodeData } from '@genfeedai/types';\nimport { useReactFlow } from '@xyflow/react';\nimport { useCallback, useMemo, useRef } from 'react';\nimport type { ContextMenuItemConfig } from '../components/context-menu';\nimport {\n getEdgeMenuItems,\n getNodeMenuItems,\n getPaneMenuItems,\n getSelectionMenuItems,\n} from '../components/context-menu/menus';\nimport { useWorkflowUIConfig } from '../provider/WorkflowUIProvider';\nimport { useContextMenuStore } from '../stores/contextMenuStore';\nimport {\n selectCreateGroup,\n selectNodes,\n selectSetSelectedNodeIds,\n selectToggleNodeLock,\n selectUpdateNodeData,\n selectWorkflowId,\n} from '../stores/workflow/selectors';\nimport { useWorkflowStore } from '../stores/workflowStore';\nimport { useNodeActions } from './useNodeActions';\nimport { usePaneActions } from './usePaneActions';\n\nexport function useContextMenu() {\n const {\n isOpen,\n position,\n menuType,\n targetId,\n targetIds,\n openNodeMenu,\n openEdgeMenu,\n openPaneMenu,\n openSelectionMenu,\n close,\n } = useContextMenuStore();\n\n const { workflowsApi } = useWorkflowUIConfig();\n\n const nodes = useWorkflowStore(selectNodes);\n const removeEdge = useWorkflowStore((state) => state.removeEdge);\n const toggleNodeLock = useWorkflowStore(selectToggleNodeLock);\n const createGroup = useWorkflowStore(selectCreateGroup);\n const workflowId = useWorkflowStore(selectWorkflowId);\n const addNodesAndEdges = useWorkflowStore((state) => state.addNodesAndEdges);\n const setSelectedNodeIds = useWorkflowStore(selectSetSelectedNodeIds);\n const updateNodeData = useWorkflowStore(selectUpdateNodeData);\n const {\n clipboard,\n deleteNode,\n duplicate,\n copyNode,\n cutNode,\n deleteMultipleNodes,\n duplicateMultipleNodes,\n getPasteData,\n } = useNodeActions();\n const { addNodeAtPosition, selectAll, fitView, autoLayout } =\n usePaneActions();\n const reactFlow = useReactFlow();\n\n // Stable reference for handlers that don't need to change\n const stableHandlersRef = useRef({\n addNodeAtPosition,\n autoLayout,\n copyNode,\n cutNode,\n deleteMultipleNodes,\n deleteNode,\n duplicate,\n duplicateMultipleNodes,\n fitView,\n removeEdge,\n selectAll,\n });\n\n // Update ref on each render (avoids stale closures while maintaining stable reference)\n stableHandlersRef.current = {\n addNodeAtPosition,\n autoLayout,\n copyNode,\n cutNode,\n deleteMultipleNodes,\n deleteNode,\n duplicate,\n duplicateMultipleNodes,\n fitView,\n removeEdge,\n selectAll,\n };\n\n const lockNode = useCallback(\n (nodeId: string) => {\n const node = nodes.find((n) => n.id === nodeId);\n if (node && !node.data.locked) {\n toggleNodeLock(nodeId);\n }\n },\n [nodes, toggleNodeLock],\n );\n\n const unlockNode = useCallback(\n (nodeId: string) => {\n const node = nodes.find((n) => n.id === nodeId);\n if (node?.data.locked) {\n toggleNodeLock(nodeId);\n }\n },\n [nodes, toggleNodeLock],\n );\n\n const groupNodes = useCallback(\n (nodeIds: string[]) => {\n if (nodeIds.length > 1) {\n createGroup(nodeIds);\n }\n },\n [createGroup],\n );\n\n const lockAllNodes = useCallback(\n (nodeIds: string[]) => {\n for (const nodeId of nodeIds) {\n const node = nodes.find((n) => n.id === nodeId);\n if (node && !node.data.locked) {\n toggleNodeLock(nodeId);\n }\n }\n },\n [nodes, toggleNodeLock],\n );\n\n const unlockAllNodes = useCallback(\n (nodeIds: string[]) => {\n for (const nodeId of nodeIds) {\n const node = nodes.find((n) => n.id === nodeId);\n if (node?.data.locked) {\n toggleNodeLock(nodeId);\n }\n }\n },\n [nodes, toggleNodeLock],\n );\n\n const alignNodesHorizontally = useCallback(\n (nodeIds: string[]) => {\n if (nodeIds.length < 2) return;\n\n const selectedNodes = nodes.filter((n) => nodeIds.includes(n.id));\n if (selectedNodes.length < 2) return;\n\n // Calculate average Y position\n const avgY =\n selectedNodes.reduce((sum, n) => sum + n.position.y, 0) /\n selectedNodes.length;\n\n // Update all selected nodes to the same Y position\n reactFlow.setNodes((nds) =>\n nds.map((node) =>\n nodeIds.includes(node.id)\n ? { ...node, position: { ...node.position, y: avgY } }\n : node,\n ),\n );\n },\n [nodes, reactFlow],\n );\n\n const alignNodesVertically = useCallback(\n (nodeIds: string[]) => {\n if (nodeIds.length < 2) return;\n\n const selectedNodes = nodes.filter((n) => nodeIds.includes(n.id));\n if (selectedNodes.length < 2) return;\n\n // Calculate average X position\n const avgX =\n selectedNodes.reduce((sum, n) => sum + n.position.x, 0) /\n selectedNodes.length;\n\n // Update all selected nodes to the same X position\n reactFlow.setNodes((nds) =>\n nds.map((node) =>\n nodeIds.includes(node.id)\n ? { ...node, position: { ...node.position, x: avgX } }\n : node,\n ),\n );\n },\n [nodes, reactFlow],\n );\n\n const pasteNodes = useCallback(() => {\n if (!clipboard) return;\n\n // Convert the context menu position to flow coordinates\n const flowPosition = reactFlow.screenToFlowPosition({\n x: position.x,\n y: position.y,\n });\n\n const pasteData = getPasteData(flowPosition.x, flowPosition.y);\n if (!pasteData) return;\n\n // Add nodes and edges to the store\n addNodesAndEdges(pasteData.nodes, pasteData.edges);\n\n // Select the pasted nodes\n setSelectedNodeIds(pasteData.nodes.map((n) => n.id));\n }, [\n clipboard,\n position,\n reactFlow,\n getPasteData,\n addNodesAndEdges,\n setSelectedNodeIds,\n ]);\n\n const setNodeColor = useCallback(\n (nodeId: string, color: string | null) => {\n updateNodeData(nodeId, { color: color || undefined });\n },\n [updateNodeData],\n );\n\n const setAsThumbnail = useCallback(\n async (nodeId: string) => {\n if (!workflowId || !workflowsApi) return;\n\n const node = nodes.find((n) => n.id === nodeId);\n if (!node) return;\n\n const data = node.data as WorkflowNodeData & {\n outputVideo?: string;\n outputImage?: string;\n };\n\n const thumbnailUrl = data.outputVideo || data.outputImage;\n if (!thumbnailUrl) return;\n\n try {\n await workflowsApi.setThumbnail(workflowId, thumbnailUrl, nodeId);\n } catch {\n // Silently fail — consuming app can handle errors via its own API layer\n }\n },\n [workflowId, workflowsApi, nodes],\n );\n\n const hasMediaOutput = useCallback(\n (nodeId: string): boolean => {\n const node = nodes.find((n) => n.id === nodeId);\n if (!node) return false;\n\n const data = node.data as WorkflowNodeData & {\n outputVideo?: string;\n outputImage?: string;\n };\n\n return Boolean(data.outputVideo || data.outputImage);\n },\n [nodes],\n );\n\n const getMenuItems = useCallback((): ContextMenuItemConfig[] => {\n if (!menuType) return [];\n\n const handlers = stableHandlersRef.current;\n\n switch (menuType) {\n case 'node': {\n if (!targetId) return [];\n const node = nodes.find((n) => n.id === targetId);\n const isLocked = Boolean(node?.data.locked);\n const nodeHasMediaOutput = hasMediaOutput(targetId);\n const currentColor = (node?.data as { color?: string })?.color;\n return getNodeMenuItems({\n currentColor,\n hasMediaOutput: nodeHasMediaOutput,\n isLocked,\n nodeId: targetId,\n onCopy: handlers.copyNode,\n onCut: handlers.cutNode,\n onDelete: handlers.deleteNode,\n onDuplicate: handlers.duplicate,\n onLock: lockNode,\n onSetAsThumbnail:\n workflowId && workflowsApi ? setAsThumbnail : undefined,\n onSetColor: setNodeColor,\n onUnlock: unlockNode,\n });\n }\n\n case 'edge':\n if (!targetId) return [];\n return getEdgeMenuItems({\n edgeId: targetId,\n onDelete: handlers.removeEdge,\n });\n\n case 'pane':\n return getPaneMenuItems({\n hasClipboard: !!clipboard,\n onAddNode: handlers.addNodeAtPosition,\n onAutoLayout: () => handlers.autoLayout('LR'),\n onFitView: handlers.fitView,\n onPaste: pasteNodes,\n onSelectAll: handlers.selectAll,\n screenX: position.x,\n screenY: position.y,\n });\n\n case 'selection':\n if (!targetIds || targetIds.length === 0) return [];\n return getSelectionMenuItems({\n nodeIds: targetIds,\n onAlignHorizontal: alignNodesHorizontally,\n onAlignVertical: alignNodesVertically,\n onDeleteAll: handlers.deleteMultipleNodes,\n onDuplicateAll: handlers.duplicateMultipleNodes,\n onGroup: groupNodes,\n onLockAll: lockAllNodes,\n onUnlockAll: unlockAllNodes,\n });\n\n default:\n return [];\n }\n }, [\n menuType,\n targetId,\n targetIds,\n nodes,\n position,\n clipboard,\n lockNode,\n unlockNode,\n pasteNodes,\n groupNodes,\n lockAllNodes,\n unlockAllNodes,\n alignNodesHorizontally,\n alignNodesVertically,\n hasMediaOutput,\n setAsThumbnail,\n setNodeColor,\n workflowId,\n workflowsApi,\n ]);\n\n const menuItems = useMemo(() => getMenuItems(), [getMenuItems]);\n\n return {\n close,\n isOpen,\n menuItems,\n menuType,\n openEdgeMenu,\n openNodeMenu,\n openPaneMenu,\n openSelectionMenu,\n position,\n };\n}\n"]}
@@ -15,7 +15,7 @@ function supportsImageInput(schema) {
15
15
  if (!schema) return true;
16
16
  const properties = schema.properties;
17
17
  if (!properties) return true;
18
- return !!(properties.image || properties.image_input || properties.start_image || properties.first_frame_image || properties.reference_images);
18
+ return !!(properties.image || properties.image_input || properties.image_url || properties.image_urls || properties.start_image || properties.first_frame_image || properties.reference_images);
19
19
  }
20
20
  function extractEnumValues(componentSchemas) {
21
21
  if (!componentSchemas) return void 0;
@@ -57,13 +57,14 @@ var CONNECTION_FIELDS = /* @__PURE__ */ new Set([
57
57
  "prompt",
58
58
  "image",
59
59
  "image_input",
60
+ "image_url",
61
+ "image_urls",
60
62
  "video",
61
63
  "audio",
62
64
  "start_image",
63
65
  "first_frame_image",
64
66
  "last_frame",
65
67
  "reference_images",
66
- "image_url",
67
68
  "video_url",
68
69
  "end_image",
69
70
  "start_video_id",
@@ -97,3 +98,5 @@ function getVideoMetadata(src) {
97
98
  }
98
99
 
99
100
  export { CONNECTION_FIELDS, extractEnumValues, getImageDimensions, getSchemaDefaults, getVideoMetadata, supportsImageInput, validateRequiredSchemaFields };
101
+ //# sourceMappingURL=chunk-X3XNTD4R.mjs.map
102
+ //# sourceMappingURL=chunk-X3XNTD4R.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/schemaUtils.ts","../src/lib/schemaValidation.ts","../src/lib/media.ts"],"names":[],"mappings":"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","file":"chunk-X3XNTD4R.mjs","sourcesContent":["/**\n * Shared utilities for working with provider model schemas\n */\n\ntype SchemaProperty = {\n default?: unknown;\n enum?: unknown[];\n type?: string;\n $ref?: string;\n};\n\ntype SchemaProperties = Record<string, SchemaProperty>;\n\ninterface Schema {\n properties?: SchemaProperties;\n}\n\n/**\n * Extract default values from schema properties\n */\nexport function getSchemaDefaults(\n schema: Record<string, unknown> | undefined,\n): Record<string, unknown> {\n if (!schema) return {};\n\n const properties = (schema as Schema).properties;\n if (!properties) return {};\n\n const defaults: Record<string, unknown> = {};\n for (const [key, prop] of Object.entries(properties)) {\n if (prop.default !== undefined) {\n defaults[key] = prop.default;\n }\n }\n return defaults;\n}\n\n/**\n * Check if the model's schema supports image input\n * Used to determine whether to enable/disable image input handles\n */\nexport function supportsImageInput(\n schema: Record<string, unknown> | undefined,\n): boolean {\n if (!schema) return true; // Default to true if no schema\n\n const properties = (schema as Schema).properties;\n if (!properties) return true;\n\n // Check for common image input field names across providers\n return !!(\n properties.image ||\n properties.image_input ||\n properties.image_url ||\n properties.image_urls ||\n properties.start_image ||\n properties.first_frame_image ||\n properties.reference_images\n );\n}\n\n/**\n * Extract enum values from component schemas for SchemaInputs dropdowns\n */\nexport function extractEnumValues(\n componentSchemas:\n | Record<string, { enum?: unknown[]; type?: string }>\n | undefined,\n): Record<string, string[]> | undefined {\n if (!componentSchemas) return undefined;\n\n const result: Record<string, string[]> = {};\n for (const [key, schema] of Object.entries(componentSchemas)) {\n if (schema.enum && Array.isArray(schema.enum)) {\n // Convert all enum values to strings for the dropdown\n result[key] = schema.enum.map((v) => String(v));\n }\n }\n return Object.keys(result).length > 0 ? result : undefined;\n}\n","/**\n * Utility functions for validating required schema fields\n */\n\n/**\n * JSON Schema with required array\n */\ninterface JsonSchema {\n required?: string[];\n properties?: Record<string, unknown>;\n}\n\n/**\n * Validates that all required fields in a JSON Schema have values.\n *\n * @param inputSchema - The JSON Schema with required array\n * @param values - Current field values\n * @param skipFields - Fields to skip (e.g., fields populated via connections)\n * @returns Validation result with isValid flag and list of missing fields\n */\nexport function validateRequiredSchemaFields(\n inputSchema: Record<string, unknown> | undefined,\n values: Record<string, unknown>,\n skipFields: Set<string>,\n): { isValid: boolean; missingFields: string[] } {\n if (!inputSchema) {\n return { isValid: true, missingFields: [] };\n }\n\n const schema = inputSchema as JsonSchema;\n const requiredFields = schema.required ?? [];\n\n if (requiredFields.length === 0) {\n return { isValid: true, missingFields: [] };\n }\n\n const missingFields: string[] = [];\n\n for (const field of requiredFields) {\n // Skip fields that come from connections\n if (skipFields.has(field)) {\n continue;\n }\n\n const value = values[field];\n\n // Check if value is missing or empty\n if (value === undefined || value === null || value === '') {\n missingFields.push(field);\n }\n }\n\n return {\n isValid: missingFields.length === 0,\n missingFields,\n };\n}\n\n/**\n * Fields that are populated via node connections rather than schema inputs.\n * These should be skipped when validating schema required fields.\n */\nexport const CONNECTION_FIELDS = new Set([\n 'prompt',\n 'image',\n 'image_input',\n 'image_url',\n 'image_urls',\n 'video',\n 'audio',\n 'start_image',\n 'first_frame_image',\n 'last_frame',\n 'reference_images',\n 'video_url',\n 'end_image',\n 'start_video_id',\n 'end_video_id',\n 'subject_reference',\n 'image_prompt',\n 'mask',\n]);\n","/**\n * Get the dimensions of an image from its source URL or data URL.\n */\nexport function getImageDimensions(\n src: string,\n): Promise<{ width: number; height: number }> {\n return new Promise((resolve) => {\n const img = new window.Image();\n img.crossOrigin = 'anonymous';\n img.onload = () => resolve({ height: img.height, width: img.width });\n img.onerror = () => resolve({ height: 0, width: 0 });\n img.src = src;\n });\n}\n\n/**\n * Get duration and dimensions of a video from its source URL or data URL.\n */\nexport function getVideoMetadata(src: string): Promise<{\n duration: number;\n dimensions: { width: number; height: number };\n}> {\n return new Promise((resolve) => {\n const video = document.createElement('video');\n video.crossOrigin = 'anonymous';\n video.onloadedmetadata = () =>\n resolve({\n dimensions: { height: video.videoHeight, width: video.videoWidth },\n duration: video.duration,\n });\n video.onerror = () =>\n resolve({ dimensions: { height: 0, width: 0 }, duration: 0 });\n video.src = src;\n });\n}\n"]}
@@ -0,0 +1,3 @@
1
+
2
+ //# sourceMappingURL=chunk-YYFM6P4C.mjs.map
3
+ //# sourceMappingURL=chunk-YYFM6P4C.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-YYFM6P4C.mjs"}
package/dist/hooks.mjs CHANGED
@@ -1,11 +1,13 @@
1
- export { useCommentNavigation } from './chunk-ESVULCFY.mjs';
2
- export { useCanvasKeyboardShortcuts, useContextMenu, useNodeActions, usePaneActions } from './chunk-ORVDYXDP.mjs';
3
- export { useAIGenNode, useAIGenNodeHeader, useAutoLoadModelSchema, useCanGenerate, useMediaUpload, useModelSelection, useNodeExecution, usePromptAutocomplete, useRequiredInputs } from './chunk-FWJIAW2E.mjs';
4
- import './chunk-B4EAAKYF.mjs';
5
- import './chunk-VVQ4CH77.mjs';
6
- import './chunk-YUIK4AHM.mjs';
7
- import './chunk-7LV4UAUS.mjs';
8
- import './chunk-LDN7IX4Y.mjs';
9
- import './chunk-OJWVEEMM.mjs';
10
- import './chunk-GPYIIWD5.mjs';
11
- import './chunk-XRC3O5GK.mjs';
1
+ export { useCommentNavigation } from './chunk-TOFB4BTA.mjs';
2
+ export { useCanvasKeyboardShortcuts, useContextMenu, useNodeActions, usePaneActions } from './chunk-VKXTPLM7.mjs';
3
+ export { useAIGenNode, useAIGenNodeHeader, useAutoLoadModelSchema, useCanGenerate, useMediaUpload, useModelSelection, useNodeExecution, usePromptAutocomplete, useRequiredInputs } from './chunk-SHU7JPQY.mjs';
4
+ import './chunk-SBB2YW3Y.mjs';
5
+ import './chunk-X3XNTD4R.mjs';
6
+ import './chunk-JSF4FHBH.mjs';
7
+ import './chunk-IKR6GVZ4.mjs';
8
+ import './chunk-YYFM6P4C.mjs';
9
+ import './chunk-R5L7WB7F.mjs';
10
+ import './chunk-7DJHFOIW.mjs';
11
+ import './chunk-4JOFNZW6.mjs';
12
+ //# sourceMappingURL=hooks.mjs.map
13
+ //# sourceMappingURL=hooks.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"hooks.mjs"}
package/dist/index.mjs CHANGED
@@ -1,28 +1,28 @@
1
- import { BottomBar } from './chunk-ZSITTZ4S.mjs';
2
- export { BottomBar, CostIndicator, OverflowMenu, SaveAsDialog, SaveIndicator, Toolbar, ToolbarDropdown } from './chunk-ZSITTZ4S.mjs';
3
- import { WorkflowCanvas } from './chunk-53XDE62A.mjs';
4
- export { ConnectionDropMenu, DEFAULT_GROUP_COLORS, EdgeToolbar, EditableEdge, GROUP_COLORS, GlobalImageHistory, GroupOverlay, HelperLines, NodeSearch, NotificationToast, PauseEdge, ReferenceEdge, ShortcutHelpModal, WorkflowCanvas } from './chunk-53XDE62A.mjs';
5
- export { useCommentNavigation } from './chunk-ESVULCFY.mjs';
6
- export { useCanvasKeyboardShortcuts } from './chunk-ORVDYXDP.mjs';
7
- import './chunk-MGLAKMDP.mjs';
8
- export { BaseNode, nodeTypes } from './chunk-2FUPL67V.mjs';
9
- import './chunk-C6MQBJFC.mjs';
10
- export { useAIGenNode, useAIGenNodeHeader, useAutoLoadModelSchema, useCanGenerate, useMediaUpload, useModelSelection, useNodeExecution, usePromptAutocomplete, useRequiredInputs } from './chunk-FWJIAW2E.mjs';
11
- import './chunk-B4EAAKYF.mjs';
12
- import './chunk-U4QPE4CY.mjs';
13
- import './chunk-VVQ4CH77.mjs';
14
- import { NodePalette } from './chunk-IYFWAJBB.mjs';
15
- export { DebugPanel, NodePalette, PanelContainer } from './chunk-IYFWAJBB.mjs';
16
- import './chunk-MLJJBBTB.mjs';
17
- export { WorkflowUIProvider, useWorkflowUIConfig } from './chunk-YUIK4AHM.mjs';
18
- import './chunk-7LV4UAUS.mjs';
19
- export { useAnnotationStore, usePromptEditorStore } from './chunk-QQVHGJ2G.mjs';
20
- import './chunk-LDN7IX4Y.mjs';
21
- import { useUIStore } from './chunk-OJWVEEMM.mjs';
22
- export { useExecutionStore, useSettingsStore, useUIStore } from './chunk-OJWVEEMM.mjs';
23
- import { useWorkflowStore } from './chunk-GPYIIWD5.mjs';
24
- export { useWorkflowStore } from './chunk-GPYIIWD5.mjs';
25
- export { configurePromptLibrary, usePromptLibraryStore } from './chunk-XRC3O5GK.mjs';
1
+ import { BottomBar } from './chunk-3GWH2ZOH.mjs';
2
+ export { BottomBar, CostIndicator, OverflowMenu, SaveAsDialog, SaveIndicator, Toolbar, ToolbarDropdown } from './chunk-3GWH2ZOH.mjs';
3
+ import { WorkflowCanvas } from './chunk-RY6OZJ7A.mjs';
4
+ export { ConnectionDropMenu, DEFAULT_GROUP_COLORS, EdgeToolbar, EditableEdge, GROUP_COLORS, GlobalImageHistory, GroupOverlay, HelperLines, NodeSearch, NotificationToast, PauseEdge, ReferenceEdge, ShortcutHelpModal, WorkflowCanvas } from './chunk-RY6OZJ7A.mjs';
5
+ export { useCommentNavigation } from './chunk-TOFB4BTA.mjs';
6
+ export { useCanvasKeyboardShortcuts } from './chunk-VKXTPLM7.mjs';
7
+ import './chunk-2BHILUF7.mjs';
8
+ export { BaseNode, nodeTypes } from './chunk-55JFUNLR.mjs';
9
+ import './chunk-G3HCTMAZ.mjs';
10
+ export { useAIGenNode, useAIGenNodeHeader, useAutoLoadModelSchema, useCanGenerate, useMediaUpload, useModelSelection, useNodeExecution, usePromptAutocomplete, useRequiredInputs } from './chunk-SHU7JPQY.mjs';
11
+ import './chunk-SBB2YW3Y.mjs';
12
+ import './chunk-2C2AAXJP.mjs';
13
+ import './chunk-X3XNTD4R.mjs';
14
+ import { NodePalette } from './chunk-HMTYPFOT.mjs';
15
+ export { DebugPanel, NodePalette, PanelContainer } from './chunk-HMTYPFOT.mjs';
16
+ import './chunk-SRPSHHHV.mjs';
17
+ export { WorkflowUIProvider, useWorkflowUIConfig } from './chunk-JSF4FHBH.mjs';
18
+ import './chunk-IKR6GVZ4.mjs';
19
+ export { useAnnotationStore, usePromptEditorStore } from './chunk-AZJFDWBF.mjs';
20
+ import './chunk-YYFM6P4C.mjs';
21
+ import { useUIStore } from './chunk-R5L7WB7F.mjs';
22
+ export { useExecutionStore, useSettingsStore, useUIStore } from './chunk-R5L7WB7F.mjs';
23
+ import { useWorkflowStore } from './chunk-7DJHFOIW.mjs';
24
+ export { useWorkflowStore } from './chunk-7DJHFOIW.mjs';
25
+ export { configurePromptLibrary, usePromptLibraryStore } from './chunk-4JOFNZW6.mjs';
26
26
  import { useReactFlow } from '@xyflow/react';
27
27
  import { useRef, useEffect } from 'react';
28
28
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
@@ -104,3 +104,5 @@ function WorkflowEditorShell({
104
104
  }
105
105
 
106
106
  export { SmallGraphViewportGuard, WorkflowEditorShell };
107
+ //# sourceMappingURL=index.mjs.map
108
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/SmallGraphViewportGuard.tsx","../src/components/WorkflowEditorShell.tsx"],"names":["nodeTypes"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,IAAM,sBAAA,GAAyB,CAAA;AAC/B,IAAM,oBAAA,GAAuB,GAAA;AAC7B,IAAM,oBAAA,GAAuB,IAAA;AAC7B,IAAM,mBAAA,GAAsB,IAAA;AAErB,SAAS,uBAAA,GAA0B;AACxC,EAAA,MAAM,KAAA,GAAQ,gBAAA,CAAiB,CAAC,KAAA,KAAU,MAAM,KAAK,CAAA;AACrD,EAAA,MAAM,YAAY,YAAA,EAAa;AAC/B,EAAA,MAAM,oBAAA,GAAuB,OAAsB,IAAI,CAAA;AAEvD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,oBAAoB,oBAAA,CAAqB,OAAA;AAC/C,IAAA,oBAAA,CAAqB,UAAU,KAAA,CAAM,MAAA;AAErC,IAAA,IAAI,sBAAsB,IAAA,EAAM;AAC9B,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,YAAA,GACJ,KAAA,CAAM,MAAA,GAAS,CAAA,IAAK,MAAM,MAAA,IAAU,sBAAA;AACtC,IAAA,MAAM,qBAAA,GAAwB,MAAM,MAAA,GAAS,iBAAA;AAE7C,IAAA,IAAI,CAAC,YAAA,IAAgB,CAAC,qBAAA,EAAuB;AAC3C,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,QAAA,GACJ,OAAO,MAAA,KAAW,WAAA,IAAe,OAAO,qBAAA,GACpC,MAAA,CAAO,sBAAsB,IAAA,CAAK,MAAM,IACxC,CAAC,QAAA,KACC,OAAO,UAAA,CAAW,MAAM,SAAS,WAAA,CAAY,GAAA,EAAK,CAAA,EAAG,CAAC,CAAA;AAC9D,IAAA,MAAM,MAAA,GACJ,OAAO,MAAA,KAAW,WAAA,IAAe,OAAO,oBAAA,GACpC,MAAA,CAAO,oBAAA,CAAqB,IAAA,CAAK,MAAM,CAAA,GACvC,MAAA,CAAO,YAAA,CAAa,KAAK,MAAM,CAAA;AAErC,IAAA,MAAM,MAAA,GAAS,SAAS,MAAM;AAC5B,MAAA,SAAA,CAAU,OAAA,CAAQ;AAAA,QAChB,QAAA,EAAU,GAAA;AAAA,QACV,OAAA,EAAS,oBAAA;AAAA,QACT,OAAA,EAAS,oBAAA;AAAA,QACT,OAAA,EAAS;AAAA,OACV,CAAA;AAAA,IACH,CAAC,CAAA;AAED,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,MAAM,CAAA;AAAA,IACf,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,KAAA,CAAM,MAAA,EAAQ,SAAS,CAAC,CAAA;AAE5B,EAAA,OAAO,IAAA;AACT;AClCO,SAAS,mBAAA,CAAoB;AAAA,EAClC,YAAA;AAAA,EACA,WAAA;AAAA,EACA,SAAA,EAAAA,UAAAA;AAAA,EACA,eAAA;AAAA,EACA,UAAA;AAAA,EACA,aAAA,GAAgB,IAAA;AAAA,EAChB,eAAA,GAAkB,IAAA;AAAA,EAClB,2BAAA,GAA8B,IAAA;AAAA,EAC9B;AACF,CAAA,EAA6B;AAC3B,EAAA,MAAM,WAAA,GAAc,UAAA,CAAW,CAAC,KAAA,KAAU,MAAM,WAAW,CAAA;AAE3D,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,MAAA,EAAA,EAAK,WAAU,qEAAA,EACb,QAAA,EAAA;AAAA,MAAA,OAAA;AAAA,sBAED,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,6BAAA,EACZ,QAAA,EAAA;AAAA,QAAA,eAAA,oBACC,GAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAW,CAAA,wDAAA,EACT,WAAA,GAAc,kBAAA,GAAqB,eACrC,CAAA,CAAA;AAAA,YAEC,QAAA,EAAA,WAAA,wBAAgB,WAAA,EAAA,EAAY;AAAA;AAAA,SAC/B;AAAA,wBAGF,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iBAAA,EACZ,QAAA,EAAA;AAAA,UAAA,2BAAA,wBAAgC,uBAAA,EAAA,EAAwB,CAAA;AAAA,0BACzD,GAAA;AAAA,YAAC,cAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAWA,UAAAA;AAAA,cACX;AAAA;AAAA,WACF;AAAA,UACC,aAAA,wBAAkB,SAAA,EAAA,EAAU;AAAA,SAAA,EAC/B,CAAA;AAAA,QAEC;AAAA,OAAA,EACH;AAAA,KAAA,EACF,CAAA;AAAA,IAEC;AAAA,GAAA,EACH,CAAA;AAEJ","file":"index.mjs","sourcesContent":["'use client';\n\nimport { useReactFlow } from '@xyflow/react';\nimport { useEffect, useRef } from 'react';\nimport { useWorkflowStore } from '../stores/workflowStore';\n\nconst SMALL_GRAPH_NODE_LIMIT = 2;\nconst SMALL_GRAPH_MAX_ZOOM = 0.9;\nconst SMALL_GRAPH_MIN_ZOOM = 0.35;\nconst SMALL_GRAPH_PADDING = 0.24;\n\nexport function SmallGraphViewportGuard() {\n const nodes = useWorkflowStore((state) => state.nodes);\n const reactFlow = useReactFlow();\n const previousNodeCountRef = useRef<number | null>(null);\n\n useEffect(() => {\n const previousNodeCount = previousNodeCountRef.current;\n previousNodeCountRef.current = nodes.length;\n\n if (previousNodeCount === null) {\n return;\n }\n\n const isSmallGraph =\n nodes.length > 0 && nodes.length <= SMALL_GRAPH_NODE_LIMIT;\n const addedNodeToSmallGraph = nodes.length > previousNodeCount;\n\n if (!isSmallGraph || !addedNodeToSmallGraph) {\n return;\n }\n\n const schedule =\n typeof window !== 'undefined' && window.requestAnimationFrame\n ? window.requestAnimationFrame.bind(window)\n : (callback: FrameRequestCallback) =>\n window.setTimeout(() => callback(performance.now()), 0);\n const cancel =\n typeof window !== 'undefined' && window.cancelAnimationFrame\n ? window.cancelAnimationFrame.bind(window)\n : window.clearTimeout.bind(window);\n\n const handle = schedule(() => {\n reactFlow.fitView({\n duration: 180,\n maxZoom: SMALL_GRAPH_MAX_ZOOM,\n minZoom: SMALL_GRAPH_MIN_ZOOM,\n padding: SMALL_GRAPH_PADDING,\n });\n });\n\n return () => {\n cancel(handle);\n };\n }, [nodes.length, reactFlow]);\n\n return null;\n}\n","'use client';\n\nimport type { WorkflowNode } from '@genfeedai/types';\nimport type { NodeTypes } from '@xyflow/react';\nimport type { ReactNode } from 'react';\nimport { WorkflowCanvas } from '../canvas/WorkflowCanvas';\nimport { NodePalette } from '../panels/NodePalette';\nimport { useUIStore } from '../stores/uiStore';\nimport { BottomBar } from '../toolbar/BottomBar';\nimport { SmallGraphViewportGuard } from './SmallGraphViewportGuard';\n\nexport interface WorkflowEditorShellProps {\n modalContent?: ReactNode;\n nodePalette?: ReactNode;\n nodeTypes?: NodeTypes;\n onDownloadAsZip?: (nodes: WorkflowNode[]) => void;\n rightPanel?: ReactNode;\n showBottomBar?: boolean;\n showNodePalette?: boolean;\n showSmallGraphViewportGuard?: boolean;\n toolbar: ReactNode;\n}\n\nexport function WorkflowEditorShell({\n modalContent,\n nodePalette,\n nodeTypes,\n onDownloadAsZip,\n rightPanel,\n showBottomBar = true,\n showNodePalette = true,\n showSmallGraphViewportGuard = true,\n toolbar,\n}: WorkflowEditorShellProps) {\n const showPalette = useUIStore((state) => state.showPalette);\n\n return (\n <>\n <main className=\"flex min-h-0 flex-1 flex-col overflow-hidden bg-[var(--background)]\">\n {toolbar}\n\n <div className=\"flex flex-1 overflow-hidden\">\n {showNodePalette && (\n <div\n className={`overflow-hidden transition-all duration-300 ease-in-out ${\n showPalette ? 'w-64 opacity-100' : 'w-0 opacity-0'\n }`}\n >\n {nodePalette ?? <NodePalette />}\n </div>\n )}\n\n <div className=\"relative flex-1\">\n {showSmallGraphViewportGuard && <SmallGraphViewportGuard />}\n <WorkflowCanvas\n nodeTypes={nodeTypes}\n onDownloadAsZip={onDownloadAsZip}\n />\n {showBottomBar && <BottomBar />}\n </div>\n\n {rightPanel}\n </div>\n </main>\n\n {modalContent}\n </>\n );\n}\n"]}
package/dist/lib.mjs CHANGED
@@ -1,7 +1,7 @@
1
- export { calculateWorkflowCost, formatCost } from './chunk-MGLAKMDP.mjs';
2
- import { easing, getEasingFunction } from './chunk-U4QPE4CY.mjs';
3
- export { CubicBezierEditor, DEFAULT_CUSTOM_BEZIER, DEFAULT_IMAGE_MODEL, DEFAULT_LIPSYNC_MODEL, DEFAULT_LLM_MODEL, DEFAULT_VIDEO_MODEL, EASING_BEZIER_MAP, EASING_PRESETS, IMAGE_MODELS, IMAGE_MODEL_ID_MAP, IMAGE_MODEL_MAP, LIPSYNC_MODELS, LIPSYNC_SYNC_MODES, LLM_MODELS, LLM_MODEL_ID_MAP, LLM_MODEL_MAP, PRESET_BEZIERS, VIDEO_MODELS, VIDEO_MODEL_ID_MAP, VIDEO_MODEL_MAP, applySpeedCurve, createAsymmetricEase, createBezierEasing, easing, evaluateBezier, generateHandlesFromSchema, getAllEasingNames, getEasingBezier, getEasingDisplayName, getEasingFunction, getImageModelLabel, getLLMModelLabel, getLipSyncModelLabel, getMediaFromNode, getPresetBezier, getVideoModelLabel, isSchemaHandle, lipSyncModelSupportsImage } from './chunk-U4QPE4CY.mjs';
4
- export { CONNECTION_FIELDS, extractEnumValues, getImageDimensions, getSchemaDefaults, getVideoMetadata, supportsImageInput, validateRequiredSchemaFields } from './chunk-VVQ4CH77.mjs';
1
+ export { calculateWorkflowCost, formatCost } from './chunk-2BHILUF7.mjs';
2
+ import { easing, getEasingFunction } from './chunk-2C2AAXJP.mjs';
3
+ export { CubicBezierEditor, DEFAULT_CUSTOM_BEZIER, DEFAULT_IMAGE_MODEL, DEFAULT_LIPSYNC_MODEL, DEFAULT_LLM_MODEL, DEFAULT_VIDEO_MODEL, EASING_BEZIER_MAP, EASING_PRESETS, IMAGE_MODELS, IMAGE_MODEL_ID_MAP, IMAGE_MODEL_MAP, LIPSYNC_MODELS, LIPSYNC_SYNC_MODES, LLM_MODELS, LLM_MODEL_ID_MAP, LLM_MODEL_MAP, PRESET_BEZIERS, VIDEO_MODELS, VIDEO_MODEL_ID_MAP, VIDEO_MODEL_MAP, applySpeedCurve, createAsymmetricEase, createBezierEasing, easing, evaluateBezier, generateHandlesFromSchema, getAllEasingNames, getEasingBezier, getEasingDisplayName, getEasingFunction, getImageModelLabel, getLLMModelLabel, getLipSyncModelLabel, getMediaFromNode, getPresetBezier, getVideoModelLabel, isSchemaHandle, lipSyncModelSupportsImage } from './chunk-2C2AAXJP.mjs';
4
+ export { CONNECTION_FIELDS, extractEnumValues, getImageDimensions, getSchemaDefaults, getVideoMetadata, supportsImageInput, validateRequiredSchemaFields } from './chunk-X3XNTD4R.mjs';
5
5
 
6
6
  // src/lib/deduplicatedFetch.ts
7
7
  var inFlightRequests = /* @__PURE__ */ new Map();
@@ -590,3 +590,5 @@ function analyzeWarpCurve(easingFunction = easing.easeInOutCubic, inputDuration
590
590
  }
591
591
 
592
592
  export { analyzeWarpCurve, calculateNodeSize, calculateNodeSizePreservingHeight, calculateWarpedDuration, clearFetchCache, createGridForDimensions, deduplicatedFetch, detectAndSplitGrid, detectGrid, detectGridWithDimensions, getGridCandidates, getImageDimensions2 as getImageDimensionsFromDataUrl, getVideoDimensions as getVideoDimensionsFromUrl, splitImage, splitWithDimensions, validateWarpFunction, warpTime };
593
+ //# sourceMappingURL=lib.mjs.map
594
+ //# sourceMappingURL=lib.mjs.map