@yiyi_zhang/reactflow-ui 1.2.0 → 1.3.1

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 (116) hide show
  1. package/README.md +8 -6
  2. package/dist/AiWorkflowIDE.d.ts +13 -0
  3. package/dist/WorkflowIDE.d.ts +9 -0
  4. package/dist/actions/builtin/coerce.d.ts +9 -0
  5. package/dist/actions/types.d.ts +1 -0
  6. package/dist/ai.d.ts +21 -2
  7. package/dist/components/AiNative/AgentTimeline.d.ts +1 -1
  8. package/dist/components/AiNative/ClarificationCard.d.ts +3 -2
  9. package/dist/components/AiNative/InlineCanvasCopilot.d.ts +2 -1
  10. package/dist/components/AiNative/RepairCard.d.ts +3 -2
  11. package/dist/components/AiNative/mermaidParser.d.ts +31 -0
  12. package/dist/components/AiNative/repairActions.d.ts +16 -0
  13. package/dist/components/AiNative/runInputs.d.ts +13 -0
  14. package/dist/components/BrandLogo.d.ts +2 -3
  15. package/dist/components/ConfirmDialog.d.ts +3 -1
  16. package/dist/components/DraftCodeField.d.ts +26 -0
  17. package/dist/components/PromptDialog.d.ts +3 -1
  18. package/dist/components/business/ActionPickerModal.d.ts +2 -0
  19. package/dist/components/business/BusinessEditorContext.d.ts +38 -0
  20. package/dist/components/business/DataPillInput.d.ts +10 -0
  21. package/dist/components/business/DecisionBranchCard.d.ts +2 -1
  22. package/dist/components/business/ForkJoinCard.d.ts +2 -1
  23. package/dist/components/business/LibraryVersionBadge.d.ts +1 -1
  24. package/dist/components/business/LoopDoWhileCard.d.ts +2 -1
  25. package/dist/components/business/NestedControlStep.d.ts +7 -1
  26. package/dist/components/business/RunStoryTimeline.d.ts +7 -0
  27. package/dist/components/business/StepCardParts.d.ts +73 -0
  28. package/dist/components/business/StepFlowEditor.d.ts +18 -1
  29. package/dist/components/business/StepListEditor.d.ts +6 -2
  30. package/dist/components/business/deleteMessage.d.ts +6 -0
  31. package/dist/components/business/runStatus.d.ts +11 -0
  32. package/dist/components/icons/CmIcon.d.ts +17 -0
  33. package/dist/components/icons/iconRegistry.d.ts +80 -0
  34. package/dist/components/import/ApiImportDialog.d.ts +27 -0
  35. package/dist/components/onboarding/ModalShell.d.ts +15 -0
  36. package/dist/components/onboarding/OnboardingController.d.ts +74 -0
  37. package/dist/components/onboarding/OnboardingGuideCard.d.ts +10 -0
  38. package/dist/components/onboarding/OnboardingWizard.d.ts +42 -0
  39. package/dist/components/onboarding/PromotionPanel.d.ts +28 -0
  40. package/dist/components/onboarding/WorkflowNameBuilder.d.ts +19 -0
  41. package/dist/components/onboarding/index.d.ts +8 -0
  42. package/dist/components/onboarding/styles.d.ts +11 -0
  43. package/dist/components/onboarding/useOnboardingData.d.ts +17 -0
  44. package/dist/components/template/TemplateGallery.d.ts +2 -0
  45. package/dist/components/template/TemplateSetupWizard.d.ts +2 -0
  46. package/dist/hooks/useConfirm.d.ts +3 -1
  47. package/dist/import/buildAction.d.ts +23 -0
  48. package/dist/import/common.d.ts +23 -0
  49. package/dist/import/curl.d.ts +12 -0
  50. package/dist/import/detect.d.ts +9 -0
  51. package/dist/import/index.d.ts +10 -0
  52. package/dist/import/insert.d.ts +16 -0
  53. package/dist/import/openapi.d.ts +9 -0
  54. package/dist/import/postman.d.ts +9 -0
  55. package/dist/import/schema.d.ts +15 -0
  56. package/dist/import/selection.d.ts +17 -0
  57. package/dist/import/sensitive.d.ts +18 -0
  58. package/dist/import/types.d.ts +62 -0
  59. package/dist/import/util.d.ts +23 -0
  60. package/dist/index.d.ts +21 -2
  61. package/dist/library/versionStatus.d.ts +2 -2
  62. package/dist/logo.svg +9 -36
  63. package/dist/onboarding/index.d.ts +6 -0
  64. package/dist/onboarding/naming.d.ts +46 -0
  65. package/dist/onboarding/poll.d.ts +42 -0
  66. package/dist/onboarding/wizardState.d.ts +44 -0
  67. package/dist/parser/conductorGenerator.d.ts +17 -2
  68. package/dist/product-launch.html +10 -1394
  69. package/dist/providers/WorkflowIdeProvider.d.ts +23 -0
  70. package/dist/providers/resolve.d.ts +20 -0
  71. package/dist/providers/types.d.ts +67 -0
  72. package/dist/reactflow-ui-ai.es.js +20355 -13884
  73. package/dist/reactflow-ui.css +1 -1
  74. package/dist/reactflow-ui.es.js +23257 -14745
  75. package/dist/reactflow-ui.umd.js +192 -38
  76. package/dist/sample-imports/cmdb-openapi3.json +334 -0
  77. package/dist/sample-imports/cmdb-postman.json +100 -0
  78. package/dist/sample-imports/ticket-swagger2.json +231 -0
  79. package/dist/sample-workflows/ecs-lifecycle-automation.json +36 -4
  80. package/dist/services/ai/agentRunner.d.ts +42 -1
  81. package/dist/services/ai/errorMessages.d.ts +9 -1
  82. package/dist/services/ai/protocolAdapter.d.ts +5 -0
  83. package/dist/services/ai/systemPrompt.d.ts +1 -1
  84. package/dist/services/ai/toolExecutor.d.ts +26 -0
  85. package/dist/services/ai/workflowSynthesizer.d.ts +4 -4
  86. package/dist/services/aiService.d.ts +5 -1
  87. package/dist/stepmodel/compile.d.ts +2 -1
  88. package/dist/stepmodel/factory.d.ts +5 -0
  89. package/dist/stepmodel/pills.d.ts +32 -0
  90. package/dist/stepmodel/types.d.ts +10 -0
  91. package/dist/stepmodel/validate.d.ts +20 -0
  92. package/dist/store/aiStore.d.ts +10 -3
  93. package/dist/store/sandboxRunObserver.d.ts +20 -0
  94. package/dist/store/workflowStore.d.ts +2 -9
  95. package/dist/telemetry/buffer.d.ts +37 -0
  96. package/dist/telemetry/once.d.ts +11 -0
  97. package/dist/telemetry/track.d.ts +17 -0
  98. package/dist/telemetry/types.d.ts +24 -0
  99. package/dist/telemetry/useTelemetry.d.ts +22 -0
  100. package/dist/template/templateStore.d.ts +6 -0
  101. package/dist/template/types.d.ts +1 -0
  102. package/dist/types/conductor.d.ts +25 -1
  103. package/dist/types/workflow.d.ts +20 -3
  104. package/dist/types/workflowLibrary.d.ts +5 -5
  105. package/dist/utils/executionAnalyzer.d.ts +5 -0
  106. package/dist/utils/executionImport.d.ts +52 -0
  107. package/dist/utils/executionPoller.d.ts +37 -0
  108. package/dist/utils/localSandboxEngine.d.ts +43 -6
  109. package/dist/utils/runStory.d.ts +20 -0
  110. package/dist/utils/sandbox/jq.d.ts +13 -0
  111. package/dist/utils/sandbox/scriptRunner.d.ts +34 -0
  112. package/dist/utils/statusMeta.d.ts +35 -0
  113. package/dist/utils/taskEditing.d.ts +59 -0
  114. package/dist/utils/taskTypeMeta.d.ts +1 -0
  115. package/dist/utils/validationRules.d.ts +19 -5
  116. package/package.json +6 -2
