mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-08-28 05:27:41 +00:00
Rename fabro-workflows crate to fabro-workflow
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
73cbcabf77
commit
d5976820d5
140 changed files with 238 additions and 239 deletions
|
|
@ -4,25 +4,25 @@ Which source files affect which doc pages. Use this as guidance — also apply j
|
|||
|
||||
| Source | Docs |
|
||||
|--------|------|
|
||||
| `lib/crates/fabro-cli/src/main.rs`, `lib/crates/fabro-workflows/src/cli/mod.rs`, `lib/crates/fabro-workflows/src/cli/run.rs` | `docs/reference/cli.mdx` |
|
||||
| `lib/crates/fabro-cli/src/main.rs`, `lib/crates/fabro-workflow/src/cli/mod.rs`, `lib/crates/fabro-workflow/src/cli/run.rs` | `docs/reference/cli.mdx` |
|
||||
| `lib/crates/fabro-cli/src/cli_config.rs` | `docs/reference/cli-configuration.mdx` |
|
||||
| `lib/crates/fabro-llm/src/cli.rs` | `docs/reference/cli.mdx` |
|
||||
| `lib/crates/fabro-api/src/serve.rs` | `docs/reference/cli.mdx` |
|
||||
| `lib/crates/fabro-workflows/src/parser/*.rs` | `docs/reference/dot-language.mdx` |
|
||||
| `lib/crates/fabro-workflows/src/condition.rs` | `docs/reference/dot-language.mdx` |
|
||||
| `lib/crates/fabro-workflows/src/cli/validate.rs` | `docs/reference/dot-language.mdx` |
|
||||
| `lib/crates/fabro-workflows/src/stylesheet.rs` | `docs/workflows/stylesheets.mdx` |
|
||||
| `lib/crates/fabro-workflows/src/transform.rs` | `docs/workflows/variables.mdx` |
|
||||
| `lib/crates/fabro-workflows/src/handler/*.rs` | `docs/workflows/stages-and-nodes.mdx`, `docs/reference/dot-language.mdx` |
|
||||
| `lib/crates/fabro-workflows/src/handler/human.rs` | `docs/workflows/human-in-the-loop.mdx` |
|
||||
| `lib/crates/fabro-workflows/src/cli/run_config.rs` | `docs/execution/run-configuration.mdx` |
|
||||
| `lib/crates/fabro-workflows/src/engine.rs` | `docs/core-concepts/how-arc-works.mdx` |
|
||||
| `lib/crates/fabro-workflows/src/context/*.rs` | `docs/execution/context.mdx` |
|
||||
| `lib/crates/fabro-workflows/src/checkpoint.rs` | `docs/execution/checkpoints.mdx` |
|
||||
| `lib/crates/fabro-workflows/src/retro.rs`, `lib/crates/fabro-workflows/src/retro_agent.rs` | `docs/execution/retros.mdx` |
|
||||
| `lib/crates/fabro-workflows/src/interviewer/*.rs` | `docs/execution/interviews.mdx` |
|
||||
| `lib/crates/fabro-workflows/src/hook/*.rs` | `docs/agents/hooks.mdx` |
|
||||
| `lib/crates/fabro-workflows/src/daytona_sandbox.rs` | `docs/integrations/daytona.mdx`, `docs/execution/environments.mdx` |
|
||||
| `lib/crates/fabro-workflow/src/parser/*.rs` | `docs/reference/dot-language.mdx` |
|
||||
| `lib/crates/fabro-workflow/src/condition.rs` | `docs/reference/dot-language.mdx` |
|
||||
| `lib/crates/fabro-workflow/src/cli/validate.rs` | `docs/reference/dot-language.mdx` |
|
||||
| `lib/crates/fabro-workflow/src/stylesheet.rs` | `docs/workflows/stylesheets.mdx` |
|
||||
| `lib/crates/fabro-workflow/src/transform.rs` | `docs/workflows/variables.mdx` |
|
||||
| `lib/crates/fabro-workflow/src/handler/*.rs` | `docs/workflows/stages-and-nodes.mdx`, `docs/reference/dot-language.mdx` |
|
||||
| `lib/crates/fabro-workflow/src/handler/human.rs` | `docs/workflows/human-in-the-loop.mdx` |
|
||||
| `lib/crates/fabro-workflow/src/cli/run_config.rs` | `docs/execution/run-configuration.mdx` |
|
||||
| `lib/crates/fabro-workflow/src/engine.rs` | `docs/core-concepts/how-arc-works.mdx` |
|
||||
| `lib/crates/fabro-workflow/src/context/*.rs` | `docs/execution/context.mdx` |
|
||||
| `lib/crates/fabro-workflow/src/checkpoint.rs` | `docs/execution/checkpoints.mdx` |
|
||||
| `lib/crates/fabro-workflow/src/retro.rs`, `lib/crates/fabro-workflow/src/retro_agent.rs` | `docs/execution/retros.mdx` |
|
||||
| `lib/crates/fabro-workflow/src/interviewer/*.rs` | `docs/execution/interviews.mdx` |
|
||||
| `lib/crates/fabro-workflow/src/hook/*.rs` | `docs/agents/hooks.mdx` |
|
||||
| `lib/crates/fabro-workflow/src/daytona_sandbox.rs` | `docs/integrations/daytona.mdx`, `docs/execution/environments.mdx` |
|
||||
| `lib/crates/fabro-agent/src/tools.rs`, `lib/crates/fabro-agent/src/tool_registry.rs`, `lib/crates/fabro-agent/src/tool_execution.rs` | `docs/agents/tools.mdx` |
|
||||
| `lib/crates/fabro-agent/src/v4a_patch.rs` | `docs/agents/tools.mdx` |
|
||||
| `lib/crates/fabro-agent/src/cli.rs` | `docs/agents/permissions.mdx` |
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ medium = { max-threads = 4 } # 18-30 MB binaries
|
|||
[[profile.default.overrides]]
|
||||
filter = """
|
||||
package(fabro-server)
|
||||
| package(fabro-workflows)
|
||||
| package(fabro-workflow)
|
||||
| package(fabro-agent)
|
||||
| package(fabro-cli)
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|||
- `cargo build --workspace` — build all crates
|
||||
- `cargo nextest run --workspace` — run all unit tests
|
||||
- `cargo nextest run -p fabro-server` — test a single crate
|
||||
- `cargo nextest run -p fabro-workflows -- test_name` — run a single test
|
||||
- `cargo nextest run -p fabro-workflow -- test_name` — run a single test
|
||||
- `set -a && source .env && set +a && cargo nextest run --workspace --profile e2e --run-ignored only` — run all E2E live tests (requires credentials in `.env`, see `.env.example`)
|
||||
- `set -a && source .env && set +a && cargo nextest run -p fabro-llm --profile e2e --run-ignored only` — run E2E tests for a single crate
|
||||
- `cargo fmt --check --all` — check formatting
|
||||
|
|
@ -51,7 +51,7 @@ Fabro is an AI-powered workflow orchestration platform. Workflows are defined as
|
|||
|
||||
### Rust crates (`lib/crates/`)
|
||||
- **fabro-cli** — CLI entry point. Commands: `run`, `exec`, `serve`, `validate`, `parse`, `cp`, `model`, `doctor`, `init`, `install`, `ps`, `system prune`, `llm`
|
||||
- **fabro-workflows** — Core workflow engine. Parses Graphviz graphs, runs stages, manages checkpoints/resume, hooks, retros, and human-in-the-loop interactions
|
||||
- **fabro-workflow** — Core workflow engine. Parses Graphviz graphs, runs stages, manages checkpoints/resume, hooks, retros, and human-in-the-loop interactions
|
||||
- **fabro-agent** — AI coding agent with tool use (Bash, Read, Write, Edit, Glob, Grep, WebFetch). `Sandbox` trait abstracts execution environments
|
||||
- **fabro-server** — Axum HTTP server. Routes for runs, sessions, models, completions, usage. SSE event streaming. Demo mode via header
|
||||
- **fabro-llm** — Unified LLM client with providers: Anthropic, OpenAI, Gemini, OpenAI-compatible, plus retry/middleware/streaming
|
||||
|
|
@ -84,12 +84,12 @@ When working on Rust crates, read the relevant strategy doc **before** making ch
|
|||
|
||||
## Shell quoting in sandbox code
|
||||
|
||||
When interpolating values into shell command strings (in `fabro-workflows`), always use the `shell_quote()` helper (backed by `shlex::try_quote`). Never use manual `replace('\'', "'\\''")` or unquoted interpolation. This applies to file paths, branch names, URLs, env vars, image names, glob patterns, and any other user-controlled input assembled into a shell script.
|
||||
When interpolating values into shell command strings (in `fabro-workflow`), always use the `shell_quote()` helper (backed by `shlex::try_quote`). Never use manual `replace('\'', "'\\''")` or unquoted interpolation. This applies to file paths, branch names, URLs, env vars, image names, glob patterns, and any other user-controlled input assembled into a shell script.
|
||||
|
||||
## Rust import style
|
||||
|
||||
- **Types** (structs, enums, traits): import by name — `use crate::outcome::Outcome;`
|
||||
- **Functions**: import the parent module, call as `module::function()` — `use fabro_workflows::operations; operations::create(...)`
|
||||
- **Functions**: import the parent module, call as `module::function()` — `use fabro_workflow::operations; operations::create(...)`
|
||||
- **No glob imports** in production code (`use foo::*`). Globs are acceptable in test modules and preludes. Enforced by clippy `wildcard_imports` lint.
|
||||
|
||||
## Testing workflows
|
||||
|
|
|
|||
8
Cargo.lock
generated
8
Cargo.lock
generated
|
|
@ -1477,7 +1477,7 @@ dependencies = [
|
|||
"fabro-types",
|
||||
"fabro-util",
|
||||
"fabro-validate",
|
||||
"fabro-workflows",
|
||||
"fabro-workflow",
|
||||
"futures",
|
||||
"git2",
|
||||
"httpmock",
|
||||
|
|
@ -1810,7 +1810,7 @@ dependencies = [
|
|||
"fabro-store",
|
||||
"fabro-types",
|
||||
"fabro-util",
|
||||
"fabro-workflows",
|
||||
"fabro-workflow",
|
||||
"futures-util",
|
||||
"hex",
|
||||
"hmac",
|
||||
|
|
@ -1847,7 +1847,7 @@ name = "fabro-slack"
|
|||
version = "0.176.2"
|
||||
dependencies = [
|
||||
"fabro-interview",
|
||||
"fabro-workflows",
|
||||
"fabro-workflow",
|
||||
"futures-util",
|
||||
"reqwest",
|
||||
"rustls",
|
||||
|
|
@ -1972,7 +1972,7 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "fabro-workflows"
|
||||
name = "fabro-workflow"
|
||||
version = "0.176.2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ openssl pkey -in fabro-jwt-private.pem -pubout -out fabro-jwt-public.pem
|
|||
echo ""
|
||||
echo "Generated:"
|
||||
echo " fabro-jwt-private.pem (private key — for fabro-web / FABRO_JWT_PRIVATE_KEY)"
|
||||
echo " fabro-jwt-public.pem (public key — for fabro-workflows / FABRO_JWT_PUBLIC_KEY)"
|
||||
echo " fabro-jwt-public.pem (public key — for fabro-workflow / FABRO_JWT_PUBLIC_KEY)"
|
||||
echo ""
|
||||
echo "Set env vars with the PEM contents (including header/footer lines):"
|
||||
echo ""
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ Every line in `progress.jsonl` has three envelope fields, then the event's own f
|
|||
| `run_id` | string | ULID for this workflow run |
|
||||
| `event` | string | Event name (matches Rust variant, dot-separated for wrapped types) |
|
||||
|
||||
The envelope is built in `fabro-workflows/src/event.rs` by `build_event_envelope()`, and file logging is handled by `ProgressLogger`. Field names from the event that collide with envelope keys (`ts`, `run_id`, `event`) are dropped — the `run_id` from `WorkflowRunStarted` populates the envelope itself.
|
||||
The envelope is built in `fabro-workflow/src/event.rs` by `build_event_envelope()`, and file logging is handled by `ProgressLogger`. Field names from the event that collide with envelope keys (`ts`, `run_id`, `event`) are dropped — the `run_id` from `WorkflowRunStarted` populates the envelope itself.
|
||||
|
||||
## Run Completion Contract
|
||||
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ warn!(provider = %provider, attempt = n, error = %err, "Request failed, retrying
|
|||
error!(provider = %provider, error = %err, "Request failed after all retries");
|
||||
```
|
||||
|
||||
**fabro-workflows:**
|
||||
**fabro-workflow:**
|
||||
```rust
|
||||
info!(pipeline = %name, "Starting pipeline execution");
|
||||
info!(pipeline = %name, nodes = count, "Pipeline complete");
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ fabro-sandbox = { path = "../fabro-sandbox", features = ["daytona"] }
|
|||
fabro-git-storage = { path = "../fabro-git-storage" }
|
||||
fabro-graphviz = { path = "../fabro-graphviz" }
|
||||
fabro-validate = { path = "../fabro-validate" }
|
||||
fabro-workflows = { path = "../fabro-workflows" }
|
||||
fabro-workflow = { path = "../fabro-workflow" }
|
||||
fabro-server = { path = "../fabro-server", optional = true }
|
||||
fabro-telemetry = { path = "../fabro-telemetry" }
|
||||
fabro-store = { path = "../fabro-store" }
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ use std::path::{Path, PathBuf};
|
|||
use anyhow::{Context, Result, bail};
|
||||
use fabro_config::FabroSettingsExt;
|
||||
use fabro_store::RuntimeState;
|
||||
use fabro_workflows::assets::{AssetEntry, scan_assets};
|
||||
use fabro_workflows::run_lookup::{resolve_run, runs_base};
|
||||
use fabro_workflow::assets::{AssetEntry, scan_assets};
|
||||
use fabro_workflow::run_lookup::{resolve_run, runs_base};
|
||||
|
||||
use crate::args::{AssetCpArgs, GlobalArgs};
|
||||
use crate::shared::split_run_path;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use anyhow::Result;
|
||||
use fabro_config::FabroSettingsExt;
|
||||
use fabro_store::RuntimeState;
|
||||
use fabro_workflows::assets::scan_assets;
|
||||
use fabro_workflows::run_lookup::{resolve_run, runs_base};
|
||||
use fabro_workflow::assets::scan_assets;
|
||||
use fabro_workflow::run_lookup::{resolve_run, runs_base};
|
||||
|
||||
use crate::args::{AssetListArgs, GlobalArgs};
|
||||
use crate::shared::format_size;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use fabro_config::project::resolve_workflow_path;
|
|||
use fabro_graphviz::render::render_dot;
|
||||
use fabro_util::terminal::Styles;
|
||||
use fabro_validate::Severity;
|
||||
use fabro_workflows::operations::{ValidateInput, WorkflowInput, validate};
|
||||
use fabro_workflow::operations::{ValidateInput, WorkflowInput, validate};
|
||||
use tracing::debug;
|
||||
|
||||
use crate::args::{GraphArgs, GraphDirection};
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::path::Path;
|
|||
|
||||
use anyhow::{Context, Result};
|
||||
use fabro_config::FabroSettingsExt;
|
||||
use fabro_workflows::run_lookup::runs_base;
|
||||
use fabro_workflow::run_lookup::runs_base;
|
||||
use tracing::info;
|
||||
|
||||
use crate::args::{GlobalArgs, PrCloseArgs};
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@ use anyhow::{Context, Result, bail};
|
|||
use fabro_config::FabroSettingsExt;
|
||||
use fabro_model::Catalog;
|
||||
use fabro_sandbox::daytona::detect_repo_info;
|
||||
use fabro_workflows::outcome::StageStatus;
|
||||
use fabro_workflows::pull_request::maybe_open_pull_request;
|
||||
use fabro_workflows::records::{
|
||||
use fabro_workflow::outcome::StageStatus;
|
||||
use fabro_workflow::pull_request::maybe_open_pull_request;
|
||||
use fabro_workflow::records::{
|
||||
Conclusion, ConclusionExt, RunRecord, RunRecordExt, StartRecord, StartRecordExt,
|
||||
};
|
||||
use fabro_workflows::run_lookup::{resolve_run_combined, runs_base};
|
||||
use fabro_workflow::run_lookup::{resolve_run_combined, runs_base};
|
||||
use tracing::info;
|
||||
|
||||
use crate::args::{GlobalArgs, PrCreateArgs};
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ use std::path::Path;
|
|||
|
||||
use anyhow::{Context, Result};
|
||||
use fabro_config::FabroSettingsExt;
|
||||
use fabro_workflows::pull_request::PullRequestRecord;
|
||||
use fabro_workflows::run_lookup::{runs_base, scan_runs_combined};
|
||||
use fabro_workflow::pull_request::PullRequestRecord;
|
||||
use fabro_workflow::run_lookup::{runs_base, scan_runs_combined};
|
||||
use futures::future::join_all;
|
||||
use tracing::info;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use anyhow::{Context, Result};
|
|||
use fabro_config::FabroSettingsExt;
|
||||
use tracing::info;
|
||||
|
||||
use fabro_workflows::run_lookup::runs_base;
|
||||
use fabro_workflow::run_lookup::runs_base;
|
||||
|
||||
use crate::args::{GlobalArgs, PrMergeArgs};
|
||||
use crate::user_config::load_user_settings_with_globals;
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ use std::path::{Path, PathBuf};
|
|||
|
||||
use anyhow::{Context, Result};
|
||||
|
||||
use fabro_workflows::pull_request::PullRequestRecord;
|
||||
use fabro_workflows::run_lookup::resolve_run_combined;
|
||||
use fabro_workflow::pull_request::PullRequestRecord;
|
||||
use fabro_workflow::run_lookup::resolve_run_combined;
|
||||
|
||||
use crate::args::{GlobalArgs, PrCommand, PrNamespace};
|
||||
use crate::shared::github::build_github_app_credentials;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use anyhow::{Context, Result};
|
|||
use fabro_config::FabroSettingsExt;
|
||||
use tracing::info;
|
||||
|
||||
use fabro_workflows::run_lookup::runs_base;
|
||||
use fabro_workflow::run_lookup::runs_base;
|
||||
|
||||
use crate::args::{GlobalArgs, PrViewArgs};
|
||||
use crate::user_config::load_user_settings_with_globals;
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ use fabro_model::{Catalog, Provider};
|
|||
use fabro_sandbox::daytona::{DaytonaConfig, detect_repo_info};
|
||||
use fabro_sandbox::{DockerSandboxConfig, Sandbox, SandboxProvider, SandboxSpec};
|
||||
use fabro_util::terminal::Styles;
|
||||
use fabro_workflows::git::{GitSyncStatus, sync_status};
|
||||
use fabro_workflows::operations::{ValidateInput, WorkflowInput, validate};
|
||||
use fabro_workflow::git::{GitSyncStatus, sync_status};
|
||||
use fabro_workflow::operations::{ValidateInput, WorkflowInput, validate};
|
||||
|
||||
use crate::args::{GlobalArgs, PreflightArgs};
|
||||
use crate::shared::github::build_github_app_credentials;
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ use futures::StreamExt;
|
|||
use fabro_interview::{AnswerValue, ConsoleInterviewer};
|
||||
use fabro_store::{EventEnvelope, RunStore, RuntimeState};
|
||||
use fabro_util::terminal::Styles;
|
||||
use fabro_workflows::outcome::StageStatus;
|
||||
use fabro_workflows::records::{Conclusion, ConclusionExt, RunRecord, RunRecordExt};
|
||||
use fabro_workflows::run_status::{RunStatus, RunStatusRecord, RunStatusRecordExt};
|
||||
use fabro_workflow::outcome::StageStatus;
|
||||
use fabro_workflow::records::{Conclusion, ConclusionExt, RunRecord, RunRecordExt};
|
||||
use fabro_workflow::run_status::{RunStatus, RunStatusRecord, RunStatusRecordExt};
|
||||
use tokio::signal::ctrl_c;
|
||||
use tokio::time::{self, sleep};
|
||||
|
||||
|
|
@ -695,9 +695,9 @@ mod tests {
|
|||
use chrono::Utc;
|
||||
use fabro_interview::{Answer, AnswerValue};
|
||||
use fabro_util::terminal::Styles;
|
||||
use fabro_workflows::outcome::StageStatus;
|
||||
use fabro_workflows::records::Conclusion;
|
||||
use fabro_workflows::run_status::{StatusReason, write_run_status};
|
||||
use fabro_workflow::outcome::StageStatus;
|
||||
use fabro_workflow::records::Conclusion;
|
||||
use fabro_workflow::run_status::{StatusReason, write_run_status};
|
||||
|
||||
fn no_color_styles() -> &'static Styles {
|
||||
Box::leak(Box::new(Styles::new(false)))
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use fabro_agent::sandbox::Sandbox;
|
|||
use fabro_config::FabroSettingsExt;
|
||||
use fabro_sandbox::SandboxRecordExt;
|
||||
use fabro_sandbox::reconnect::reconnect;
|
||||
use fabro_workflows::run_lookup::{resolve_run, runs_base};
|
||||
use fabro_workflow::run_lookup::{resolve_run, runs_base};
|
||||
use tokio::fs;
|
||||
use tracing::{debug, info};
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ use crate::args::RunArgs;
|
|||
use fabro_config::{ConfigLayer, FabroSettings};
|
||||
use fabro_types::RunId;
|
||||
use fabro_util::terminal::Styles;
|
||||
use fabro_workflows::error::FabroError;
|
||||
use fabro_workflows::operations::{CreateRunInput, WorkflowInput, create};
|
||||
use fabro_workflow::error::FabroError;
|
||||
use fabro_workflow::operations::{CreateRunInput, WorkflowInput, create};
|
||||
|
||||
use super::output::{print_diagnostics_from_error, print_workflow_report_from_persisted};
|
||||
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ use anyhow::Result;
|
|||
use fabro_config::FabroSettingsExt;
|
||||
use fabro_interview::FileInterviewer;
|
||||
use fabro_store::RuntimeState;
|
||||
use fabro_workflows::event::EventEmitter;
|
||||
use fabro_workflows::operations::{
|
||||
use fabro_workflow::event::EventEmitter;
|
||||
use fabro_workflow::operations::{
|
||||
StartServices, open_or_hydrate_run, resume as resume_run, start as start_run,
|
||||
};
|
||||
use fabro_workflows::records::{RunRecord, RunRecordExt};
|
||||
use fabro_workflow::records::{RunRecord, RunRecordExt};
|
||||
|
||||
use crate::shared;
|
||||
use crate::store;
|
||||
|
|
@ -21,7 +21,7 @@ pub(crate) async fn execute(run_dir: PathBuf, launcher_path: PathBuf, resume: bo
|
|||
});
|
||||
|
||||
let run_record = RunRecord::load(&run_dir)?;
|
||||
let on_node: fabro_workflows::OnNodeCallback = Some({
|
||||
let on_node: fabro_workflow::OnNodeCallback = Some({
|
||||
let run_id = run_record.run_id.to_string();
|
||||
let short_id = super::short_run_id(&run_id).to_string();
|
||||
fabro_proctitle::set(&format!("fabro: {short_id}"));
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ use anyhow::{Context, Result, bail};
|
|||
use fabro_config::FabroSettingsExt;
|
||||
use fabro_sandbox::SandboxRecordExt;
|
||||
use fabro_sandbox::reconnect::reconnect;
|
||||
use fabro_workflows::records::{StartRecord, StartRecordExt};
|
||||
use fabro_workflows::run_lookup::{resolve_run_combined, runs_base};
|
||||
use fabro_workflows::sandbox_git::GIT_REMOTE;
|
||||
use fabro_workflow::records::{StartRecord, StartRecordExt};
|
||||
use fabro_workflow::run_lookup::{resolve_run_combined, runs_base};
|
||||
use fabro_workflow::sandbox_git::GIT_REMOTE;
|
||||
use tracing::{debug, info};
|
||||
|
||||
use crate::args::{DiffArgs, GlobalArgs};
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use anyhow::Result;
|
|||
use fabro_config::FabroSettingsExt;
|
||||
use fabro_git_storage::gitobj::Store;
|
||||
use fabro_util::terminal::Styles;
|
||||
use fabro_workflows::operations::{
|
||||
use fabro_workflow::operations::{
|
||||
ForkRunInput, RewindTarget, build_timeline_or_rebuild, find_run_id_by_prefix_or_store, fork,
|
||||
};
|
||||
use git2::Repository;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use anyhow::{Context, Result};
|
|||
use chrono::{DateTime, Utc};
|
||||
use fabro_config::FabroSettingsExt;
|
||||
use fabro_types::RunId;
|
||||
use fabro_workflows::records::{RunRecord, RunRecordExt};
|
||||
use fabro_workflow::records::{RunRecord, RunRecordExt};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
@ -114,7 +114,7 @@ mod tests {
|
|||
use fabro_config::FabroSettings;
|
||||
use fabro_graphviz::graph::Graph;
|
||||
use fabro_types::fixtures;
|
||||
use fabro_workflows::records::RunRecord;
|
||||
use fabro_workflow::records::RunRecord;
|
||||
|
||||
#[test]
|
||||
fn active_launcher_record_for_run_removes_stale_record() {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use chrono::{DateTime, Utc};
|
|||
use fabro_config::FabroSettingsExt;
|
||||
use fabro_store::RunStore;
|
||||
use fabro_util::terminal::Styles;
|
||||
use fabro_workflows::run_lookup::{resolve_run_combined, runs_base};
|
||||
use fabro_workflow::run_lookup::{resolve_run_combined, runs_base};
|
||||
use futures::StreamExt;
|
||||
use tokio::time;
|
||||
use tracing::{debug, info, warn};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use anyhow::Result;
|
||||
use fabro_config::FabroSettingsExt;
|
||||
use fabro_util::terminal::Styles;
|
||||
use fabro_workflows::run_lookup::{resolve_run_combined, runs_base};
|
||||
use fabro_workflow::run_lookup::{resolve_run_combined, runs_base};
|
||||
|
||||
use crate::args::{GlobalArgs, RunCommands};
|
||||
use crate::store;
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ use fabro_graphviz::graph::Graph;
|
|||
use fabro_store::RuntimeState;
|
||||
use fabro_util::terminal::Styles;
|
||||
use fabro_util::text::strip_goal_decoration;
|
||||
use fabro_workflows::asset_snapshot::collect_asset_paths;
|
||||
use fabro_workflows::outcome::{StageStatus, format_cost};
|
||||
use fabro_workflows::pipeline::{Persisted, Validated};
|
||||
use fabro_workflows::pull_request::PullRequestRecord;
|
||||
use fabro_workflows::records::{Checkpoint, CheckpointExt, Conclusion, ConclusionExt};
|
||||
use fabro_workflow::asset_snapshot::collect_asset_paths;
|
||||
use fabro_workflow::outcome::{StageStatus, format_cost};
|
||||
use fabro_workflow::pipeline::{Persisted, Validated};
|
||||
use fabro_workflow::pull_request::PullRequestRecord;
|
||||
use fabro_workflow::records::{Checkpoint, CheckpointExt, Conclusion, ConclusionExt};
|
||||
use indicatif::HumanDuration;
|
||||
|
||||
use crate::shared::{format_tokens_human, print_diagnostics, relative_path, tilde_path};
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use anyhow::{Context, Result};
|
|||
use fabro_config::FabroSettingsExt;
|
||||
use fabro_sandbox::SandboxRecordExt;
|
||||
use fabro_sandbox::daytona::DaytonaSandbox;
|
||||
use fabro_workflows::run_lookup::{resolve_run_combined, runs_base};
|
||||
use fabro_workflow::run_lookup::{resolve_run_combined, runs_base};
|
||||
use tracing::info;
|
||||
|
||||
use crate::args::{GlobalArgs, PreviewArgs};
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use anyhow::bail;
|
||||
use fabro_config::FabroSettingsExt;
|
||||
use fabro_util::terminal::Styles;
|
||||
use fabro_workflows::records::{RunRecord, RunRecordExt};
|
||||
use fabro_workflows::run_lookup::{resolve_run_combined, runs_base};
|
||||
use fabro_workflow::records::{RunRecord, RunRecordExt};
|
||||
use fabro_workflow::run_lookup::{resolve_run_combined, runs_base};
|
||||
|
||||
use crate::args::{GlobalArgs, ResumeArgs};
|
||||
use crate::store;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use cli_table::{Cell, CellStruct, Color, Style, Table};
|
|||
use fabro_config::FabroSettingsExt;
|
||||
use fabro_git_storage::gitobj::Store;
|
||||
use fabro_util::terminal::Styles;
|
||||
use fabro_workflows::operations::{
|
||||
use fabro_workflow::operations::{
|
||||
RewindInput, RewindTarget, RunTimeline, build_timeline_or_rebuild,
|
||||
find_run_id_by_prefix_or_store, rewind,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ use indicatif::{MultiProgress, ProgressBar, ProgressDrawTarget, ProgressStyle};
|
|||
use fabro_agent::AgentEvent;
|
||||
use fabro_interview::{Answer, ConsoleInterviewer, Interviewer, Question};
|
||||
use fabro_util::version::FABRO_VERSION;
|
||||
use fabro_workflows::event::{EventEmitter, RunNoticeLevel, WorkflowRunEvent};
|
||||
use fabro_workflows::outcome::StageStatus;
|
||||
use fabro_workflow::event::{EventEmitter, RunNoticeLevel, WorkflowRunEvent};
|
||||
use fabro_workflow::outcome::StageStatus;
|
||||
|
||||
use crate::shared::{format_duration_ms, format_tokens_human, tilde_path};
|
||||
use fabro_workflows::outcome::{compute_stage_cost, format_cost};
|
||||
use fabro_workflow::outcome::{compute_stage_cost, format_cost};
|
||||
|
||||
// ── Cached styles ───────────────────────────────────────────────────────
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use anyhow::{Context, Result, bail};
|
|||
use fabro_config::FabroSettingsExt;
|
||||
use fabro_sandbox::SandboxRecordExt;
|
||||
use fabro_sandbox::daytona::DaytonaSandbox;
|
||||
use fabro_workflows::run_lookup::{resolve_run_combined, runs_base};
|
||||
use fabro_workflow::run_lookup::{resolve_run_combined, runs_base};
|
||||
use tracing::info;
|
||||
|
||||
use crate::args::{GlobalArgs, SshArgs};
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::path::Path;
|
|||
use anyhow::{Result, anyhow};
|
||||
use chrono::Utc;
|
||||
use fabro_config::FabroSettingsExt;
|
||||
use fabro_workflows::records::{RunRecord, RunRecordExt};
|
||||
use fabro_workflow::records::{RunRecord, RunRecordExt};
|
||||
|
||||
use super::launcher::{
|
||||
LauncherRecord, launcher_log_path, launcher_record_path, remove_launcher_record,
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ use anyhow::{Result, bail};
|
|||
use fabro_config::FabroSettingsExt;
|
||||
use fabro_types::RunId;
|
||||
use fabro_util::terminal::Styles;
|
||||
use fabro_workflows::records::{Conclusion, ConclusionExt};
|
||||
use fabro_workflows::run_lookup::{resolve_run_combined, runs_base};
|
||||
use fabro_workflows::run_status::{RunStatus, RunStatusRecord, RunStatusRecordExt};
|
||||
use fabro_workflow::records::{Conclusion, ConclusionExt};
|
||||
use fabro_workflow::run_lookup::{resolve_run_combined, runs_base};
|
||||
use fabro_workflow::run_status::{RunStatus, RunStatusRecord, RunStatusRecordExt};
|
||||
use tracing::info;
|
||||
|
||||
use crate::args::{GlobalArgs, WaitArgs};
|
||||
|
|
@ -147,8 +147,8 @@ fn print_human_output(
|
|||
mod tests {
|
||||
use super::*;
|
||||
use fabro_types::fixtures;
|
||||
use fabro_workflows::outcome::StageStatus;
|
||||
use fabro_workflows::records::Conclusion;
|
||||
use fabro_workflow::outcome::StageStatus;
|
||||
use fabro_workflow::records::Conclusion;
|
||||
|
||||
fn no_color_styles() -> Styles {
|
||||
Styles::new(false)
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@ use anyhow::Result;
|
|||
use fabro_config::FabroSettingsExt;
|
||||
use fabro_sandbox::SandboxRecordExt;
|
||||
use fabro_types::RunId;
|
||||
use fabro_workflows::records::{CheckpointExt, ConclusionExt, RunRecordExt, StartRecordExt};
|
||||
use fabro_workflow::records::{CheckpointExt, ConclusionExt, RunRecordExt, StartRecordExt};
|
||||
use serde::Serialize;
|
||||
|
||||
use fabro_workflows::records::{Checkpoint, Conclusion, RunRecord, StartRecord};
|
||||
use fabro_workflows::run_lookup::{resolve_run_combined, runs_base};
|
||||
use fabro_workflows::run_status::RunStatus;
|
||||
use fabro_workflow::records::{Checkpoint, Conclusion, RunRecord, StartRecord};
|
||||
use fabro_workflow::run_lookup::{resolve_run_combined, runs_base};
|
||||
use fabro_workflow::run_status::RunStatus;
|
||||
|
||||
use crate::args::{GlobalArgs, InspectArgs};
|
||||
use crate::store;
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ use fabro_config::FabroSettingsExt;
|
|||
use fabro_util::terminal::Styles;
|
||||
|
||||
use fabro_util::text::strip_goal_decoration;
|
||||
use fabro_workflows::run_lookup::{StatusFilter, filter_runs, runs_base, scan_runs_combined};
|
||||
use fabro_workflows::run_status::RunStatus;
|
||||
use fabro_workflow::run_lookup::{StatusFilter, filter_runs, runs_base, scan_runs_combined};
|
||||
use fabro_workflow::run_status::RunStatus;
|
||||
|
||||
use crate::args::{GlobalArgs, RunsListArgs};
|
||||
use crate::shared::{color_if, format_duration_ms, tilde_path};
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ use fabro_store::Store;
|
|||
use tracing::warn;
|
||||
|
||||
use fabro_sandbox::reconnect::reconnect as reconnect_sandbox;
|
||||
use fabro_workflows::run_lookup::{resolve_run_combined, runs_base};
|
||||
use fabro_workflows::run_status::{RunStatus, RunStatusRecord, write_run_status};
|
||||
use fabro_workflow::run_lookup::{resolve_run_combined, runs_base};
|
||||
use fabro_workflow::run_status::{RunStatus, RunStatusRecord, write_run_status};
|
||||
|
||||
use crate::args::{GlobalArgs, RunsRemoveArgs};
|
||||
use crate::store;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use std::path::{Component, Path, PathBuf};
|
|||
use anyhow::{Context, Result, bail};
|
||||
use fabro_config::FabroSettingsExt;
|
||||
use fabro_store::{NodeVisitRef, RunSnapshot, RunStore};
|
||||
use fabro_workflows::run_lookup::{resolve_run_combined, runs_base};
|
||||
use fabro_workflow::run_lookup::{resolve_run_combined, runs_base};
|
||||
use serde::Serialize;
|
||||
#[cfg(test)]
|
||||
use serde::de::DeserializeOwned;
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ use cli_table::format::{Border, Justify, Separator};
|
|||
use cli_table::{Cell, CellStruct, Style, Table};
|
||||
use fabro_config::FabroSettingsExt;
|
||||
|
||||
use fabro_workflows::run_lookup::{logs_base, runs_base, scan_runs_combined};
|
||||
use fabro_workflows::run_status::RunStatus;
|
||||
use fabro_workflow::run_lookup::{logs_base, runs_base, scan_runs_combined};
|
||||
use fabro_workflow::run_status::RunStatus;
|
||||
|
||||
use crate::args::{DfArgs, GlobalArgs};
|
||||
use crate::shared::format_size;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use fabro_config::FabroSettingsExt;
|
|||
use fabro_store::Store;
|
||||
use tracing::{debug, info};
|
||||
|
||||
use fabro_workflows::run_lookup::{StatusFilter, filter_runs, runs_base, scan_runs_combined};
|
||||
use fabro_workflow::run_lookup::{StatusFilter, filter_runs, runs_base, scan_runs_combined};
|
||||
|
||||
use crate::args::{GlobalArgs, RunsPruneArgs};
|
||||
use crate::shared::format_size;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use fabro_config::ConfigLayer;
|
|||
use fabro_config::project::resolve_workflow_path;
|
||||
use fabro_util::terminal::Styles;
|
||||
use fabro_validate::Severity;
|
||||
use fabro_workflows::operations::{ValidateInput, WorkflowInput, validate};
|
||||
use fabro_workflow::operations::{ValidateInput, WorkflowInput, validate};
|
||||
|
||||
use crate::args::ValidateArgs;
|
||||
use crate::shared::{print_diagnostics, relative_path};
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ impl<G: Graph + 'static> Executor<G> {
|
|||
}
|
||||
}
|
||||
|
||||
// Check visit limits (>= matches fabro-workflows semantics)
|
||||
// Check visit limits (>= matches fabro-workflow semantics)
|
||||
let visits = state.increment_visits(node.id());
|
||||
if let Some(max) = node.max_visits() {
|
||||
if visits >= max {
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ impl Graph for TestGraph {
|
|||
Some(o) if o.status == *required_status => {}
|
||||
_ => {
|
||||
// Return the failed node id (the node whose gate is
|
||||
// checked), matching fabro-workflows convention
|
||||
// checked), matching fabro-workflow convention
|
||||
return Err(required_node.clone());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ fabro-config = { path = "../fabro-config" }
|
|||
fabro-graphviz = { path = "../fabro-graphviz" }
|
||||
fabro-hooks = { path = "../fabro-hooks" }
|
||||
fabro-interview = { path = "../fabro-interview" }
|
||||
fabro-workflows = { path = "../fabro-workflows" }
|
||||
fabro-workflow = { path = "../fabro-workflow" }
|
||||
fabro-sandbox = { path = "../fabro-sandbox", features = ["daytona"] }
|
||||
fabro-github = { path = "../fabro-github" }
|
||||
fabro-agent = { path = "../fabro-agent" }
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ use fabro_retro::retro::{Retro, extract_stage_durations};
|
|||
use fabro_store::{InMemoryStore, Store};
|
||||
use fabro_types::RunId;
|
||||
use fabro_util::redact::redact_jsonl_line;
|
||||
use fabro_workflows::error::FabroError;
|
||||
use fabro_workflows::handler::HandlerRegistry;
|
||||
use fabro_workflow::error::FabroError;
|
||||
use fabro_workflow::handler::HandlerRegistry;
|
||||
use futures_util::stream;
|
||||
use tokio::sync::broadcast;
|
||||
use tokio::sync::oneshot;
|
||||
|
|
@ -44,11 +44,11 @@ use crate::sessions as sessions_mod;
|
|||
use crate::sessions::{SessionStore, new_session_store};
|
||||
use fabro_interview::{Answer, Interviewer, QuestionType, WebInterviewer};
|
||||
use fabro_retro::RetroExt;
|
||||
use fabro_workflows::context::Context;
|
||||
use fabro_workflows::event::{EventEmitter, WorkflowRunEvent};
|
||||
use fabro_workflows::operations::{self, CreateRunInput, WorkflowInput};
|
||||
use fabro_workflows::pipeline::Persisted;
|
||||
use fabro_workflows::records::{Checkpoint, CheckpointExt};
|
||||
use fabro_workflow::context::Context;
|
||||
use fabro_workflow::event::{EventEmitter, WorkflowRunEvent};
|
||||
use fabro_workflow::operations::{self, CreateRunInput, WorkflowInput};
|
||||
use fabro_workflow::pipeline::Persisted;
|
||||
use fabro_workflow::records::{Checkpoint, CheckpointExt};
|
||||
|
||||
pub use fabro_api_types::{
|
||||
ApiQuestion, ApiQuestionOption, PaginatedRunList, PaginationMeta,
|
||||
|
|
@ -728,7 +728,7 @@ async fn execute_run(state: Arc<AppState>, run_id: RunId) {
|
|||
// Accumulate aggregate usage after execution completes.
|
||||
if let Some(ref cp) = checkpoint {
|
||||
let stage_durations = match run_store.list_events().await {
|
||||
Ok(events) => fabro_workflows::extract_stage_durations_from_events(&events),
|
||||
Ok(events) => fabro_workflow::extract_stage_durations_from_events(&events),
|
||||
Err(err) => {
|
||||
tracing::warn!(run_id = %run_id, error = %err, "Failed to load run events from store");
|
||||
extract_stage_durations(&run_dir)
|
||||
|
|
@ -1600,7 +1600,7 @@ mod tests {
|
|||
use axum::body::Body;
|
||||
use axum::http::Request;
|
||||
use fabro_types::fixtures;
|
||||
use fabro_workflows::records::{RunRecord, RunRecordExt};
|
||||
use fabro_workflow::records::{RunRecord, RunRecordExt};
|
||||
use tower::ServiceExt;
|
||||
|
||||
const MINIMAL_DOT: &str = r#"digraph Test {
|
||||
|
|
@ -2516,8 +2516,8 @@ mod tests {
|
|||
let mut status_record = None;
|
||||
for _ in 0..50 {
|
||||
if let Some(record) = run_store.get_status().await.unwrap() {
|
||||
if record.status == fabro_workflows::run_status::RunStatus::Failed
|
||||
&& record.reason == Some(fabro_workflows::run_status::StatusReason::Cancelled)
|
||||
if record.status == fabro_workflow::run_status::RunStatus::Failed
|
||||
&& record.reason == Some(fabro_workflow::run_status::StatusReason::Cancelled)
|
||||
{
|
||||
status_record = Some(record);
|
||||
break;
|
||||
|
|
@ -2529,11 +2529,11 @@ mod tests {
|
|||
let status_record = status_record.expect("status record should be persisted");
|
||||
assert_eq!(
|
||||
status_record.status,
|
||||
fabro_workflows::run_status::RunStatus::Failed
|
||||
fabro_workflow::run_status::RunStatus::Failed
|
||||
);
|
||||
assert_eq!(
|
||||
status_record.reason,
|
||||
Some(fabro_workflows::run_status::StatusReason::Cancelled)
|
||||
Some(fabro_workflow::run_status::StatusReason::Cancelled)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -2541,7 +2541,7 @@ mod tests {
|
|||
async fn cancel_before_run_transitions_to_running_closes_event_stream() {
|
||||
let state = create_app_state_with_registry_factory(test_db().await, |interviewer| {
|
||||
std::thread::sleep(std::time::Duration::from_millis(200));
|
||||
fabro_workflows::handler::default_registry(interviewer, || None)
|
||||
fabro_workflow::handler::default_registry(interviewer, || None)
|
||||
});
|
||||
let app = build_router(Arc::clone(&state), AuthMode::Disabled);
|
||||
|
||||
|
|
|
|||
|
|
@ -421,11 +421,11 @@ mod server_lifecycle {
|
|||
use axum::http::{Request, StatusCode};
|
||||
use fabro_interview::Interviewer;
|
||||
use fabro_server::server::{build_router, create_app_state_with_registry_factory};
|
||||
use fabro_workflows::handler::HandlerRegistry;
|
||||
use fabro_workflows::handler::agent::AgentHandler;
|
||||
use fabro_workflows::handler::exit::ExitHandler;
|
||||
use fabro_workflows::handler::human::HumanHandler;
|
||||
use fabro_workflows::handler::start::StartHandler;
|
||||
use fabro_workflow::handler::HandlerRegistry;
|
||||
use fabro_workflow::handler::agent::AgentHandler;
|
||||
use fabro_workflow::handler::exit::ExitHandler;
|
||||
use fabro_workflow::handler::human::HumanHandler;
|
||||
use fabro_workflow::handler::start::StartHandler;
|
||||
use tower::ServiceExt;
|
||||
|
||||
fn gate_registry(interviewer: Arc<dyn Interviewer>) -> HandlerRegistry {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ workspace = true
|
|||
|
||||
[dependencies]
|
||||
fabro-interview = { path = "../fabro-interview" }
|
||||
fabro-workflows = { path = "../fabro-workflows" }
|
||||
fabro-workflow = { path = "../fabro-workflow" }
|
||||
futures-util.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
[package]
|
||||
name = "fabro-workflows"
|
||||
name = "fabro-workflow"
|
||||
edition.workspace = true
|
||||
version.workspace = true
|
||||
publish = false
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
# fabro-workflows
|
||||
# fabro-workflow
|
||||
|
||||
A DOT-based pipeline runner for multi-stage AI workflows. Define workflows as Graphviz `digraph` files and execute them with pluggable handlers, conditional routing, human-in-the-loop gates, parallel branching, retry policies, and checkpoint-based recovery.
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ digraph MyPipeline {
|
|||
### Parsing and Validating a Pipeline
|
||||
|
||||
```rust
|
||||
use fabro_workflows::operations::{create, CreateOptions};
|
||||
use fabro_workflow::operations::{create, CreateOptions};
|
||||
|
||||
let dot_source = r#"digraph Simple {
|
||||
graph [goal="Run tests"]
|
||||
|
|
@ -64,8 +64,8 @@ assert_eq!(graph.goal(), "Run tests");
|
|||
### Running a Pipeline
|
||||
|
||||
```rust
|
||||
use fabro_workflows::operations::start;
|
||||
use fabro_workflows::pipeline;
|
||||
use fabro_workflow::operations::start;
|
||||
use fabro_workflow::pipeline;
|
||||
|
||||
// Use `operations::start(...)` for the full initialize -> execute -> retro -> finalize flow.
|
||||
// Use `pipeline::initialize(...)` + `pipeline::execute(...)` when you need partial lifecycle control.
|
||||
|
|
@ -159,7 +159,7 @@ pub mod test_support;
|
|||
#[doc(hidden)]
|
||||
pub mod transforms;
|
||||
|
||||
// Re-export aliases (back-compat with `fabro_workflows::transform::*` imports)
|
||||
// Re-export aliases (back-compat with `fabro_workflow::transform::*` imports)
|
||||
#[doc(hidden)]
|
||||
pub mod transform {
|
||||
pub use crate::transforms::*;
|
||||
|
|
@ -22,7 +22,7 @@ use fabro_graphviz::graph::types::Graph as GvGraph;
|
|||
use tokio::time::timeout;
|
||||
|
||||
/// Production node handler that bridges fabro-core's NodeHandler to the
|
||||
/// existing fabro-workflows Handler trait via EngineServices.
|
||||
/// existing fabro-workflow Handler trait via EngineServices.
|
||||
///
|
||||
/// On each `execute()` call, forks the context, runs the handler,
|
||||
/// then diffs and applies changes back.
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue