yaml-flow 2.2.0 → 2.4.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
@@ -801,6 +801,188 @@ Entry points (no requires) get rounded shapes, leaf tasks get double-bracketed s
801
801
 
802
802
  ---
803
803
 
804
+ ## Graph Validation (Semantic)
805
+
806
+ Validate the logical correctness of a graph — catches issues that structural validation (`validateGraphConfig`) can't.
807
+
808
+ ```typescript
809
+ import { validateGraph } from 'yaml-flow/event-graph';
810
+
811
+ const result = validateGraph(graph);
812
+
813
+ result.valid; // true if no errors (warnings/info allowed)
814
+ result.errors; // issues that will break execution
815
+ result.warnings; // issues that may cause unexpected behavior
816
+ result.issues; // all issues (errors + warnings + info)
817
+
818
+ // Each issue
819
+ result.issues[0].severity; // 'error' | 'warning' | 'info'
820
+ result.issues[0].code; // e.g. 'CIRCULAR_DEPENDENCY'
821
+ result.issues[0].message; // human-readable description
822
+ result.issues[0].tasks; // affected task names
823
+ result.issues[0].tokens; // affected tokens
824
+ ```
825
+
826
+ | Issue Code | Severity | Description |
827
+ |---|---|---|
828
+ | `EMPTY_GRAPH` | error | Graph has no tasks |
829
+ | `DANGLING_REQUIRES` | error | Task requires a token that no task produces |
830
+ | `CIRCULAR_DEPENDENCY` | error | Cycle detected in task dependencies |
831
+ | `SELF_DEPENDENCY` | error | Task requires a token it provides itself |
832
+ | `UNREACHABLE_GOAL` | error | Goal token cannot be produced by any task |
833
+ | `MISSING_GOAL` | error | `goal-reached` strategy without goal array |
834
+ | `PROVIDE_CONFLICT` | warning | Multiple tasks produce the same token |
835
+ | `DEAD_END_TASK` | warning | Task has no provides — can't unblock downstream |
836
+ | `ISOLATED_TASK` | info | Disconnected task with no requires or dependents |
837
+
838
+ Use `validateGraphConfig()` for structural checks (JSON shape) and `validateGraph()` for semantic checks (logical correctness). Both are pure functions.
839
+
840
+ ---
841
+
842
+ ## Continuous Event Graph
843
+
844
+ A **long-lived, evolving** event-graph where both the graph config and execution state mutate over time. Ideal for dashboards, monitoring systems, and any scenario where the workflow has no fixed endpoint.
845
+
846
+ The core type is `LiveGraph` — it bundles `config` + `state` so they can't get out of sync. Every function is pure: `f(LiveGraph, input) → LiveGraph`.
847
+
848
+ ```typescript
849
+ import {
850
+ createLiveGraph, applyEvent,
851
+ addNode, removeNode,
852
+ addRequires, removeRequires, addProvides, removeProvides,
853
+ injectTokens, drainTokens,
854
+ schedule, inspect,
855
+ resetNode, disableNode, enableNode, getNode,
856
+ snapshot, restore,
857
+ getUnreachableTokens, getUnreachableNodes,
858
+ getUpstream, getDownstream,
859
+ } from 'yaml-flow/continuous-event-graph';
860
+ ```
861
+
862
+ ### Quick Start
863
+
864
+ ```typescript
865
+ import { createLiveGraph, applyEvent, addNode, schedule, inspect } from 'yaml-flow/continuous-event-graph';
866
+
867
+ // 1. Bootstrap
868
+ let live = createLiveGraph({
869
+ settings: { completion: 'manual' },
870
+ tasks: {
871
+ fetch_prices: { provides: ['price-data'] },
872
+ compute: { requires: ['price-data'], provides: ['indicators'] },
873
+ },
874
+ });
875
+
876
+ // 2. Schedule — what's ready?
877
+ schedule(live).eligible; // ['fetch_prices']
878
+
879
+ // 3. Apply events — immutable state transitions
880
+ live = applyEvent(live, { type: 'task-started', taskName: 'fetch_prices', timestamp: new Date().toISOString() });
881
+ live = applyEvent(live, { type: 'task-completed', taskName: 'fetch_prices', timestamp: new Date().toISOString() });
882
+ schedule(live).eligible; // ['compute']
883
+
884
+ // 4. Evolve — add a node at runtime
885
+ live = addNode(live, 'alert', { requires: ['indicators'], provides: ['alert-sent'] });
886
+
887
+ // 5. Health check
888
+ inspect(live); // { totalNodes: 3, running: 0, completed: 1, ... }
889
+ ```
890
+
891
+ ### Graph Mutations
892
+
893
+ | Function | Description |
894
+ |---|---|
895
+ | `addNode(live, name, config)` | Add a task to the graph (config + state) |
896
+ | `removeNode(live, name)` | Remove a task from the graph |
897
+ | `addRequires(live, node, tokens)` | Add requires tokens to a node |
898
+ | `removeRequires(live, node, tokens)` | Remove requires tokens from a node |
899
+ | `addProvides(live, node, tokens)` | Add provides tokens to a node |
900
+ | `removeProvides(live, node, tokens)` | Remove provides tokens from a node |
901
+
902
+ ### Token Management
903
+
904
+ ```typescript
905
+ // Inject external data/signals
906
+ live = injectTokens(live, ['market-open', 'price-data']);
907
+
908
+ // Drain stale/expired tokens
909
+ live = drainTokens(live, ['price-data']); // forces re-fetch before downstream can run
910
+ ```
911
+
912
+ ### Node Lifecycle
913
+
914
+ | Function | Description |
915
+ |---|---|
916
+ | `resetNode(live, name)` | Reset a node to `not-started` (for retry) |
917
+ | `disableNode(live, name)` | Set a node to `inactivated` (scheduler skips it) |
918
+ | `enableNode(live, name)` | Re-enable a disabled node |
919
+ | `getNode(live, name)` | Get config + state for a single node |
920
+
921
+ ### Graph Traversal
922
+
923
+ ```typescript
924
+ // "What feeds into generate_signals?"
925
+ const upstream = getUpstream(live, 'generate_signals');
926
+ upstream.nodes; // [{ nodeName: 'fetch_prices', providesTokens: ['price-data'] }, ...]
927
+ upstream.tokens; // ['price-data', 'indicators', ...]
928
+
929
+ // "What breaks if fetch_prices goes down?"
930
+ const downstream = getDownstream(live, 'fetch_prices');
931
+ downstream.nodes; // [{ nodeName: 'compute', requiresTokens: ['price-data'] }, ...]
932
+ downstream.tokens; // ['price-data', 'indicators', ...]
933
+ ```
934
+
935
+ ### Reachability Analysis
936
+
937
+ ```typescript
938
+ // Tokens that can never be produced given the current state
939
+ const unreachableTokens = getUnreachableTokens(live);
940
+ unreachableTokens.tokens; // [{ token: 'ghost', reason: 'no-producer', producers: [] }]
941
+
942
+ // Nodes that can never become eligible
943
+ const unreachableNodes = getUnreachableNodes(live);
944
+ unreachableNodes.nodes; // [{ nodeName: 'orphan', missingTokens: ['ghost'] }]
945
+ ```
946
+
947
+ ### Persistence
948
+
949
+ ```typescript
950
+ // Save
951
+ const snap = snapshot(live); // JSON-safe object
952
+ localStorage.setItem('graph', JSON.stringify(snap));
953
+
954
+ // Restore
955
+ const data = JSON.parse(localStorage.getItem('graph')!);
956
+ const restored = restore(data); // → LiveGraph (validates shape)
957
+ ```
958
+
959
+ ### Continuous Event Graph API Reference
960
+
961
+ | Function | Description |
962
+ |---|---|
963
+ | `createLiveGraph(config, id?)` | Bootstrap a LiveGraph from a GraphConfig |
964
+ | `applyEvent(live, event)` | Apply an execution event (task-started, task-completed, etc.) |
965
+ | `addNode(live, name, config)` | Add a node (both config + state) |
966
+ | `removeNode(live, name)` | Remove a node |
967
+ | `addRequires / removeRequires` | Wire/unwire requires tokens |
968
+ | `addProvides / removeProvides` | Wire/unwire provides tokens |
969
+ | `injectTokens(live, tokens)` | Add tokens to available outputs |
970
+ | `drainTokens(live, tokens)` | Remove tokens from available outputs |
971
+ | `schedule(live)` | Classify tasks: eligible / pending / unresolved / blocked / conflicts |
972
+ | `inspect(live)` | Health report: statuses, cycles, open deps, conflicts |
973
+ | `resetNode(live, name)` | Reset node to not-started |
974
+ | `disableNode(live, name)` | Disable a node (inactivated) |
975
+ | `enableNode(live, name)` | Re-enable a disabled node |
976
+ | `getNode(live, name)` | Get a node's config + state |
977
+ | `getUpstream(live, name)` | Transitive upstream: what feeds into this node? |
978
+ | `getDownstream(live, name)` | Transitive downstream: what depends on this node? |
979
+ | `getUnreachableTokens(live)` | Tokens that can never be produced |
980
+ | `getUnreachableNodes(live)` | Nodes that can never become eligible |
981
+ | `snapshot(live)` | Serialize to a JSON-safe snapshot |
982
+ | `restore(data)` | Restore a LiveGraph from a snapshot |
983
+
984
+ ---
985
+
804
986
  ## Loading & Exporting Graph Configs