@@ -68,10 +68,20 @@ export interface TaskDef {
68
68
  assignmentCompletionStrategy?: string;
69
69
  displayName?: string;
70
70
  };
71
+ /**
72
+ * 内嵌任务定义(Conductor WorkflowTask.taskDefinition)。超时 / 重试策略等 TaskDef 字段只在这里或已注册的
73
+ * 任务定义中生效;设置后 Conductor 用它代替同名的已注册任务定义。
74
+ */
75
+ taskDefinition?: Record<string, any>;
76
+ /** WorkflowTask 自身支持 retryCount(覆盖任务定义里的值) */
71
77
  retryCount?: number;
78
+ /** @deprecated 写在 WorkflowTask 顶层会被 Conductor 忽略,请改用 taskDefinition.retryLogic */
72
79
  retryLogic?: 'FIXED' | 'EXPONENTIAL_BACKOFF' | 'LINEAR_BACKOFF';
80
+ /** @deprecated 请改用 taskDefinition.retryDelaySeconds */
73
81
  retryDelaySeconds?: number;
82
+ /** @deprecated 请改用 taskDefinition.timeoutSeconds */
74
83
  timeoutSeconds?: number;
84
+ /** @deprecated 请改用 taskDefinition.timeoutPolicy */
75
85
  timeoutPolicy?: 'RETRY' | 'TIME_OUT_WF' | 'ALERT_ONLY' | 'FAIL_WORKFLOW';
76
86
  }
77
87
  /**
@@ -105,7 +115,15 @@ export interface WorkflowInputParam {
105
115
  /**
106
116
  * 解析工作流入参声明:兼容 string[] 旧格式与 WorkflowInputParam[] 新格式
107
117
  */
108
- export declare function parseWorkflowInputParams(raw: any[] | undefined): WorkflowInputParam[];
118
+ export declare function parseWorkflowInputParams(raw: any[] | undefined, def?: Pick<WorkflowDef, 'inputSchema' | 'inputTemplate'> | null): WorkflowInputParam[];
119
+ /**
120
+ * 把结构化入参写回 Conductor 能接受的形态(E22):
121
+ * - `inputParameters` 只保留参数名(Conductor WorkflowDef 只接受 List<String>)
122
+ * - 类型 / 说明 / 必填 / 示例写入 `inputSchema`(JSON Schema,Conductor 标准字段)
123
+ * - 默认值写入 `inputTemplate`(Conductor 启动时用它补齐缺省入参)
124
+ * 只改动由入参列表管理的键,用户手写的其他 schema 属性 / 模板键原样保留。
125
+ */
126
+ export declare function serializeWorkflowInputParams(params: WorkflowInputParam[], def: Pick<WorkflowDef, 'name' | 'inputParameters' | 'inputSchema' | 'inputTemplate'>): Pick<WorkflowDef, 'inputParameters' | 'inputSchema' | 'inputTemplate'>;
109
127
  /**
110
128
  * Conductor 工作流定义
111
129
  */
