import { Node, Edge, Connection } from 'reactflow'; import { GeneratorNodeData, TransformNodeData, SaveNodeData, InputNodeData, VisionNodeData, TextNodeData, FanOutNodeData, CollectNodeData, RouterNodeData, NodeDefinition, GeneratedWorkflowData, ErrorCategory, StudioValidationIssue, AIWorkflowOperation, Template, StudioNode, StudioEdge } from '@teamflojo/floimg-studio-shared'; type NodeData = GeneratorNodeData | TransformNodeData | SaveNodeData | InputNodeData | VisionNodeData | TextNodeData | FanOutNodeData | CollectNodeData | RouterNodeData; type NodeExecutionStatus = "idle" | "pending" | "running" | "completed" | "error"; interface DataOutput { dataType: "text" | "json"; content: string; parsed?: Record; } export interface ExecutionRunOutput { nodeId: string; nodeName: string; preview: string; imageId?: string; } export interface ExecutionRun { id: string; timestamp: number; status: "completed" | "error"; duration: number; nodeCount: number; outputs: ExecutionRunOutput[]; error?: string; errorNodeId?: string; } export interface SavedWorkflow { id: string; name: string; nodes: Node[]; edges: Edge[]; createdAt: number; updatedAt: number; templateId?: string; } interface ExecutionState { status: "idle" | "running" | "completed" | "error"; imageIds: string[]; imageUrls: string[]; previews: Record; dataOutputs: Record; nodeStatus: Record; /** Per-node timing: startTime when running, duration when completed */ nodeTiming: Record; error?: string; /** ID of the node that caused the error (for error highlighting) */ errorNodeId?: string; /** Machine-readable error code (e.g., "GENERATION_ERROR", "NETWORK_ERROR") */ errorCode?: string; /** Error category for handling strategies */ errorCategory?: ErrorCategory; /** Whether the operation can be retried */ retryable?: boolean; /** Validation issues with suggested fixes (for VALIDATION_ERROR) */ validationIssues?: StudioValidationIssue[]; } interface WorkflowStore { nodes: Node[]; edges: Edge[]; selectedNodeId: string | null; currentTemplateId: string | null; loadTemplate: (template: Template) => void; clearWorkflow: () => void; savedWorkflows: SavedWorkflow[]; activeWorkflowId: string | null; activeWorkflowName: string; hasUnsavedChanges: boolean; showLibrary: boolean; parentWorkflowId: string | null; saveWorkflow: (name?: string) => string; loadWorkflow: (id: string) => void; deleteWorkflow: (id: string) => void; renameWorkflow: (id: string, name: string) => void; duplicateWorkflow: (id: string) => string; newWorkflow: () => void; setActiveWorkflowName: (name: string) => void; toggleLibrary: () => void; markDirty: () => void; previewVisible: Record; togglePreview: (id: string) => void; generators: NodeDefinition[]; transforms: NodeDefinition[]; textProviders: NodeDefinition[]; visionProviders: NodeDefinition[]; setGenerators: (generators: NodeDefinition[]) => void; setTransforms: (transforms: NodeDefinition[]) => void; setTextProviders: (textProviders: NodeDefinition[]) => void; setVisionProviders: (visionProviders: NodeDefinition[]) => void; addNode: (definition: NodeDefinition, position: { x: number; y: number; }) => void; updateNodeData: (id: string, data: Partial) => void; deleteNode: (id: string) => void; duplicateNode: (id: string) => void; setNodes: (nodes: Node[]) => void; /** Insert a Convert node between two connected nodes (for format validation quick fix) */ insertConvertNode: (sourceNodeId: string, targetNodeId: string, targetFormat: string) => void; addEdge: (connection: Connection) => void; deleteEdge: (id: string) => void; setEdges: (edges: Edge[]) => void; setSelectedNode: (id: string | null) => void; execution: ExecutionState; execute: () => Promise; executeWithValidation: () => Promise; cancelExecution: () => void; preflightValidation: { show: boolean; issues: StudioValidationIssue[]; }; validateWorkflow: () => Promise; showValidationPanel: (issues: StudioValidationIssue[]) => void; hideValidationPanel: () => void; executionHistory: ExecutionRun[]; addExecutionRun: (run: ExecutionRun) => void; clearHistory: () => void; unseenRunCount: number; hasUnseenErrors: boolean; markRunsAsSeen: () => void; pinnedRunIds: string[]; togglePinRun: (runId: string) => void; exportToYaml: () => Promise; importFromYaml: (nodes: StudioNode[], edges: StudioEdge[], name?: string) => void; loadGeneratedWorkflow: (workflow: GeneratedWorkflowData) => void; applyAIOperations: (operations: AIWorkflowOperation[]) => void; loadRemixImage: (imageUrl: string) => void; loadFromWorkflowJson: (json: { nodes: StudioNode[]; edges: StudioEdge[]; }, metadata?: { name?: string; parentWorkflowId?: string; }) => void; inspectedNodeId: string | null; openOutputInspector: (nodeId: string) => void; closeOutputInspector: () => void; imageLightbox: { src: string; nodeName: string; nodeId: string; } | null; openImageLightbox: (params: { src: string; nodeName: string; nodeId: string; }) => void; closeImageLightbox: () => void; } export declare const useWorkflowStore: import('zustand').UseBoundStore, "setState" | "persist"> & { setState(partial: WorkflowStore | Partial | ((state: WorkflowStore) => WorkflowStore | Partial), replace?: false | undefined): unknown; setState(state: WorkflowStore | ((state: WorkflowStore) => WorkflowStore), replace: true): unknown; persist: { setOptions: (options: Partial>) => void; clearStorage: () => void; rehydrate: () => Promise | void; hasHydrated: () => boolean; onHydrate: (fn: (state: WorkflowStore) => void) => () => void; onFinishHydration: (fn: (state: WorkflowStore) => void) => () => void; getOptions: () => Partial>; }; }>; export {};