import { Fragment, useCallback, useMemo, useState } from 'react'; import { AlertCircle, CheckCircle, ChevronLeft, ChevronRight, Download, Info, Plus, Trash2, Upload, X } from 'lucide-react'; import type { ModelDefinition } from '@shared/domain/models'; import type { WorkflowDefinition, WorkflowGraph, WorkflowNode, WorkflowNodeConfig, WorkflowNodeKind, WorkflowEdge, AgentNodeConfig, SubWorkflowConfig, WorkflowStateScope, } from '@shared/domain/workflow'; import { validateWorkflowDefinition } from '@shared/domain/workflow'; import { createId } from '@shared/utils/ids'; import { ToggleSwitch } from '@renderer/components/ui'; import { WorkflowGraphCanvas } from './workflow/WorkflowGraphCanvas'; import { ExportDropdown, ExportModal, ImportModal } from './workflow/WorkflowExportImportPanel'; import { WorkflowGraphInspector } from './workflow/WorkflowGraphInspector'; import { WorkflowNodePalette } from './workflow/WorkflowNodePalette'; import { OrchestrationModePanel } from './workflow/OrchestrationModePanel'; interface WorkflowEditorProps { availableModels: ReadonlyArray; workflow: WorkflowDefinition; workflows: ReadonlyArray; onChange: (workflow: WorkflowDefinition) => void; onDelete?: () => void; onSave: () => void; onBack: () => void; onExportWorkflow?: (format: 'yaml' | 'mermaid' | 'dot') => Promise<{ content: string }>; onImportWorkflow?: (content: string, format: 'yaml' | 'json') => Promise; } interface WorkflowBreadcrumb { workflow: WorkflowDefinition; nodeId: string; nodeLabel: string; /** true when drilling into a referenced (not inline) workflow — view-only */ readOnly: boolean; } function InputField({ label, value, onChange, multiline, placeholder, }: { label: string; value: string; onChange: (value: string) => void; multiline?: boolean; placeholder?: string; }) { const baseClasses = 'w-full rounded-lg border border-[var(--color-border)] bg-[var(--color-surface-1)] px-3 py-2 text-[13px] text-[var(--color-text-primary)] placeholder-[var(--color-text-muted)] outline-none transition-all duration-200 focus:border-[var(--color-accent)]/50'; return (