@@ -184,6 +202,10 @@ export interface TaskInstance {
184
202
  externalInputPayloadStoragePath?: string;
185
203
  externalOutputPayloadStoragePath?: string;
186
204
  workflowTask?: TaskDef;
205
+ /** 仅浏览器沙箱:本任务是真实执行、使用模拟数据,还是未执行(同步接口不执行脚本等) */
206
+ sandboxExecution?: 'executed' | 'mocked' | 'not_executed';
207
+ /** 仅浏览器沙箱:执行中的提示(未取到值的引用、走默认分支的原因等) */
208
+ sandboxWarnings?: string[];
187
209
  }
188
210
  /**
189
211
  * Conductor 工作流实例 (运行时)
@@ -217,4 +239,6 @@ export interface WorkflowInstance {
217
239
  startTime?: number;
218
240
  createdBy?: string;
219
241
  updatedBy?: string;
242
+ /** 浏览器沙箱试运行产生的实例(模拟数据,不存在于服务端) */
243
+ isSandbox?: boolean;
220
244
  }
@@ -228,6 +228,14 @@ export interface WorkflowState {
228
228
  affectedTasks: string[];
229
229
  timestamp: number;
230
230
  } | null;
231
+ /** 本地沙箱:试运行进行中(脚本在 Web Worker 中异步执行) */
232
+ sandboxRunning: boolean;
233
+ /** 本地沙箱:最近一次需要提示用户的消息(空流程、执行出错),界面显示后调用 clearSandboxNotice */
234
+ sandboxNotice: {
235
+ text: string;
236
+ type: 'error' | 'info';
237
+ timestamp: number;
238
+ } | null;
231
239
  /** 运行态:是否显示底部并发瀑布流与时空回放面板 */
232
240
  showWaterfallPanel: boolean;
233
241
  /** 运行态:时空旅行回放游标时间戳 (ms),为 null 表示展示最终实时态 */