805
987
 
806
988
  ```typescript
@@ -835,6 +1017,7 @@ import { next, apply, applyAll, getCandidateTasks } from 'yaml-flow/event-graph'
835
1017
  import { createInitialExecutionState, isExecutionComplete, detectStuckState } from 'yaml-flow/event-graph';
836
1018
  import { planExecution, graphToMermaid, flowToMermaid } from 'yaml-flow/event-graph';
837
1019
  import { loadGraphConfig, validateGraphConfig, exportGraphConfig } from 'yaml-flow/event-graph';
1020
+ import { validateGraph } from 'yaml-flow/event-graph';
838
1021
  import { TASK_STATUS, COMPLETION_STRATEGIES, CONFLICT_STRATEGIES } from 'yaml-flow/event-graph';
839
1022
 
840
1023
  // Stores
@@ -847,6 +1030,17 @@ import type { BatchOptions, BatchResult, BatchItemResult, BatchProgress } from '
847
1030
  // Config utilities
848
1031
  import { resolveVariables, resolveConfigTemplates } from 'yaml-flow/config';
849
1032
 
1033
+ // Continuous Event Graph (long-lived evolving workflows)
1034
+ import {
1035
+ createLiveGraph, applyEvent, addNode, removeNode,
1036
+ addRequires, removeRequires, addProvides, removeProvides,
1037
+ injectTokens, drainTokens, schedule, inspect,
1038
+ resetNode, disableNode, enableNode, getNode,
1039
+ snapshot, restore,
1040
+ getUnreachableTokens, getUnreachableNodes,
1041
+ getUpstream, getDownstream,
1042
+ } from 'yaml-flow/continuous-event-graph';
1043
+
850
1044
  // Backward compatibility (v1 names → v2)
851
1045
  import { FlowEngine, createEngine } from 'yaml-flow'; // aliases for StepMachine, createStepMachine
852
1046
  ```
