yaml-flow 2.1.0 → 2.2.0

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.
package/README.md CHANGED
@@ -748,6 +748,78 @@ See the [examples/graph-of-graphs/](./examples/graph-of-graphs/) directory for c
748
748
 
749
749
  ---
750
750
 
751
+ ## Execution Plan (Dry Run)
752
+
753
+ Compute the full execution plan from a graph config without running anything — like `terraform plan` for workflows.
754
+
755
+ ```typescript
756
+ import { planExecution } from 'yaml-flow/event-graph';
757
+
758
+ const plan = planExecution(graph);
759
+
760
+ plan.phases; // [['prep'], ['copy'], ['evidence'], ['synthesis'], ['analyze'], ['health', 'report'], ['archive']]
761
+ plan.depth; // 7
762
+ plan.maxParallelism; // 2
763
+ plan.entryPoints; // ['prep']
764
+ plan.leafTasks; // ['archive']
765
+ plan.conflicts; // { 'output-token': ['task-a', 'task-b'] } — multiple producers
766
+ plan.unreachableTokens; // ['human-approval'] — required but no task produces it
767
+ plan.blockedTasks; // ['approve'] — blocked by unreachable tokens
768
+ plan.dependencies; // { 'copy': ['prep'], 'evidence': ['copy'], ... }
769
+ ```
770
+
771
+ ---
772
+
773
+ ## Mermaid Diagrams
774
+
775
+ Generate Mermaid syntax from any config — useful for docs, debugging, and CI reports.
776
+
777
+ ```typescript
778
+ import { graphToMermaid, flowToMermaid } from 'yaml-flow/event-graph';
779
+
780
+ // Event graph → dependency diagram
781
+ console.log(graphToMermaid(graph));
782
+ // graph TD
783
+ // build([build])
784
+ // test[test]
785
+ // deploy[[deploy]]
786
+ // build -->|artifact| test
787
+ // test -->|tested| deploy
788
+
789
+ // Step machine → flowchart
790
+ console.log(flowToMermaid(flow));
791
+ // graph TD
792
+ // START(( ))
793
+ // START --> classify
794
+ // classify -->|billing| handle
795
+ // handle -->|resolved| done
796
+ // done([done: resolved])
797
+ ```
798
+
799
+ Options: `{ direction: 'LR' | 'TD', showTokens: boolean, title: string }`.
800
+ Entry points (no requires) get rounded shapes, leaf tasks get double-bracketed shapes, unreachable deps get warning markers.
801
+
802
+ ---
803
+
804
+ ## Loading & Exporting Graph Configs
805
+
806
+ ```typescript
807
+ import { loadGraphConfig, exportGraphConfig, exportGraphConfigToFile } from 'yaml-flow/event-graph';
808
+
809
+ // Load from file, URL, JSON string, or object (validates automatically)
810
+ const graph = await loadGraphConfig('./pipeline.yaml');
811
+ const graph2 = await loadGraphConfig('https://example.com/graph.json');
812
+
813
+ // Export to string
814
+ const json = exportGraphConfig(graph); // JSON (default)
815
+ const yaml = exportGraphConfig(graph, { format: 'yaml' }); // YAML
816
+
817
+ // Export to file (format auto-detected from extension)
818
+ await exportGraphConfigToFile(graph, './output/pipeline.yaml');
819
+ ```
820
+
821
+ ---
822
+
751
823
  ## Package Exports
752
824
 
