1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//! # Goblin Engine
//!
//! A high-performance, async workflow engine for executing scripts in planned sequences.
//!
//! Goblin Engine allows you to define scripts, create execution plans that orchestrate multiple
//! scripts, handle dependencies between steps automatically, and execute workflows asynchronously
//! with proper error handling.
//!
//! ## Features
//!
//! - **Async Execution**: Fully asynchronous workflow execution using Tokio
//! - **Dependency Resolution**: Automatic topological sorting and cycle detection
//! - **Type Safety**: Compile-time validation with rich error types
//! - **Concurrent Execution**: Execute independent steps concurrently
//! - **Template Interpolation**: Reference previous step outputs in later steps
//! - **Script Auto-Discovery**: Automatically find and load scripts from directories
//! - **Flexible Configuration**: TOML-based configuration with validation
//!
//! ## Quick Start
//!
//! ```rust,no_run
//! use goblin_engine::{Engine, EngineConfig};
//!
//! #[tokio::main]
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! // Create and configure engine
//! let config = EngineConfig::from_file("goblin.toml")?;
//! let engine = Engine::new()
//! .with_scripts_dir(config.scripts_dir.unwrap());
//!
//! // Auto-discover scripts
//! engine.auto_discover_scripts()?;
//!
//! // Execute a plan
//! let context = engine.execute_plan("my_plan", Some("input".to_string())).await?;
//!
//! println!("Execution completed in {:?}", context.elapsed());
//! for (step, result) in context.results {
//! println!("{}: {}", step, result);
//! }
//!
//! Ok(())
//! }
//! ```
//!
//! ## Core Concepts
//!
//! ### Scripts
//!
//! A [`Script`] represents an executable unit with configuration. Scripts are defined via
//! `goblin.toml` files in script directories:
//!
//! ```toml
//! name = "example_script"
//! command = "deno run --allow-all main.ts"
//! timeout = 500 # seconds
//! test_command = "deno test"
//! require_test = false
//! ```
//!
//! ### Plans
//!
//! A [`Plan`] orchestrates multiple scripts in a defined sequence, with automatic dependency
//! resolution. Plans are defined in TOML files:
//!
//! ```toml
//! name = "example_plan"
//!
//! [[steps]]
//! name = "step_one"
//! function = "script_name"
//! inputs = ["default_input"]
//!
//! [[steps]]
//! name = "step_two"
//! function = "another_script"
//! inputs = ["step_one", "literal_value"] # References step_one's output
//! ```
//!
//! ### Engine
//!
//! The [`Engine`] is the main orchestrator that loads scripts and plans, resolves dependencies,
//! and executes workflows.
//!
//! ## Module Organization
//!
//! - [`engine`]: Core engine implementation and execution context
//! - [`script`]: Script configuration and management
//! - [`plan`]: Plan definition, step configuration, and dependency resolution
//! - [`executor`]: Script execution trait and default implementation
//! - [`error`]: Error types and result aliases
//! - [`config`]: Engine configuration from TOML files
//!
//! ## Error Handling
//!
//! All fallible operations return a [`Result<T>`] type alias that uses [`GoblinError`]
//! as the error type. Errors are structured with rich context for debugging.
//!
//! ```rust
//! use goblin_engine::{GoblinError, Result};
//!
//! fn example() -> Result<()> {
//! // Operations that may fail return Result<T>
//! Ok(())
//! }
//! ```
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use EngineConfig;