@@ -889,6 +1083,7 @@ import { FlowEngine, createEngine } from 'yaml-flow'; // aliases for StepMachin
889
1083
  | `validateGraphConfig(config)` | Validate a GraphConfig, returns error strings |
890
1084
  | `exportGraphConfig(config, options?)` | Export a GraphConfig to JSON or YAML string |
891
1085
  | `exportGraphConfigToFile(config, path)` | Export a GraphConfig to a file |
1086
+ | `validateGraph(graph)` | Semantic validation: cycles, dangling requires, unreachable goals, conflicts |
892
1087
 
893
1088
  ### Event Types (for `apply()`)
894
1089
 
@@ -917,6 +1112,7 @@ See the [examples/](./examples) directory:
917
1112
  | [Batch Tickets](./examples/batch/batch-step-machine.ts) | Batch | Concurrent processing, progress tracking |
918
1113
  | [URL Pipeline](./examples/graph-of-graphs/url-processing-pipeline.ts) | Graph-of-Graphs | Outer event-graph → batch × inner event-graph per item |
919
1114
  | [Multi-Stage ETL](./examples/graph-of-graphs/multi-stage-etl.ts) | Graph-of-Graphs | Mixed modes: event-graph outer → step-machine + event-graph subs |
1115
+ | [Stock Dashboard](./examples/continuous-event-graph/stock-dashboard.ts) | Continuous Event Graph | Runtime mutations, token drain, upstream/downstream, snapshot |
920
1116
  | [Order Processing](./examples/flows/order-processing.yaml) | Step Machine | YAML flow definition |
921
1117
  | [Browser Demo](./examples/browser/index.html) | Step Machine | In-browser usage |
922
1118
 
@@ -1,191 +1,6 @@
1
+ import { G as GraphConfig, c as ExecutionState, S as SchedulerResult, e as GraphEvent, T as TaskConfig, l as TaskState, g as StuckDetection, C as CompletionStrategy, a as ConflictStrategy, b as ExecutionMode, d as ExecutionStatus, m as TaskStatus } from './types-CTu8RqY0.cjs';
1
2
  import { e as StepFlowConfig } from './types-FZ_eyErS.cjs';
2
3
 
3
- /**
4
- * Event Graph — Core Types
5
- *
6
- * Type definitions for the stateless event-graph engine.
7
- * Pure: f(state, event) → newState
8
- */
9
- interface GraphConfig {
10
- id?: string;
11
- settings: GraphSettings;
12
- tasks: Record<string, TaskConfig>;
13
- }
14
- interface GraphSettings {
15
- /** Completion strategy */
16
- completion: CompletionStrategy;
17
- /** Conflict resolution strategy */
18
- conflict_strategy?: ConflictStrategy;
19
- /** Execution mode */
20
- execution_mode?: ExecutionMode;
21
- /** Goal outputs — used with 'goal-reached' completion */
22
- goal?: string[];
23
- /** Max total scheduler iterations (safety limit, default: 1000) */
24
- max_iterations?: number;
25
- /** Timeout in ms (declared for drivers, not enforced by pure engine) */
26
- timeout_ms?: number;
27
- }
28
- interface TaskConfig {
29
- /** What this task needs to become eligible */
30
- requires?: string[];
31
- /** What this task produces on successful completion */
32
- provides: string[];
33
- /** Conditional provides based on handler result */
34
- on?: Record<string, string[]>;
35
- /** Tokens to inject into available outputs on failure */
36
- on_failure?: string[];
37
- /** Task execution method (informational — driver concern) */
38
- method?: string;
39
- /** Arbitrary task configuration (driver concern) */
40
- config?: Record<string, unknown>;
41
- /** Task priority (higher = preferred in conflict resolution) */
42
- priority?: number;
43
- /** Estimated duration in ms (used by duration-first strategy) */
44
- estimatedDuration?: number;
45
- /** Estimated cost (used by cost-optimized strategy) */
46
- estimatedCost?: number;
47
- /** Resource requirements (used by resource-aware strategy) */
48
- estimatedResources?: Record<string, number>;
49
- /** Retry configuration */
50
- retry?: TaskRetryConfig;
51
- /** Repeatable task configuration */
52
- repeatable?: boolean | RepeatableConfig;
53
- /** Circuit breaker: max executions before breaking */
54
- circuit_breaker?: TaskCircuitBreakerConfig;
55
- /** Description */
56
- description?: string;
57
- }
58
- interface TaskRetryConfig {
59
- max_attempts: number;
60
- delay_ms?: number;
61
- backoff_multiplier?: number;
62
- }
63
- interface RepeatableConfig {
64
- /** Max times this task can repeat (undefined = unlimited) */
65
- max?: number;
66
- }
67
- interface TaskCircuitBreakerConfig {
68
- /** Max executions before injecting break tokens */
69
- max_executions: number;
70
- /** Tokens to inject when breaker trips */
71
- on_break: string[];
72
- }
73
- interface ExecutionState {
74
- /** Current status of the execution */
75
- status: ExecutionStatus;
76
- /** Task states keyed by task name */
77
- tasks: Record<string, TaskState>;
78
- /** Tokens currently available in the system */
79
- availableOutputs: string[];
80
- /** Stuck detection result */
81
- stuckDetection: StuckDetection;
82
- /** Last update timestamp */
83
- lastUpdated: string;
84
- /** Execution ID for this run */
85
- executionId: string | null;
86
- /** Execution configuration */
87
- executionConfig: ExecutionConfig;
88
- }
89
- interface ExecutionConfig {
90
- executionMode: ExecutionMode;
91
- conflictStrategy: ConflictStrategy;
92
- completionStrategy: CompletionStrategy;
93
- }
94
- interface TaskState {
95
- status: TaskStatus;
96
- executionCount: number;
97
- retryCount: number;
98
- lastEpoch: number;
99
- startedAt?: string;
100
- completedAt?: string;
101
- failedAt?: string;
102
- lastUpdated?: string;
103
- error?: string;
104
- messages?: TaskMessage[];
105
- progress?: number | null;
106
- }
107
- interface TaskMessage {
108
- message: string;
109
- timestamp: string;
110
- status: string;
111
- }
112
- interface StuckDetection {
113
- is_stuck: boolean;
114
- stuck_description: string | null;
115
- outputs_unresolvable: string[];
116
- tasks_blocked: string[];
117
- }
118
- type GraphEvent = TaskStartedEvent | TaskCompletedEvent | TaskFailedEvent | TaskProgressEvent | InjectTokensEvent | AgentActionEvent | TaskCreationEvent;
119
- interface TaskStartedEvent {
120
- type: 'task-started';
121
- taskName: string;
122
- timestamp: string;
123
- executionId?: string;
124
- }
125
- interface TaskCompletedEvent {
126
- type: 'task-completed';
127
- taskName: string;
128
- /** Handler result key — used for conditional routing via `on` */
129
- result?: string;
130
- /** Data payload from task execution */
131
- data?: Record<string, unknown>;
132
- timestamp: string;
133
- executionId?: string;
134
- }
135
- interface TaskFailedEvent {
136
- type: 'task-failed';
137
- taskName: string;
138
- error: string;
139
- timestamp: string;
140
- executionId?: string;
141
- }
142
- interface TaskProgressEvent {
143
- type: 'task-progress';
144
- taskName: string;
145
- message?: string;
146
- progress?: number;
147
- timestamp: string;
148
- executionId?: string;
149
- }
150
- interface InjectTokensEvent {
151
- type: 'inject-tokens';
152
- tokens: string[];
153
- timestamp: string;
154
- }
155
- interface AgentActionEvent {
156
- type: 'agent-action';
157
- action: 'start' | 'stop' | 'pause' | 'resume';
158
- timestamp: string;
159
- config?: Partial<ExecutionConfig>;
160
- }
161
- interface TaskCreationEvent {
162
- type: 'task-creation';
163
- taskName: string;
164
- taskConfig: TaskConfig;
165
- timestamp: string;
166
- }
167
- interface SchedulerResult {
168
- /** Tasks eligible for execution */
169
- eligibleTasks: string[];
170
- /** Whether the graph execution is complete */
171
- isComplete: boolean;
172
- /** Stuck detection result */
173
- stuckDetection: StuckDetection;
174
- /** Whether conflicts were detected */
175
- hasConflicts: boolean;
176
- /** Conflict groups: output → competing task names */
177
- conflicts: Record<string, string[]>;
178
- /** Strategy used for conflict resolution */
179
- strategy: ConflictStrategy;
180
- /** Processing log for diagnostics */
181
- processingLog: string[];
182
- }
183
- type TaskStatus = 'not-started' | 'running' | 'completed' | 'failed' | 'inactivated';
184
- type ExecutionStatus = 'created' | 'running' | 'paused' | 'stopped' | 'completed' | 'failed';
185
- type CompletionStrategy = 'all-tasks-done' | 'all-outputs-done' | 'only-resolved' | 'goal-reached' | 'manual';
186
- type ExecutionMode = 'dependency-mode' | 'eligibility-mode';
187
- type ConflictStrategy = 'alphabetical' | 'priority-first' | 'duration-first' | 'cost-optimized' | 'resource-aware' | 'random-select' | 'user-choice' | 'parallel-all' | 'skip-conflicts' | 'round-robin';
188
-
189
4
  /**
190
5
  * Event Graph — Scheduler
191
6
  *
@@ -438,6 +253,56 @@ declare function exportGraphConfig(config: GraphConfig, options?: ExportOptions)
438
253
  */