753
825
  ```typescript
@@ -761,6 +833,8 @@ import { applyStepResult, checkCircuitBreaker, createInitialState } from 'yaml-f
761
833
  // Event Graph only
762
834
  import { next, apply, applyAll, getCandidateTasks } from 'yaml-flow/event-graph';
763
835
  import { createInitialExecutionState, isExecutionComplete, detectStuckState } from 'yaml-flow/event-graph';
836
+ import { planExecution, graphToMermaid, flowToMermaid } from 'yaml-flow/event-graph';
837
+ import { loadGraphConfig, validateGraphConfig, exportGraphConfig } from 'yaml-flow/event-graph';
764
838
  import { TASK_STATUS, COMPLETION_STRATEGIES, CONFLICT_STRATEGIES } from 'yaml-flow/event-graph';
765
839
 
766
840
  // Stores
@@ -808,6 +882,13 @@ import { FlowEngine, createEngine } from 'yaml-flow'; // aliases for StepMachin
808
882
  | `isExecutionComplete(graph, state)` | Check completion against configured strategy |
809
883
  | `detectStuckState({graph, state, ...})` | Check if execution is stuck |
810
884
  | `addDynamicTask(graph, name, config)` | Immutably add a task to a graph config |
885
+ | `planExecution(graph)` | Dry-run: compute phases, parallelism, conflicts, unreachable tokens |
886
+ | `graphToMermaid(graph, options?)` | Generate Mermaid dependency diagram from an event-graph |
887
+ | `flowToMermaid(flow, options?)` | Generate Mermaid flowchart from a step-machine |
888
+ | `loadGraphConfig(source)` | Load + validate a YAML/JSON/URL graph config |
889
+ | `validateGraphConfig(config)` | Validate a GraphConfig, returns error strings |
890
+ | `exportGraphConfig(config, options?)` | Export a GraphConfig to JSON or YAML string |
891
+ | `exportGraphConfigToFile(config, path)` | Export a GraphConfig to a file |
811
892
 
812
893
  ### Event Types (for `apply()`)
813
894
 
@@ -1,3 +1,5 @@
1
+ import { e as StepFlowConfig } from './types-FZ_eyErS.cjs';
2
+
1
3
  /**
2
4
  * Event Graph — Core Types
3
5
  *
@@ -311,6 +313,131 @@ declare function detectStuckState(params: {
311
313
  completionResult?: CompletionResult;
312
314
  }): StuckDetection;
313
315
 
316
+ /**
317
+ * Event Graph — Execution Plan (Dry Run)
318
+ *
319
+ * Compute the full execution plan from a GraphConfig without running anything.
320
+ * Shows phases (what runs in parallel), dependency edges, and potential issues.
321
+ *
322
+ * Pure function — no I/O, no side effects.
323
+ */
324
+
325
+ interface ExecutionPlan {
326
+ /** Ordered phases — tasks within a phase can run in parallel */
327
+ phases: string[][];
328
+ /** Dependency edges: taskName → tasks it depends on */
329
+ dependencies: Record<string, string[]>;
330
+ /** Tasks that provide conflicts (same output from multiple tasks) */
331
+ conflicts: Record<string, string[]>;
332
+ /** Tasks that have no requires (entry points) */
333
+ entryPoints: string[];
334
+ /** Tasks that nothing depends on (leaf nodes) */
335
+ leafTasks: string[];
336
+ /** Tokens required but not produced by any task */
337
+ unreachableTokens: string[];
338
+ /** Tasks blocked by unreachable tokens */
339
+ blockedTasks: string[];
340
+ /** Total number of phases (depth of the graph) */
341
+ depth: number;
342
+ /** Max parallelism (widest phase) */
343
+ maxParallelism: number;
344
+ }
345
+ /**
346
+ * Compute a full execution plan from a graph config.
347
+ *
348
+ * Shows the order tasks would execute, what can run in parallel,
349
+ * where conflicts exist, and what's unreachable — all without
350
+ * actually running anything.
351
+ *
352
+ * @param graph - The event-graph configuration
353
+ * @returns ExecutionPlan with phases, dependencies, conflicts, and diagnostics
354
+ */
355
+ declare function planExecution(graph: GraphConfig): ExecutionPlan;
356
+
357
+ /**
358
+ * Mermaid Diagram Export
359
+ *
360
+ * Generate Mermaid diagram strings from GraphConfig (event-graph)
361
+ * and StepFlowConfig (step-machine). Useful for documentation,
362
+ * debugging, and CI reports.
363
+ *
364
+ * Pure functions — no I/O, no side effects.
365
+ */
366
+
367
+ interface MermaidOptions {
368
+ /** Diagram direction: TB (top-bottom), LR (left-right), etc. Default: 'TD' */
369
+ direction?: 'TD' | 'TB' | 'LR' | 'RL' | 'BT';
370
+ /** Show token labels on edges. Default: true */
371
+ showTokens?: boolean;
372
+ /** Title comment at top. Default: graph.id or 'Event Graph' */
373
+ title?: string;
374
+ }
375
+ /**
376
+ * Generate a Mermaid dependency graph from an event-graph config.
377
+ *
378
+ * Tasks are nodes. Edges represent token dependencies:
379
+ * if task B requires token X and task A provides X, then A --> B.
380
+ *
381
+ * @param graph - Event graph configuration
382
+ * @param options - Diagram options
383
+ * @returns Mermaid diagram string
384
+ */
385
+ declare function graphToMermaid(graph: GraphConfig, options?: MermaidOptions): string;
386
+ /**
387
+ * Generate a Mermaid flowchart from a step-machine config.
388
+ *
389
+ * Steps are nodes. Transitions are labeled edges.
390
+ * Terminal states are shown as filled/rounded nodes.
391
+ *
392
+ * @param flow - Step machine flow configuration
393
+ * @param options - Diagram options
394
+ * @returns Mermaid diagram string
395
+ */
396
+ declare function flowToMermaid(flow: StepFlowConfig, options?: MermaidOptions): string;
397
+
398
+ /**
399
+ * Event Graph — Loader & Exporter
400
+ *
401
+ * Load GraphConfig from YAML/JSON files or strings, and export back.
402
+ * Mirrors the step-machine's loadStepFlow/validateStepFlowConfig pattern.
403
+ */
404
+
405
+ /**
406
+ * Validate a GraphConfig object. Returns an array of error strings.
407
+ * Empty array = valid config.
408
+ */
409
+ declare function validateGraphConfig(config: unknown): string[];
410
+ /**
411
+ * Load a GraphConfig from a file path, URL, JSON string, or object.
412
+ * Validates the config and throws if invalid.
413
+ *
414
+ * @param source - File path (.yaml/.yml/.json), URL, JSON string, or GraphConfig object
415
+ * @returns Validated GraphConfig
416
+ */
417
+ declare function loadGraphConfig(source: string | GraphConfig): Promise<GraphConfig>;
418
+ interface ExportOptions {
419
+ /** Output format. Default: 'json' */
420
+ format?: 'json' | 'yaml';
421
+ /** Indentation for JSON (default: 2) or YAML */
422
+ indent?: number;
423
+ }
424
+ /**
425
+ * Export a GraphConfig to a JSON or YAML string.
426
+ *
427
+ * @param config - The graph configuration to export
428
+ * @param options - Export format options
429
+ * @returns Serialized config string
430
+ */
431
+ declare function exportGraphConfig(config: GraphConfig, options?: ExportOptions): string;
432
+ /**
433
+ * Export a GraphConfig to a file.
434
+ *
435
+ * @param config - The graph configuration to export
436
+ * @param filePath - Output file path (.json or .yaml/.yml)
437
+ * @param options - Export format options (format auto-detected from extension if not specified)
438
+ */
439
+ declare function exportGraphConfigToFile(config: GraphConfig, filePath: string, options?: ExportOptions): Promise<void>;
440
+
314
441
  /**
315
442
  * Event Graph — Constants
316
443
  */
@@ -327,4 +454,4 @@ declare const DEFAULTS: {
327
454
  readonly MAX_ITERATIONS: 1000;
328
455
  };
329
456
 
330
- export { getRepeatableMax as $, type AgentActionEvent as A, getAllTasks as B, COMPLETION_STRATEGIES as C, DEFAULTS as D, EXECUTION_MODES as E, getCandidateTasks as F, type GraphConfig as G, getProvides as H, type InjectTokensEvent as I, getRequires as J, getTask as K, hasTask as L, isExecutionComplete as M, isNonActiveTask as N, isRepeatableTask as O, isTaskCompleted as P, isTaskRunning as Q, next as R, type SchedulerResult as S, type TaskConfig as T, type RepeatableConfig as U, type TaskCircuitBreakerConfig as V, type TaskMessage as W, type TaskProgressEvent as X, type TaskRetryConfig as Y, addKeyToProvides as Z, addKeyToRequires as _, CONFLICT_STRATEGIES as a, groupTasksByProvides as a0, hasOutputConflict as a1, removeKeyFromProvides as a2, removeKeyFromRequires as a3, type CompletionResult as b, type CompletionStrategy as c, type ConflictStrategy as d, EXECUTION_STATUS as e, type ExecutionConfig as f, type ExecutionMode as g, type ExecutionState as h, type ExecutionStatus as i, type GraphEvent as j, type GraphSettings as k, type StuckDetection as l, TASK_STATUS as m, type TaskCompletedEvent as n, type TaskCreationEvent as o, type TaskFailedEvent as p, type TaskStartedEvent as q, type TaskState as r, type TaskStatus as s, addDynamicTask as t, apply as u, applyAll as v, computeAvailableOutputs as w, createDefaultTaskState as x, createInitialExecutionState as y, detectStuckState as z };
457
+ export { next as $, type AgentActionEvent as A, createInitialExecutionState as B, COMPLETION_STRATEGIES as C, DEFAULTS as D, EXECUTION_MODES as E, detectStuckState as F, type GraphConfig as G, exportGraphConfig as H, type InjectTokensEvent as I, exportGraphConfigToFile as J, flowToMermaid as K, getAllTasks as L, type MermaidOptions as M, getCandidateTasks as N, getProvides as O, getRequires as P, getTask as Q, graphToMermaid as R, type SchedulerResult as S, type TaskConfig as T, hasTask as U, isExecutionComplete as V, isNonActiveTask as W, isRepeatableTask as X, isTaskCompleted as Y, isTaskRunning as Z, loadGraphConfig as _, CONFLICT_STRATEGIES as a, planExecution as a0, validateGraphConfig as a1, type RepeatableConfig as a2, type TaskCircuitBreakerConfig as a3, type TaskMessage as a4, type TaskProgressEvent as a5, type TaskRetryConfig as a6, addKeyToProvides as a7, addKeyToRequires as a8, getRepeatableMax as a9, groupTasksByProvides as aa, hasOutputConflict as ab, removeKeyFromProvides as ac, removeKeyFromRequires as ad, type CompletionResult as b, type CompletionStrategy as c, type ConflictStrategy as d, EXECUTION_STATUS as e, type ExecutionConfig as f, type ExecutionMode as g, type ExecutionPlan as h, type ExecutionState as i, type ExecutionStatus as j, type ExportOptions as k, type GraphEvent as l, type GraphSettings as m, type StuckDetection as n, TASK_STATUS as o, type TaskCompletedEvent as p, type TaskCreationEvent as q, type TaskFailedEvent as r, type TaskStartedEvent as s, type TaskState as t, type TaskStatus as u, addDynamicTask as v, apply as w, applyAll as x, computeAvailableOutputs as y, createDefaultTaskState as z };
@@ -1,3 +1,5 @@
1
+ import { e as StepFlowConfig } from './types-FZ_eyErS.js';
2
+
1
3
  /**
2
4
  * Event Graph — Core Types
3
5
  *
@@ -311,6 +313,131 @@ declare function detectStuckState(params: {
311
313
  completionResult?: CompletionResult;
312
314
  }): StuckDetection;
313
315
 
316
+ /**
317
+ * Event Graph — Execution Plan (Dry Run)
318
+ *
319
+ * Compute the full execution plan from a GraphConfig without running anything.
320
+ * Shows phases (what runs in parallel), dependency edges, and potential issues.
321
+ *
322
+ * Pure function — no I/O, no side effects.
323
+ */
324
+
325
+ interface ExecutionPlan {
326
+ /** Ordered phases — tasks within a phase can run in parallel */
327
+ phases: string[][];
328
+ /** Dependency edges: taskName → tasks it depends on */
329
+ dependencies: Record<string, string[]>;
330
+ /** Tasks that provide conflicts (same output from multiple tasks) */
331
+ conflicts: Record<string, string[]>;
332
+ /** Tasks that have no requires (entry points) */
333
+ entryPoints: string[];
334
+ /** Tasks that nothing depends on (leaf nodes) */
335
+ leafTasks: string[];
336
+ /** Tokens required but not produced by any task */
337
+ unreachableTokens: string[];
338
+ /** Tasks blocked by unreachable tokens */
339
+ blockedTasks: string[];
340
+ /** Total number of phases (depth of the graph) */
341
+ depth: number;
342
+ /** Max parallelism (widest phase) */
343
+ maxParallelism: number;
344
+ }
345
+ /**
346
+ * Compute a full execution plan from a graph config.
347
+ *
348
+ * Shows the order tasks would execute, what can run in parallel,
349
+ * where conflicts exist, and what's unreachable — all without
350
+ * actually running anything.
351
+ *
352
+ * @param graph - The event-graph configuration
353
+ * @returns ExecutionPlan with phases, dependencies, conflicts, and diagnostics
354
+ */
355
+ declare function planExecution(graph: GraphConfig): ExecutionPlan;
356
+
357
+ /**
358
+ * Mermaid Diagram Export
359
+ *
360
+ * Generate Mermaid diagram strings from GraphConfig (event-graph)
361
+ * and StepFlowConfig (step-machine). Useful for documentation,
362
+ * debugging, and CI reports.
363
+ *
364
+ * Pure functions — no I/O, no side effects.
365
+ */
366
+
367
+ interface MermaidOptions {
368
+ /** Diagram direction: TB (top-bottom), LR (left-right), etc. Default: 'TD' */
369
+ direction?: 'TD' | 'TB' | 'LR' | 'RL' | 'BT';
370
+ /** Show token labels on edges. Default: true */
371
+ showTokens?: boolean;
372
+ /** Title comment at top. Default: graph.id or 'Event Graph' */
373
+ title?: string;
374
+ }
375
+ /**
376
+ * Generate a Mermaid dependency graph from an event-graph config.
377
+ *
378
+ * Tasks are nodes. Edges represent token dependencies:
379
+ * if task B requires token X and task A provides X, then A --> B.
380
+ *
381
+ * @param graph - Event graph configuration
382
+ * @param options - Diagram options
383
+ * @returns Mermaid diagram string
384
+ */
385
+ declare function graphToMermaid(graph: GraphConfig, options?: MermaidOptions): string;
386
+ /**
387
+ * Generate a Mermaid flowchart from a step-machine config.
388
+ *
389
+ * Steps are nodes. Transitions are labeled edges.
390
+ * Terminal states are shown as filled/rounded nodes.
391
+ *
392
+ * @param flow - Step machine flow configuration
393
+ * @param options - Diagram options
394
+ * @returns Mermaid diagram string
395
+ */
396
+ declare function flowToMermaid(flow: StepFlowConfig, options?: MermaidOptions): string;
397
+
398
+ /**
399
+ * Event Graph — Loader & Exporter
400
+ *
401
+ * Load GraphConfig from YAML/JSON files or strings, and export back.
402
+ * Mirrors the step-machine's loadStepFlow/validateStepFlowConfig pattern.
403
+ */
404
+
405
+ /**
406
+ * Validate a GraphConfig object. Returns an array of error strings.
407
+ * Empty array = valid config.
408
+ */
409
+ declare function validateGraphConfig(config: unknown): string[];
410
+ /**
411
+ * Load a GraphConfig from a file path, URL, JSON string, or object.
412
+ * Validates the config and throws if invalid.
413
+ *
414
+ * @param source - File path (.yaml/.yml/.json), URL, JSON string, or GraphConfig object
415
+ * @returns Validated GraphConfig
416
+ */
417
+ declare function loadGraphConfig(source: string | GraphConfig): Promise<GraphConfig>;
418
+ interface ExportOptions {
419
+ /** Output format. Default: 'json' */
420
+ format?: 'json' | 'yaml';
421
+ /** Indentation for JSON (default: 2) or YAML */
422
+ indent?: number;
423
+ }
424
+ /**
425
+ * Export a GraphConfig to a JSON or YAML string.
426
+ *
427
+ * @param config - The graph configuration to export
428
+ * @param options - Export format options
429
+ * @returns Serialized config string
430
+ */
431
+ declare function exportGraphConfig(config: GraphConfig, options?: ExportOptions): string;
432
+ /**
433
+ * Export a GraphConfig to a file.
434
+ *
435
+ * @param config - The graph configuration to export
436
+ * @param filePath - Output file path (.json or .yaml/.yml)
437
+ * @param options - Export format options (format auto-detected from extension if not specified)
438
+ */
439
+ declare function exportGraphConfigToFile(config: GraphConfig, filePath: string, options?: ExportOptions): Promise<void>;
440
+
314
441
  /**
315
442
  * Event Graph — Constants
316
443
  */
@@ -327,4 +454,4 @@ declare const DEFAULTS: {
327
454
  readonly MAX_ITERATIONS: 1000;
328
455
  };
329
456
 
330
- export { getRepeatableMax as $, type AgentActionEvent as A, getAllTasks as B, COMPLETION_STRATEGIES as C, DEFAULTS as D, EXECUTION_MODES as E, getCandidateTasks as F, type GraphConfig as G, getProvides as H, type InjectTokensEvent as I, getRequires as J, getTask as K, hasTask as L, isExecutionComplete as M, isNonActiveTask as N, isRepeatableTask as O, isTaskCompleted as P, isTaskRunning as Q, next as R, type SchedulerResult as S, type TaskConfig as T, type RepeatableConfig as U, type TaskCircuitBreakerConfig as V, type TaskMessage as W, type TaskProgressEvent as X, type TaskRetryConfig as Y, addKeyToProvides as Z, addKeyToRequires as _, CONFLICT_STRATEGIES as a, groupTasksByProvides as a0, hasOutputConflict as a1, removeKeyFromProvides as a2, removeKeyFromRequires as a3, type CompletionResult as b, type CompletionStrategy as c, type ConflictStrategy as d, EXECUTION_STATUS as e, type ExecutionConfig as f, type ExecutionMode as g, type ExecutionState as h, type ExecutionStatus as i, type GraphEvent as j, type GraphSettings as k, type StuckDetection as l, TASK_STATUS as m, type TaskCompletedEvent as n, type TaskCreationEvent as o, type TaskFailedEvent as p, type TaskStartedEvent as q, type TaskState as r, type TaskStatus as s, addDynamicTask as t, apply as u, applyAll as v, computeAvailableOutputs as w, createDefaultTaskState as x, createInitialExecutionState as y, detectStuckState as z };
457
+ export { next as $, type AgentActionEvent as A, createInitialExecutionState as B, COMPLETION_STRATEGIES as C, DEFAULTS as D, EXECUTION_MODES as E, detectStuckState as F, type GraphConfig as G, exportGraphConfig as H, type InjectTokensEvent as I, exportGraphConfigToFile as J, flowToMermaid as K, getAllTasks as L, type MermaidOptions as M, getCandidateTasks as N, getProvides as O, getRequires as P, getTask as Q, graphToMermaid as R, type SchedulerResult as S, type TaskConfig as T, hasTask as U, isExecutionComplete as V, isNonActiveTask as W, isRepeatableTask as X, isTaskCompleted as Y, isTaskRunning as Z, loadGraphConfig as _, CONFLICT_STRATEGIES as a, planExecution as a0, validateGraphConfig as a1, type RepeatableConfig as a2, type TaskCircuitBreakerConfig as a3, type TaskMessage as a4, type TaskProgressEvent as a5, type TaskRetryConfig as a6, addKeyToProvides as a7, addKeyToRequires as a8, getRepeatableMax as a9, groupTasksByProvides as aa, hasOutputConflict as ab, removeKeyFromProvides as ac, removeKeyFromRequires as ad, type CompletionResult as b, type CompletionStrategy as c, type ConflictStrategy as d, EXECUTION_STATUS as e, type ExecutionConfig as f, type ExecutionMode as g, type ExecutionPlan as h, type ExecutionState as i, type ExecutionStatus as j, type ExportOptions as k, type GraphEvent as l, type GraphSettings as m, type StuckDetection as n, TASK_STATUS as o, type TaskCompletedEvent as p, type TaskCreationEvent as q, type TaskFailedEvent as r, type TaskStartedEvent as s, type TaskState as t, type TaskStatus as u, addDynamicTask as v, apply as w, applyAll as x, computeAvailableOutputs as y, createDefaultTaskState as z };