@@ -258,7 +266,10 @@ export interface WorkflowActions {
258
266
  setSelectedTask: (task: TaskDef | null) => void;
259
267
  setSelectedTaskInstance: (instance: TaskInstance | null) => void;
260
268
  checkTaskRefUniqueness: (newRef: string, currentRef: string) => boolean;
269
+ /** 按字段合并更新任务;引用名改成重复 / 非法值时整次更新被拒绝 */
261
270
  updateTask: (taskRef: string, field: string | Record<string, any>, value?: any) => void;
271
+ /** 用新的任务对象整体替换(JSON 面板“应用到画布”使用,删掉的键会真正删除);成功返回 null,失败返回原因 */
272
+ replaceTask: (taskRef: string, nextTask: TaskDef) => string | null;
262
273
  updateWorkflowProperties: (properties: Partial<WorkflowDef>) => void;
263
274
  addNode: (newNode: any, sourceId: string, targetId: string, edgeId: string, edgeData?: any) => void;
264
275
  removeNode: (nodeId: string) => void;
@@ -266,7 +277,8 @@ export interface WorkflowActions {
266
277
  removeLoopTask: (loopRef: string, taskRef: string) => void;
267
278
  addDecisionBranch: (taskRef: string, caseName: string) => void;
268
279
  removeDecisionBranch: (taskRef: string, caseName: string) => void;
269
- renameDecisionBranch: (taskRef: string, oldName: string, newName: string) => void;
280
+ /** 重命名分支;新名称为空、为保留字 default 或与已有分支重名时拒绝并返回 false */
281
+ renameDecisionBranch: (taskRef: string, oldName: string, newName: string) => boolean;
270
282
  addForkBranch: (taskRef: string) => void;
271
283
  copyTask: (task: TaskDef) => void;
272
284
  pasteTask: (task: TaskDef) => void;
@@ -295,6 +307,8 @@ export interface WorkflowActions {
295
307
  setShowDataLineage: (show: boolean) => void;
296
308
  /** W-LSP: 清除重构提示文案 */
297
309
  clearRefactorNotice: () => void;
310
+ /** 本地沙箱:清除提示消息 */
311
+ clearSandboxNotice: () => void;
298
312
  /** 运行态:切换底部并发瀑布流面板 */
299
313
  setShowWaterfallPanel: (show: boolean) => void;
300
314
  /** 运行态:设置时空旅行时间戳 */
@@ -303,8 +317,11 @@ export interface WorkflowActions {
303
317
  setLoopIteration: (loopRef: string, iteration: number) => void;
304
318
  /** AI 共驾:打开/关闭画布原位 Cmd+K 浮窗 */
305
319
  setInlineCopilotTaskRef: (taskRef: string | null) => void;
306
- /** 本地沙箱:在浏览器内执行零延迟确定性试运行并进入调试视图 */
307
- runLocalSandboxDryRun: (mockInput?: Record<string, any>, taskMocks?: Record<string, any>, maxLoopIterations?: number) => void;
320
+ /**
321
+ * 本地沙箱:在浏览器内试运行并进入运行视图。INLINE / JQ / SWITCH / DO_WHILE 等无外部依赖的任务真实执行,
322
+ * 调用外部系统的任务使用模拟数据。脚本在隔离的 Web Worker 中运行,因此是异步的。
323
+ */
324
+ runLocalSandboxDryRun: (mockInput?: Record<string, any>, taskMocks?: Record<string, any>, maxLoopIterations?: number) => Promise<void>;
308
325
  }
309
326
  /**
310
327
  * 重启选项
@@ -6,11 +6,11 @@
6
6
  * L3: 端到端编排(跨系统复杂场景,可由 L2/L1 组合而成)
7
7
  *
8
8
  * 调用规则:高层可调用低层及同层,禁止反向跨层调用
9
- * L3 → L2/L1/L3(同层) ✅
10
- * L2 → L1/L2(同层) ✅
11
- * L1 → L1(同层) ✅
12
- * L1 → L2/L3 ❌
13
- * L2 → L3 ❌
9
+ * L3 → L2/L1/L3(同层) 允许
10
+ * L2 → L1/L2(同层) 允许
11
+ * L1 → L1(同层) 允许
12
+ * L1 → L2/L3 禁止
13
+ * L2 → L3 禁止
14
14
  */
15
15
  export type WorkflowLevel = 'L1' | 'L2' | 'L3';
16
16
  /** 工作流库元数据(列表/搜索返回) */
@@ -12,7 +12,10 @@ export interface StepInfo {
12
12
  startTime?: number;
13
13
  endTime?: number;
14
14
  durationMs?: number;
15
+ /** Retries only (R5): loop iterations are not retries. */
15
16
  retryCount: number;
17
+ /** Loop iterations the step ran (0 outside loops). */
18
+ iterationCount: number;
16
19
  reasonForIncompletion?: string;
17
20
  diagnostics: DiagnosticResult[];
18
21
  }
@@ -28,5 +31,7 @@ export interface ExecutionSummary {
28
31
  export declare function diagnoseTask(taskRef: string, executionData: Record<string, TaskExecutionData>): DiagnosticResult[];
29
32
  export declare function analyzeExecution(executionData: Record<string, TaskExecutionData>, workflowInstance: WorkflowInstance | null): ExecutionSummary;
30
33
  export declare function formatDuration(ms?: number): string;
34
+ /** Icon name from the CMASTER icon registry (render with <CmIcon name=…>). */
31
35
  export declare function getCategoryIcon(category: DiagnosticResult['category']): string;
36
+ /** Every diagnostic is a problem, so the colour is a status colour; the icon and label tell the categories apart. */
32
37
  export declare function getCategoryColor(category: DiagnosticResult['category']): string;
@@ -0,0 +1,52 @@
1
+ import type { TaskExecutionData } from '../types/workflow';
2
+ import type { TaskInstance } from '../types/conductor';
3
+ /**
4
+ * Pure helpers behind `importExecutionJSON` and the run view (R3, R5, R9).
5
+ *
6
+ * Conductor names tasks inside a DO_WHILE `<ref>__<iteration>` and gives each retry a new task with a higher
7
+ * `retryCount`. Iterations and retries are different things: an iteration is a new pass through the loop, a retry is
8
+ * another attempt at the same pass.
9
+ */
10
+ type DefTask = {
11
+ type?: string;
12
+ taskReferenceName?: string;
13
+ decisionCases?: Record<string, DefTask[]>;
14
+ defaultCase?: DefTask[];
15
+ forkTasks?: DefTask[][];
16
+ loopOver?: DefTask[];
17
+ };
18
+ /** Split `step__3` into `{ baseRef: 'step', iteration: 3 }` when `step` is a task of the definition. */
19
+ export declare function splitIterationRef(ref: string, knownRefs: Record<string, unknown>): {
20
+ baseRef: string;
21
+ iteration?: number;
22
+ };
23
+ /** Number of retries across all attempts: per iteration, the highest retryCount (or extra attempts when absent). */
24
+ export declare function countRetries(attempts: TaskInstance[] | undefined): number;
25
+ /** Number of distinct loop iterations in the attempts (0 when the task is not in a loop). */
26
+ export declare function countIterations(attempts: TaskInstance[] | undefined): number;
27
+ /** The last attempt (highest retry) of the given iteration, or undefined. */
28
+ export declare function pickAttemptForIteration(attempts: TaskInstance[], iteration: number): TaskInstance | undefined;
29
+ /**
30
+ * Innermost DO_WHILE that contains `ref` (at any depth inside its loopOver, including branches), or null.
31
+ */
32
+ export declare function findEnclosingLoopRef(tasks: DefTask[] | undefined, ref: string): string | null;
33
+ /**
34
+ * Execution view of one node with the loop iteration chosen for ITS enclosing loop only (R3).
35
+ * Other loops' choices do not affect it; within the iteration the last attempt (latest retry) wins.
36
+ */
37
+ export declare function selectExecutionForIteration(execution: TaskExecutionData, loopRef: string | null, activeLoopIterations: Record<string, number>): TaskExecutionData;
38
+ /**
39
+ * Runtime children of each dynamic fork (R9). Inside a loop the fork and join run as `fork__N` / `join__N`; each fork
40
+ * occurrence is paired with the join of the same suffix. The base fork key holds the latest iteration's children;
41
+ * `fork__N` keys hold each iteration's children.
42
+ */
43
+ export declare function collectDynamicForkChildren(tasks: TaskInstance[], pairs: Array<{
44
+ forkRef: string;
45
+ joinRef: string;
46
+ }>, knownRefs: Record<string, unknown>): Record<string, TaskInstance[]>;
47
+ /**
48
+ * Group runtime tasks by definition ref (R5): a `ref__N` record is registered once, under its base ref, as the
49
+ * attempt for iteration N. Attempts are ordered by iteration, then retry; the node's status is its last attempt.
50
+ */
51
+ export declare function buildExecutionData(tasks: TaskInstance[], knownRefs: Record<string, unknown>): Record<string, TaskExecutionData>;
52
+ export {};
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Cancellable execution polling with back-off and a failure cap (R2).
3
+ *
4
+ * - `cancel()` (or aborting `signal`) stops the loop: no further timers and no more `onInstance` calls, even if a
5
+ * request is in flight when it is cancelled.
6
+ * - Thrown errors and `null` results count as failures; after `maxFailures` consecutive failures the loop stops and
7
+ * calls `onGiveUp` with a message that says what happened and how to fix it.
8
+ * - `shouldContinue()` is checked before every request and before delivering a result (e.g. "the user is still in run
9
+ * mode"); when it returns false the loop stops quietly.
10
+ */
11
+ export interface PollableInstance {
12
+ status: string;
13
+ }
14
+ export interface ExecutionPollerOptions<T extends PollableInstance> {
15
+ workflowId: string;
16
+ poll: (workflowId: string, signal: AbortSignal) => Promise<T | null>;
17
+ onInstance: (instance: T) => void;
18
+ onDone?: (instance: T) => void;
19
+ onGiveUp?: (message: string) => void;
20
+ shouldContinue?: () => boolean;
21
+ /** First delay in ms (default 3000). */
22
+ interval?: number;
23
+ /** Longest delay in ms (default 15000). */
24
+ maxInterval?: number;
25
+ /** Consecutive failures before giving up (default 5). */
26
+ maxFailures?: number;
27
+ signal?: AbortSignal;
28
+ /** Injectable timer for tests. */
29
+ setTimer?: (fn: () => void, ms: number) => unknown;
30
+ clearTimer?: (handle: unknown) => void;
31
+ }
32
+ export declare const TERMINAL_WORKFLOW_STATUSES: Set<string>;
33
+ export interface ExecutionPoller {
34
+ cancel: () => void;
35
+ readonly cancelled: boolean;
36
+ }
37
+ export declare function startExecutionPolling<T extends PollableInstance>(opts: ExecutionPollerOptions<T>): ExecutionPoller;
@@ -1,4 +1,18 @@
1
1
  import type { WorkflowDef, TaskDef as WorkflowTask, WorkflowInstance, TaskInstance as TaskExecution } from '../types/conductor';
2
+ import { type ScriptEvaluator } from './sandbox/scriptRunner';
3
+ /**
4
+ * In-browser sandbox for Conductor workflows.
5
+ *
6
+ * Tasks that need no outside system run for real with Conductor semantics: INLINE / LAMBDA (JavaScript), JSON_JQ_TRANSFORM
7
+ * (jq subset), SWITCH / DECISION (value-param and javascript), DO_WHILE (loop condition evaluated after each iteration),
8
+ * FORK_JOIN, FORK_JOIN_DYNAMIC, JOIN, SET_VARIABLE, TERMINATE, WAIT. Tasks that call outside systems (HTTP, SIMPLE, HUMAN,
9
+ * EVENT, KAFKA_PUBLISH, SUB_WORKFLOW, START_WORKFLOW, DYNAMIC …) return mock data, which the user can override per task.
10
+ * Every task execution says which one happened in `sandboxExecution`.
11
+ *
12
+ * Scripts run in an isolated Web Worker, so script evaluation is asynchronous: use `executeLocalSandboxDryRunAsync`.
13
+ * The synchronous `executeLocalSandboxDryRun` is kept for existing hosts; it does not run scripts and marks the affected
14
+ * tasks as not executed instead of inventing a result.
15
+ */
2
16
  export interface TaskMockOverride {
3
17
  __isMockOverride?: boolean;
4
18
  /** Override execution status (e.g. simulate FAILED or TIMED_OUT) */
@@ -17,33 +31,56 @@ export interface SandboxDryRunOptions {
17
31
  workflowInput?: Record<string, any>;
18
32
  /** Custom task output or behavior overrides keyed by taskReferenceName */
19
33
  taskMocks?: Record<string, Record<string, any> | TaskMockOverride>;
20
- /** Max iterations per DO_WHILE loop in dry-run (default: 2) */
34
+ /**
35
+ * Safety limit for DO_WHILE iterations. The loop condition decides when a loop ends; when it is still true at this
36
+ * limit the loop stops and is marked COMPLETED_WITH_ERRORS. Default 20 (async API). The synchronous API cannot evaluate
37
+ * loop conditions, so there it is the number of iterations run (default 2, as before).
38
+ */
21
39
  maxLoopIterations?: number;
22
40
  }
41
+ export interface SandboxAsyncOptions extends SandboxDryRunOptions {
42
+ /** Time budget per script in ms (default 2000). A script that runs longer is stopped and its task fails. */
43
+ scriptTimeoutMs?: number;
44
+ /** Custom script evaluator (tests, or hosts with their own isolation). Defaults to an isolated Web Worker. */
45
+ scriptEvaluator?: ScriptEvaluator;
46
+ }
23
47
  interface SandboxRuntimeContext {
24
48
  workflowInput: Record<string, any>;
25
49
  variables: Record<string, any>;
26
50
  taskOutputs: Record<string, Record<string, any>>;
51
+ taskInputs: Record<string, Record<string, any>>;
27
52
  taskMocks: Record<string, Record<string, any> | TaskMockOverride>;
28
53
  tasks: TaskExecution[];
29
54
  currentTimeMs: number;
30
55
  maxLoopIterations: number;
56
+ /** false in the synchronous API: loop conditions are not evaluated there */
57
+ canRunScripts: boolean;
31
58
  seqCounter: number;
59
+ /** refs spawned by the most recent FORK_JOIN_DYNAMIC, consumed by its JOIN */
60
+ lastDynamicSpawn: string[] | null;
32
61
  }
33
62
  /**
34
- * Resolve Conductor `${...}` expressions against current sandbox context
63
+ * Resolve Conductor `${...}` expressions against current sandbox context.
64
+ * References that cannot be resolved stay as written and are added to `misses` when given.
35
65
  */
36
- export declare function resolveExpressionValue(val: any, ctx: SandboxRuntimeContext): any;
66
+ export declare function resolveExpressionValue(val: any, ctx: SandboxRuntimeContext, misses?: string[]): any;
37
67
  /**
38
- * Generate default synthetic output for a given task (used both at runtime and as UI template preview)
68
+ * Default output shown for a task as a starting point for a custom mock (also what mocked tasks return).
39
69
  */
40
70
  export declare function generateDefaultTaskOutputPreview(task: WorkflowTask, resolvedInput?: Record<string, any>, iteration?: number): Record<string, any>;
41
71
  /**
42
- * Build default mock input from workflowDef.inputParameters and auto-discovered ${workflow.input.*} references
72
+ * Build mock workflow input: declared input parameters plus every `${workflow.input.<field>}` the tasks reference.
43
73
  */
44
74
  export declare function buildDefaultWorkflowMockInput(workflowDef: WorkflowDef): Record<string, any>;
45
75
  /**
46
- * Execute an entire WorkflowDef in-browser deterministically and return a complete WorkflowInstance
76
+ * Run a WorkflowDef in the browser and return a complete WorkflowInstance.
77
+ * Scripts (INLINE, javascript SWITCH / DECISION, DO_WHILE conditions) run in an isolated Web Worker.
78
+ */
79
+ export declare function executeLocalSandboxDryRunAsync(workflowDef: WorkflowDef, options?: SandboxAsyncOptions): Promise<WorkflowInstance>;
80
+ /**
81
+ * Synchronous variant kept for existing hosts. It does not run scripts: INLINE tasks are SKIPPED with
82
+ * `sandboxExecution: 'not_executed'`, javascript conditions take the default branch with a warning, and DO_WHILE runs
83
+ * `maxLoopIterations` iterations (default 2). Prefer `executeLocalSandboxDryRunAsync`.
47
84
  */
48
85
  export declare function executeLocalSandboxDryRun(workflowDef: WorkflowDef, options?: SandboxDryRunOptions): WorkflowInstance;
49
86
  export {};
@@ -0,0 +1,20 @@
1
+ import type { TaskInstance, WorkflowInstance } from '../types/conductor';
2
+ import { type StatusTone } from './statusMeta';
3
+ /**
4
+ * One sentence describing what a step did in this run.
5
+ * @param actionName display name of the step's action (falls back to task names)
6
+ * @param allTasks all tasks of the run (used for JOIN summaries)
7
+ */
8
+ export declare function generateStorySentence(task: TaskInstance, options?: {
9
+ actionId?: string;
10
+ actionName?: string;
11
+ allTasks?: TaskInstance[];
12
+ }): string;
13
+ export interface RunHeadline {
14
+ title: string;
15
+ tone: StatusTone;
16
+ /** Duration in seconds when the run has both start and end, else undefined. */
17
+ durationSec?: string;
18
+ }
19
+ /** Banner title for the whole run (B11): one wording per workflow status, never "all done" for a running run. */
20
+ export declare function runHeadline(instance: Pick<WorkflowInstance, 'status' | 'startTime' | 'endTime'>): RunHeadline;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * A small jq interpreter for the in-browser sandbox (JSON_JQ_TRANSFORM).
3
+ *
4
+ * It covers the jq that workflow authors actually write: paths, iteration, pipes, comma, object / array construction,
5
+ * arithmetic and comparison, `and/or/not`, `//`, `if-then-elif-else-end`, `as $x`, `reduce`, string interpolation, optional
6
+ * `?`, and the common builtins (see BUILTINS). Anything outside that raises a JqError that says which syntax is not
7
+ * supported, so the sandbox reports a failure instead of inventing a result.
8
+ */
9
+ export declare class JqError extends Error {
10
+ constructor(message: string);
11
+ }
12
+ /** Run a jq program against one input. Returns all outputs; throws JqError on syntax / runtime errors. */
13
+ export declare function runJq(query: string, input: unknown): unknown[];
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Runs Conductor JavaScript expressions (INLINE, SWITCH / DECISION javascript evaluators, DO_WHILE loop conditions)
3
+ * for the in-browser sandbox.
4
+ *
5
+ * The expression is workflow content, possibly written by someone else, so it never runs on the page itself: it runs in a
6
+ * dedicated Web Worker with network, storage and messaging APIs removed, and the worker is terminated when a script
7
+ * exceeds its time budget (an infinite loop cannot freeze the IDE).
8
+ */
9
+ export type ScriptResult = {
10
+ ok: true;
11
+ value: unknown;
12
+ } | {
13
+ ok: false;
14
+ error: string;
15
+ notExecuted?: boolean;
16
+ };
17
+ /** Evaluate `expression` with `$` bound to `input`; the value of the last expression statement is the result. */
18
+ export type ScriptEvaluator = (expression: string, input: Record<string, unknown>) => Promise<ScriptResult>;
19
+ export interface WorkerScriptEvaluator {
20
+ evaluate: ScriptEvaluator;
21
+ /** Stop the worker. Further calls start a new one. */
22
+ dispose: () => void;
23
+ }
24
+ export declare const DEFAULT_SCRIPT_TIMEOUT_MS = 2000;
25
+ /**
26
+ * Create an evaluator backed by an isolated Web Worker.
27
+ * Returns an evaluator that reports `notExecuted` when the page cannot create workers (no Worker API, or a CSP that
28
+ * forbids blob: workers), so the sandbox can say why a script did not run instead of guessing a result.
29
+ */
30
+ export declare function createWorkerScriptEvaluator(options?: {
31
+ timeoutMs?: number;
32
+ }): WorkerScriptEvaluator;
33
+ /** Evaluator used by the synchronous API: never runs scripts, says so. */
34
+ export declare const notExecutedEvaluator: (expression: string) => ScriptResult;
@@ -0,0 +1,35 @@
1
+ import { type LucideIcon } from 'lucide-react';
2
+ /**
3
+ * One source for "status → colour + icon + Chinese word" (CMASTER rule 5: never colour alone).
4
+ * Covers every Conductor task status and workflow status. Use it in badges, bars, timelines and summaries
5
+ * instead of a local map.
6
+ */
7
+ export type StatusTone = 'pending' | 'running' | 'success' | 'warning' | 'failed' | 'skipped' | 'muted';
8
+ export interface StatusMeta {
9
+ /** Raw Conductor status (upper case). */
10
+ status: string;
11
+ /** Chinese word shown to the user. */
12
+ label: string;
13
+ /** Lucide icon component (render with strokeWidth 1.75). */
14
+ icon: LucideIcon;
15
+ /** Stable icon key, useful for tests and CSS hooks. */
16
+ iconName: string;
17
+ /** Colour token (CSS custom property reference). */
18
+ color: string;
19
+ /** Semantic group. */
20
+ tone: StatusTone;
21
+ /** CSS class suffix, kebab-case of the status (e.g. `completed-with-errors`). */
22
+ className: string;
23
+ /** The run / task reached a final state. */
24
+ terminal: boolean;
25
+ /** Final state that counts as a failure (failed, timed out, terminated…). */
26
+ isFailure: boolean;
27
+ /** Still running or waiting to run. */
28
+ isActive: boolean;
29
+ }
30
+ /** Every status the helper knows, in a sensible display order. */
31
+ export declare const KNOWN_STATUSES: string[];
32
+ /** Look up a status. Unknown or empty values get a neutral "未知" entry (never throws). */
33
+ export declare function getStatusMeta(status: string | null | undefined): StatusMeta;
34
+ /** Chinese word for a status, e.g. `COMPLETED` → `成功`. */
35
+ export declare function statusLabel(status: string | null | undefined): string;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * 专业模式编辑器的纯函数助手:新建任务默认值、引用名 / 分支名校验、删除影响说明、粘贴改名。
3
+ * 只依赖定义数据,不依赖 React / store,方便单测(v1.3.1 E1–E4、E7、E13–E15、E19、E20)。
4
+ */
5
+ import type { TaskDef, WorkflowDef } from '../types/conductor';
6
+ /** Conductor 引用名允许的字符 */
7
+ export declare const TASK_REF_PATTERN: RegExp;
8
+ /**
9
+ * 按任务类型生成 Conductor 能直接接受的新任务(字段位置以 Conductor OSS WorkflowTask / 各 TaskMapper 为准)。
10
+ * FORK_JOIN / FORK_JOIN_DYNAMIC 的配对 JOIN 用 {@link createJoinTaskFor} 生成。
11
+ */
12
+ export declare function createDefaultTask(type: string, name: string, taskReferenceName: string): TaskDef;
13
+ /** 为 FORK_JOIN / FORK_JOIN_DYNAMIC 生成紧随其后的 JOIN;引用名与 `takenRefs` 不冲突 */
14
+ export declare function createJoinTaskFor(fork: TaskDef, takenRefs?: Set<string>): TaskDef;
15
+ /**
16
+ * 校验引用名改名(E7)。返回 null 表示可以提交,否则返回给用户看的中文原因(说明发生了什么、怎么改)。
17
+ */
18
+ export declare function validateTaskRefName(def: Pick<WorkflowDef, 'tasks'> | null | undefined, newRef: string, currentRef: string): string | null;
19
+ /**
20
+ * 校验 SWITCH / DECISION 的分支名(E14)。`oldName` 为空表示新增分支。
21
+ */
22
+ export declare function validateBranchName(task: TaskDef | null | undefined, newName: string, oldName?: string): string | null;
23
+ /**
24
+ * 删除任务前的影响说明(E13):FORK 与 JOIN 成对删除,容器任务连带删除内部任务,确认文案要讲清楚。
25
+ */
26
+ export declare function describeTaskRemoval(def: Pick<WorkflowDef, 'tasks'> | null | undefined, taskRef: string): {
27
+ message: string;
28
+ removedRefs: string[];
29
+ };
30
+ /**
31
+ * 准备粘贴的任务副本(E15):子树内所有引用名加后缀并保证全局唯一,
32
+ * 子树内部的引用(`${ref.output.x}`、loopCondition 里的 `$.ref`、joinOn 等)同步改名;
33
+ * 指向子树外部任务的引用保持不变。FORK_JOIN / FORK_JOIN_DYNAMIC 同时返回配对 JOIN。
34
+ */
35
+ export declare function prepareTaskForPaste(task: TaskDef, existingRefs: Set<string>, suffix: string): {
36
+ task: TaskDef;
37
+ join: TaskDef | null;
38
+ };
39
+ export declare const TASK_DEFINITION_FIELDS: readonly ["timeoutSeconds", "retryLogic", "retryDelaySeconds", "timeoutPolicy"];
40
+ export type TaskDefinitionField = typeof TASK_DEFINITION_FIELDS[number];
41
+ /** 读取执行控制字段:优先 taskDefinition,回退到旧版写在顶层的值 */
42
+ export declare function readTaskDefinitionField(task: TaskDef, field: TaskDefinitionField): any;
43
+ /**
44
+ * 写入执行控制字段,返回要交给 updateTask 的补丁:
45
+ * 写到 `taskDefinition`,并删除旧版的顶层同名字段;保证 Conductor TaskDef 校验要求的 name 与
46
+ * responseTimeoutSeconds ≤ timeoutSeconds。
47
+ */
48
+ export declare function patchTaskDefinitionField(task: TaskDef, field: TaskDefinitionField, value: any, ownerEmail?: string): Record<string, any>;
49
+ /** 把 JSON 文本解析为对象;失败时返回给用户看的原因 */
50
+ export declare function parseJsonDraft(text: string, opts?: {
51
+ allowEmpty?: boolean;
52
+ requireObject?: boolean;
53
+ }): {
54
+ ok: true;
55
+ value: any;
56
+ } | {
57
+ ok: false;
58
+ error: string;
59
+ };
@@ -7,6 +7,7 @@
7
7
  */
8
8
  export interface TaskTypeMeta {
9
9
  label: string;
10
+ /** CMASTER icon name (see components/icons/iconRegistry.ts), rendered with <CmIcon>. */
10
11
  icon: string;
11
12
  who: string;
12
13
  color: string;
@@ -36,12 +36,19 @@ export declare const TASK_RULES: {
36
36
  level: string;
37
37
  message: string;
38
38
  })[];
39
- INLINE: {
39
+ INLINE: ({
40
40
  field: string;
41
41
  type: string;
42
42
  validate: (_val: any, task: any) => boolean;
43
43
  message: string;
44
- }[];
44
+ level?: undefined;
45
+ } | {
46
+ field: string;
47
+ type: string;
48
+ level: string;
49
+ message: string;
50
+ validate?: undefined;
51
+ })[];
45
52
  LAMBDA: {
46
53
  field: string;
47
54
  type: string;
@@ -93,12 +100,19 @@ export declare const TASK_RULES: {
93
100
  validate: (val: any) => boolean;
94
101
  message: string;
95
102
  }[];
96
- SWITCH: {
103
+ SWITCH: ({
97
104
  field: string;
98
105
  type: string;
99
- validate: (val: any) => boolean;
106
+ validate: (val: any, task: any) => boolean;
100
107
  message: string;
101
- }[];
108
+ level?: undefined;
109
+ } | {
110
+ field: string;
111
+ type: string;
112
+ level: string;
113
+ validate: (val: any, task: any) => boolean;
114
+ message: string;
115
+ })[];
102
116
  FORK_JOIN_DYNAMIC: {
103
117
  field: string;
104
118
  type: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yiyi_zhang/reactflow-ui",
3
- "version": "1.2.0",
3
+ "version": "1.3.1",
4
4
  "description": "Conductor Workflow IDE — Next-Gen AI-Native visual workflow designer with W-LSP data lineage, deterministic in-browser sandbox dry-run, time-travel waterfall debugger, and live split-view sync built with React 19, ReactFlow and Zustand.",
5
5
  "keywords": [
6
6
  "conductor",
@@ -49,7 +49,11 @@
49
49
  "preview": "vite preview",
50
50
  "test": "vitest run",
51
51
  "test:watch": "vitest",
52
- "test:coverage": "vitest run --coverage"
52
+ "test:coverage": "vitest run --coverage",
53
+ "tokens:build": "node scripts/tokens/build.mjs",
54
+ "tokens:check": "node scripts/tokens/build.mjs --check",
55
+ "test:visual": "playwright test",
56
+ "test:visual:update": "playwright test --update-snapshots"
53
57
  },
54
58
  "dependencies": {
55
59
  "dagre": "^0.8.5",