439
254
  declare function exportGraphConfigToFile(config: GraphConfig, filePath: string, options?: ExportOptions): Promise<void>;
440
255
 
256
+ /**
257
+ * Event Graph — Semantic Graph Validation
258
+ *
259
+ * Validates the logical correctness of a static graph configuration.
260
+ * Unlike validateGraphConfig() which checks JSON structure, this checks:
261
+ * - Dangling requires (tokens no task produces)
262
+ * - Circular dependencies
263
+ * - Provide conflicts (multiple tasks producing same token)
264
+ * - Unreachable goal tokens
265
+ * - Dead-end tasks (no provides)
266
+ * - Self-dependencies
267
+ * - Orphaned tasks (disconnected from the graph)
268
+ *
269
+ * Pure function — config in, diagnostics out.
270
+ */
271
+
272
+ type IssueSeverity = 'error' | 'warning' | 'info';
273
+ interface GraphIssue {
274
+ /** Severity: error = will break execution, warning = may cause problems, info = notable */
275
+ severity: IssueSeverity;
276
+ /** Machine-readable issue code */
277
+ code: string;
278
+ /** Human-readable description */
279
+ message: string;
280
+ /** Affected task names (if applicable) */
281
+ tasks?: string[];
282
+ /** Affected tokens (if applicable) */
283
+ tokens?: string[];
284
+ }
285
+ interface GraphValidationResult {
286
+ /** true if no errors (warnings/info are allowed) */
287
+ valid: boolean;
288
+ /** All issues found */
289
+ issues: GraphIssue[];
290
+ /** Just the errors */
291
+ errors: GraphIssue[];
292
+ /** Just the warnings */
293
+ warnings: GraphIssue[];
294
+ }
295
+ /**
296
+ * Validate the semantic correctness of a static event-graph configuration.
297
+ *
298
+ * Checks for logical issues that would cause execution failures, stuck states,
299
+ * or unexpected behavior. Does NOT check JSON structure (use validateGraphConfig for that).
300
+ *
301
+ * @param graph - The event-graph configuration to validate
302
+ * @returns Validation result with categorized issues
303
+ */
304
+ declare function validateGraph(graph: GraphConfig): GraphValidationResult;
305
+
441
306
  /**
442
307
  * Event Graph — Constants
443
308
  */
