@yiyi_zhang/reactflow-ui 1.3.0 → 1.3.2

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 (91) hide show
  1. package/README.md +8 -6
  2. package/dist/AiWorkflowIDE.d.ts +23 -3
  3. package/dist/WorkflowIDE.d.ts +14 -1
  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 +5 -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/UnsavedRunNotice.d.ts +16 -0
  19. package/dist/components/business/ActionPickerModal.d.ts +2 -0
  20. package/dist/components/business/BusinessEditorContext.d.ts +38 -0
  21. package/dist/components/business/DataPillInput.d.ts +10 -0
  22. package/dist/components/business/DecisionBranchCard.d.ts +2 -1
  23. package/dist/components/business/ForkJoinCard.d.ts +2 -1
  24. package/dist/components/business/LibraryVersionBadge.d.ts +1 -1
  25. package/dist/components/business/LoopDoWhileCard.d.ts +2 -1
  26. package/dist/components/business/NestedControlStep.d.ts +7 -1
  27. package/dist/components/business/RunStoryTimeline.d.ts +7 -0
  28. package/dist/components/business/StepCardParts.d.ts +73 -0
  29. package/dist/components/business/StepFlowEditor.d.ts +12 -1
  30. package/dist/components/business/StepListEditor.d.ts +6 -2
  31. package/dist/components/business/deleteMessage.d.ts +6 -0
  32. package/dist/components/business/runStatus.d.ts +11 -0
  33. package/dist/components/icons/CmIcon.d.ts +17 -0
  34. package/dist/components/icons/iconRegistry.d.ts +80 -0
  35. package/dist/components/onboarding/OnboardingController.d.ts +7 -0
  36. package/dist/components/onboarding/PromotionPanel.d.ts +9 -1
  37. package/dist/components/template/quickRunNotice.d.ts +13 -0
  38. package/dist/hooks/useConfirm.d.ts +3 -1
  39. package/dist/hooks/useShortcuts.d.ts +1 -1
  40. package/dist/import/common.d.ts +7 -1
  41. package/dist/import/selection.d.ts +17 -0
  42. package/dist/index.d.ts +5 -2
  43. package/dist/library/versionStatus.d.ts +2 -2
  44. package/dist/logo.svg +9 -36
  45. package/dist/onboarding/naming.d.ts +5 -0
  46. package/dist/onboarding/poll.d.ts +6 -3
  47. package/dist/parser/conductorGenerator.d.ts +17 -2
  48. package/dist/product-launch.html +10 -1394
  49. package/dist/providers/types.d.ts +2 -0
  50. package/dist/reactflow-ui-ai.es.js +18497 -14329
  51. package/dist/reactflow-ui.css +1 -1
  52. package/dist/reactflow-ui.es.js +21578 -15400
  53. package/dist/reactflow-ui.umd.js +183 -41
  54. package/dist/sample-workflows/complex-workflow.json +8 -4
  55. package/dist/sample-workflows/decision-workflow.json +1 -0
  56. package/dist/sample-workflows/ecs-lifecycle-automation.json +37 -4
  57. package/dist/services/ai/agentRunner.d.ts +46 -1
  58. package/dist/services/ai/errorMessages.d.ts +9 -1
  59. package/dist/services/ai/protocolAdapter.d.ts +5 -0
  60. package/dist/services/ai/systemPrompt.d.ts +1 -1
  61. package/dist/services/ai/toolExecutor.d.ts +26 -0
  62. package/dist/services/ai/workflowSynthesizer.d.ts +4 -4
  63. package/dist/services/aiService.d.ts +5 -1
  64. package/dist/stepmodel/compile.d.ts +2 -1
  65. package/dist/stepmodel/factory.d.ts +5 -0
  66. package/dist/stepmodel/pills.d.ts +32 -0
  67. package/dist/stepmodel/types.d.ts +10 -0
  68. package/dist/stepmodel/validate.d.ts +20 -0
  69. package/dist/store/aiStore.d.ts +30 -5
  70. package/dist/store/sandboxRunObserver.d.ts +2 -1
  71. package/dist/store/workflowStore.d.ts +8 -9
  72. package/dist/template/templateStore.d.ts +6 -0
  73. package/dist/template/types.d.ts +1 -0
  74. package/dist/types/conductor.d.ts +25 -1
  75. package/dist/types/workflow.d.ts +38 -3
  76. package/dist/types/workflowLibrary.d.ts +5 -5
  77. package/dist/utils/executionAnalyzer.d.ts +5 -0
  78. package/dist/utils/executionImport.d.ts +52 -0
  79. package/dist/utils/executionPoller.d.ts +37 -0
  80. package/dist/utils/hostSave.d.ts +10 -0
  81. package/dist/utils/localSandboxEngine.d.ts +51 -6
  82. package/dist/utils/runStory.d.ts +20 -0
  83. package/dist/utils/sameWorkflow.d.ts +6 -0
  84. package/dist/utils/sandbox/jq.d.ts +13 -0
  85. package/dist/utils/sandbox/scriptRunner.d.ts +38 -0
  86. package/dist/utils/sandbox/switchHints.d.ts +17 -0
  87. package/dist/utils/statusMeta.d.ts +35 -0
  88. package/dist/utils/taskEditing.d.ts +59 -0
  89. package/dist/utils/taskTypeMeta.d.ts +1 -0
  90. package/dist/utils/validationRules.d.ts +29 -4
  91. 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
  }
