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