@@ -454,4 +319,4 @@ declare const DEFAULTS: {
454
319
  readonly MAX_ITERATIONS: 1000;
455
320
  };
456
321
 
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 };
322
+ export { isTaskCompleted as A, isTaskRunning as B, COMPLETION_STRATEGIES as C, DEFAULTS as D, EXECUTION_MODES as E, loadGraphConfig as F, type GraphIssue as G, next as H, type IssueSeverity as I, planExecution as J, validateGraph as K, validateGraphConfig as L, type MermaidOptions as M, addKeyToProvides as N, addKeyToRequires as O, getRepeatableMax as P, groupTasksByProvides as Q, hasOutputConflict as R, removeKeyFromProvides as S, TASK_STATUS as T, removeKeyFromRequires as U, CONFLICT_STRATEGIES as a, type CompletionResult as b, EXECUTION_STATUS as c, type ExecutionPlan as d, type ExportOptions as e, type GraphValidationResult as f, addDynamicTask as g, apply as h, applyAll as i, computeAvailableOutputs as j, createDefaultTaskState as k, createInitialExecutionState as l, detectStuckState as m, exportGraphConfig as n, exportGraphConfigToFile as o, flowToMermaid as p, getAllTasks as q, getCandidateTasks as r, getProvides as s, getRequires as t, getTask as u, graphToMermaid as v, hasTask as w, isExecutionComplete as x, isNonActiveTask as y, isRepeatableTask as z };