@@ -186,6 +186,18 @@ export interface WorkflowState {
186
186
  viewMode: ViewMode;
187
187
  workflowDef: WorkflowDef | null;
188
188
  workflowInstance: WorkflowInstance | null;
189
+ /**
190
+ * R19:运行态展示的实例定义(与编辑中的定义不同时才有值)。
191
+ * 运行实例里的定义只用于渲染运行视图,不会替换编辑中的定义。
192
+ */
193
+ runWorkflowDef: WorkflowDef | null;
194
+ /** R19:运行态展示实例定义期间,暂存的编辑中定义;离开运行态时原样恢复 */
195
+ editWorkflowDefStash: WorkflowDef | null;
196
+ /**
197
+ * R19:最近一次加载或保存时的定义(序列化后),用于判断画布是否有未保存的修改。
198
+ * 为 null 表示 IDE 不知道服务端保存过哪个版本。
199
+ */
200
+ savedWorkflowJson: string | null;
189
201
  nodes: WorkflowNode[];
190
202
  edges: Edge[];
191
203
  taskMap: Record<string, TaskDef>;
@@ -228,6 +240,14 @@ export interface WorkflowState {
228
240
  affectedTasks: string[];
229
241
  timestamp: number;
230
242
  } | null;
243
+ /** 本地沙箱:试运行进行中(脚本在 Web Worker 中异步执行) */
244
+ sandboxRunning: boolean;
245
+ /** 本地沙箱:最近一次需要提示用户的消息(空流程、执行出错),界面显示后调用 clearSandboxNotice */
246
+ sandboxNotice: {
247
+ text: string;
248
+ type: 'error' | 'info';
249
+ timestamp: number;
250
+ } | null;
231
251
  /** 运行态:是否显示底部并发瀑布流与时空回放面板 */
232
252
  showWaterfallPanel: boolean;
233
253
  /** 运行态:时空旅行回放游标时间戳 (ms),为 null 表示展示最终实时态 */
@@ -258,7 +278,10 @@ export interface WorkflowActions {
258
278
  setSelectedTask: (task: TaskDef | null) => void;
259
279
  setSelectedTaskInstance: (instance: TaskInstance | null) => void;
260
280
  checkTaskRefUniqueness: (newRef: string, currentRef: string) => boolean;
281
+ /** 按字段合并更新任务;引用名改成重复 / 非法值时整次更新被拒绝 */
261
282
  updateTask: (taskRef: string, field: string | Record<string, any>, value?: any) => void;
283
+ /** 用新的任务对象整体替换(JSON 面板“应用到画布”使用,删掉的键会真正删除);成功返回 null,失败返回原因 */
284
+ replaceTask: (taskRef: string, nextTask: TaskDef) => string | null;
262
285
  updateWorkflowProperties: (properties: Partial<WorkflowDef>) => void;
263
286
  addNode: (newNode: any, sourceId: string, targetId: string, edgeId: string, edgeData?: any) => void;
264
287
  removeNode: (nodeId: string) => void;
@@ -266,7 +289,8 @@ export interface WorkflowActions {
266
289
  removeLoopTask: (loopRef: string, taskRef: string) => void;
267
290
  addDecisionBranch: (taskRef: string, caseName: string) => void;
268
291
  removeDecisionBranch: (taskRef: string, caseName: string) => void;
269
- renameDecisionBranch: (taskRef: string, oldName: string, newName: string) => void;
292
+ /** 重命名分支;新名称为空、为保留字 default 或与已有分支重名时拒绝并返回 false */
293
+ renameDecisionBranch: (taskRef: string, oldName: string, newName: string) => boolean;
270
294
  addForkBranch: (taskRef: string) => void;
271
295
  copyTask: (task: TaskDef) => void;
272
296
  pasteTask: (task: TaskDef) => void;
@@ -291,10 +315,18 @@ export interface WorkflowActions {
291
315
  setRunState: (state: RunState, execId?: string | null, error?: string | null) => void;
292
316
  /** P4.3: 切回 edit 模式并聚焦到指定任务的指定参数字段 */
293
317
  switchToEditAndFocusParam: (taskRef: string, paramKey?: string) => void;
318
+ /** R19:把定义记为已保存(宿主加载定义、或交给 onSave 后调用);不传时取编辑中的定义 */
319
+ markWorkflowSaved: (def?: WorkflowDef | null) => void;
320
+ /** R19:编辑中的定义(运行态展示实例定义时取暂存的编辑定义)。保存、导出、宿主读取都用它 */
321
+ getEditingWorkflowDef: () => WorkflowDef | null;
322
+ /** R19:当前定义与最近一次加载 / 保存的版本不同(或从未记录过保存版本)时返回 true */
323
+ hasUnsavedChanges: () => boolean;
294
324
  /** W-LSP: 切换数据血缘飞线叠加显示 */
295
325
  setShowDataLineage: (show: boolean) => void;
296
326
  /** W-LSP: 清除重构提示文案 */
297
327
  clearRefactorNotice: () => void;
328
+ /** 本地沙箱:清除提示消息 */
329
+ clearSandboxNotice: () => void;
298
330
  /** 运行态:切换底部并发瀑布流面板 */
299
331
  setShowWaterfallPanel: (show: boolean) => void;
300
332
  /** 运行态:设置时空旅行时间戳 */
@@ -303,8 +335,11 @@ export interface WorkflowActions {
303
335
  setLoopIteration: (loopRef: string, iteration: number) => void;
304
336
  /** AI 共驾:打开/关闭画布原位 Cmd+K 浮窗 */
305
337
  setInlineCopilotTaskRef: (taskRef: string | null) => void;
306
- /** 本地沙箱:在浏览器内执行零延迟确定性试运行并进入调试视图 */
307
- runLocalSandboxDryRun: (mockInput?: Record<string, any>, taskMocks?: Record<string, any>, maxLoopIterations?: number) => void;
338
+ /**
339
+ * 本地沙箱:在浏览器内试运行并进入运行视图。INLINE / JQ / SWITCH / DO_WHILE 等无外部依赖的任务真实执行,
340
+ * 调用外部系统的任务使用模拟数据。脚本在隔离的 Web Worker 中运行,因此是异步的。
341
+ */
342
+ runLocalSandboxDryRun: (mockInput?: Record<string, any>, taskMocks?: Record<string, any>, maxLoopIterations?: number) => Promise<void>;
308
343
  }
309
344
  /**
310
345
  * 重启选项
@@ -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;
@@ -0,0 +1,10 @@
1
+ import type { WorkflowDef } from '../types/conductor';
2
+ /** 宿主保存回调:同步保存返回 void;异步保存返回 Promise,resolve 才算保存成功 */
3
+ export type HostSaveHandler = (def: WorkflowDef) => void | PromiseLike<unknown>;
4
+ /**
5
+ * R19:把定义交给宿主保存,并在保存成功后把它记为已保存的版本(执行验证运行的就是这一份)。
6
+ * - 宿主同步返回:交出即视为已保存(沿用原来的语义)。
7
+ * - 宿主返回 Promise:resolve 后才标记;reject 时保持"有未保存的修改",执行面板继续提示。
8
+ * reject 不在这里吞掉,宿主没处理的错误仍会像以前一样出现在控制台。
9
+ */
10
+ export declare function handOffSave(onSave: HostSaveHandler, def: WorkflowDef): void;
@@ -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,64 @@ 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;
61
+ /** set by a TERMINATE task: the workflow ends with this status, reason and output (Conductor semantics) */
62
+ termination: {
63
+ status: 'COMPLETED' | 'FAILED' | 'TERMINATED';
64
+ reason: string;
65
+ output: Record<string, any>;
66
+ } | null;
32
67
  }
33
68
  /**
34
- * Resolve Conductor `${...}` expressions against current sandbox context
69
+ * Resolve Conductor `${...}` expressions against current sandbox context.
70
+ * References that cannot be resolved stay as written and are added to `misses` when given.
35
71
  */
36
- export declare function resolveExpressionValue(val: any, ctx: SandboxRuntimeContext): any;
72
+ export declare function resolveExpressionValue(val: any, ctx: SandboxRuntimeContext, misses?: string[]): any;
37
73
  /**
38
- * Generate default synthetic output for a given task (used both at runtime and as UI template preview)
74
+ * Default output shown for a task as a starting point for a custom mock (also what mocked tasks return).
39
75
  */
40
76
  export declare function generateDefaultTaskOutputPreview(task: WorkflowTask, resolvedInput?: Record<string, any>, iteration?: number): Record<string, any>;
41
77
  /**
42
- * Build default mock input from workflowDef.inputParameters and auto-discovered ${workflow.input.*} references
78
+ * Build mock workflow input: declared input parameters plus every `${workflow.input.<field>}` the tasks reference.
79
+ * S13: declared parameters take their type, example and default from `inputSchema` / `inputTemplate`
80
+ * (`parseWorkflowInputParams`), so a number parameter gets a number, not a `sample_x` string.
43
81
  */
44
82
  export declare function buildDefaultWorkflowMockInput(workflowDef: WorkflowDef): Record<string, any>;
45
83
  /**
46
- * Execute an entire WorkflowDef in-browser deterministically and return a complete WorkflowInstance
84
+ * Run a WorkflowDef in the browser and return a complete WorkflowInstance.
85
+ * Scripts (INLINE, javascript SWITCH / DECISION, DO_WHILE conditions) run in an isolated Web Worker.
86
+ */
87
+ export declare function executeLocalSandboxDryRunAsync(workflowDef: WorkflowDef, options?: SandboxAsyncOptions): Promise<WorkflowInstance>;
88
+ /**
89
+ * Synchronous variant kept for existing hosts. It does not run scripts: INLINE tasks are SKIPPED with
90
+ * `sandboxExecution: 'not_executed'`, javascript conditions take the default branch with a warning, and DO_WHILE runs
91
+ * `maxLoopIterations` iterations (default 2). Prefer `executeLocalSandboxDryRunAsync`.
47
92
  */
48
93
  export declare function executeLocalSandboxDryRun(workflowDef: WorkflowDef, options?: SandboxDryRunOptions): WorkflowInstance;
49
94
  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,6 @@
1
+ import type { WorkflowDef } from '../types/conductor';
2
+ /**
3
+ * R21:两份定义内容是否相同(同一对象,或序列化后完全一致)。
4
+ * 用于识别受控用法下宿主把 onWorkflowChange 的结果原样回写成 workflowDef prop 的情况。
5
+ */
6
+ export declare function isSameWorkflow(a: WorkflowDef | null | undefined, b: WorkflowDef | null | undefined): boolean;
@@ -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,38 @@
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 (S10):
6
+ * - it runs in a Web Worker started from a hidden sandboxed iframe (opaque origin) whose Content-Security-Policy is
7
+ * `default-src 'none'`. The worker inherits that policy, so `import()`, `FontFace`, `fetch`, WebSocket and the like
8
+ * cannot reach the network whatever globals the script finds;
9
+ * - network, storage and messaging globals are also removed inside the worker (defence in depth);
10
+ * - every evaluation gets a fresh worker, so one script cannot see or change another script's input or result;
11
+ * - a script that exceeds its time budget is stopped (an infinite loop cannot freeze the IDE).
12
+ */
13
+ export type ScriptResult = {
14
+ ok: true;
15
+ value: unknown;
16
+ } | {
17
+ ok: false;
18
+ error: string;
19
+ notExecuted?: boolean;
20
+ };
21
+ /** Evaluate `expression` with `$` bound to `input`; the value of the last expression statement is the result. */
22
+ export type ScriptEvaluator = (expression: string, input: Record<string, unknown>) => Promise<ScriptResult>;
23
+ export interface WorkerScriptEvaluator {
24
+ evaluate: ScriptEvaluator;
25
+ /** Stop the sandbox. Further calls start a new one. */
26
+ dispose: () => void;
27
+ }
28
+ export declare const DEFAULT_SCRIPT_TIMEOUT_MS = 2000;
29
+ /**
30
+ * Create an evaluator backed by the sandbox described at the top of this file.
31
+ * Reports `notExecuted` when the page cannot host it (no DOM or Web Worker API, or a CSP that forbids the sandbox),
32
+ * so the sandbox can say why a script did not run instead of guessing a result.
33
+ */
34
+ export declare function createWorkerScriptEvaluator(options?: {
35
+ timeoutMs?: number;
36
+ }): WorkerScriptEvaluator;
37
+ /** Evaluator used by the synchronous API: never runs scripts, says so. */
38
+ export declare const notExecutedEvaluator: (expression: string) => ScriptResult;
@@ -0,0 +1,17 @@
1
+ import type { TaskDef } from '../../types/conductor';
2
+ export interface SwitchRoutingHint {
3
+ switchRef: string;
4
+ switchName: string;
5
+ /** `workflow.input` 字段名:判断取值直接来自这个入参时,改入参就能切换分支 */
6
+ inputField: string | null;
7
+ /** 判断方式:按入参取值,或按脚本(只能在配置台强制指定分支) */
8
+ evaluator: 'value-param' | 'javascript';
9
+ cases: string[];
10
+ }
11
+ /**
12
+ * S14:沙箱配置台的「条件分支快速路由」提示,按引擎选择分支的同一套规则识别判断依据:
13
+ * - SWITCH value-param:`expression` 是参数名,取值在 `inputParameters[expression]`(兼容旧写法 `caseValueParam`)
14
+ * - DECISION:`caseValueParam` 是参数名;有 `caseExpression` 时按脚本判断
15
+ * - javascript / graaljs:按脚本判断,没有可直接切换的入参
16
+ */
17
+ export declare function getSwitchRoutingHint(task: TaskDef): SwitchRoutingHint | null;
@@ -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
- validate: (_val: any, task: any) => boolean;
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;
@@ -63,6 +70,24 @@ export declare const TASK_RULES: {
63
70
  validate: (_val: any, task: any) => boolean;
64
71
  message: string;
65
72
  }[];
73
+ KAFKA_PUBLISH: {
74
+ field: string;
75
+ type: string;
76
+ validate: (val: any) => boolean;
77
+ message: string;
78
+ }[];
79
+ EVENT: {
80
+ field: string;
81
+ type: string;
82
+ validate: (val: any) => boolean;
83
+ message: string;
84
+ }[];
85
+ WAIT: {
86
+ field: string;
87
+ type: string;
88
+ validate: (val: any, task: any) => boolean;
89
+ message: string;
90
+ }[];
66
91
  DYNAMIC: {
67
92
  field: string;
68
93
  type: string;
@@ -96,7 +121,7 @@ export declare const TASK_RULES: {
96
121
  SWITCH: {
97
122
  field: string;
98
123
  type: string;
99
- validate: (val: any) => boolean;
124
+ validate: (val: any, task: any) => boolean;
100
125
  message: string;
101
126
  }[];
102
127
  FORK_JOIN_DYNAMIC: {