Composition
FlowState supports composing complex workflows from simpler building blocks through sub-flows, parallel execution, and inheritance.
Sub-Flows
Section titled “Sub-Flows”Sub-flows allow a workflow to call another workflow inline, enabling modular and reusable workflow components.
Calling a Sub-Flow
Section titled “Calling a Sub-Flow”main-workflow: tool: sub-flow arguments: workflow: helper-workflow next: continue-mainThe sub-flow executes to completion before the parent continues.
Passing Variables
Section titled “Passing Variables”Pass variables to customize sub-flow behavior:
process-file: tool: sub-flow arguments: workflow: file-processor variables: input_path: "{{ source_file }}" output_format: json next: use-resultPassed variables override the sub-flow’s default values.
Accessing Sub-Flow Results
Section titled “Accessing Sub-Flow Results”Variables set by the sub-flow are namespaced:
# Sub-flow (helper-workflow) sets: result = "success"# Parent accesses as: helper-workflow::result
check-result: tool: bash arguments: command: 'echo "Sub-flow result: {{ helper-workflow::result }}"'Sub-Flow State Paths
Section titled “Sub-Flow State Paths”During sub-flow execution, the current state is tracked as parent-state/subflow-state:
main-workflow → process-file/validate-input process-file/transform-data process-file/write-output → continue-mainThis enables accurate pause/resume within nested workflows.
Sub-Flow Discovery
Section titled “Sub-Flow Discovery”Sub-flows are resolved from:
- The same directory as the parent workflow
- The project
.flowstate/directory - The user
~/.flowstate/directory
When creating an instance, FlowState copies referenced sub-flows into the instance’s workflow/ directory.
Parallel Execution
Section titled “Parallel Execution”The parallel tool runs multiple tasks concurrently:
run-tests: tool: parallel arguments: tasks: - tool: bash arguments: command: npm test -- --shard=1/3 output: var(shard1) - tool: bash arguments: command: npm test -- --shard=2/3 output: var(shard2) - tool: bash arguments: command: npm test -- --shard=3/3 output: var(shard3) next: merge-resultsParallel Task Structure
Section titled “Parallel Task Structure”Each task in the tasks array mirrors a regular state:
tasks: - tool: <tool-name> arguments: <arg>: <value> output: var(<name>) | file(<path>)Output Capture
Section titled “Output Capture”Each task can capture output independently:
gather-data: tool: parallel arguments: tasks: - tool: bash arguments: command: curl https://api1.example.com/data output: var(api1_data) - tool: bash arguments: command: curl https://api2.example.com/data output: file(./api2_data.json)Error Handling
Section titled “Error Handling”If any parallel task fails, the parallel tool returns the first non-zero exit code. Use on-error to handle failures:
run-parallel: tool: parallel arguments: tasks: - tool: bash arguments: command: ./task1.sh - tool: bash arguments: command: ./task2.sh on-error: _: handle-parallel-failure next: all-succeededSuccessful tasks complete even if others fail.
Restrictions
Section titled “Restrictions”Interactive tools cannot run in parallel:
claude-code(requires terminal)ask-user(requires user input)
These must be executed sequentially in regular states.
Workflow Inheritance
Section titled “Workflow Inheritance”Workflows can extend other workflows using the extends field:
name: code-reviewextends: new-feature
# Override or add statesstates: additional-step: tool: bash arguments: command: echo "Added by code-review"Inheritance Resolution
Section titled “Inheritance Resolution”The child workflow inherits:
- All states from the parent
- Variable defaults (child can override)
- The
start-atvalue (unless overridden)
Child states override parent states with the same name.
Extends Syntax
Section titled “Extends Syntax”Reference parent workflows by:
# Workflow name (discovered automatically)extends: base-workflow
# Relative path from workflow directoryextends: ./parent.yaml
# Project root pathextends: @/workflows/base/index.yamlUse Cases
Section titled “Use Cases”Standardized pipelines: Define a base CI workflow, extend for specific projects.
name: base-cistart-at: checkout
states: checkout: tool: bash arguments: command: git checkout {{ branch }} next: build
build: tool: bash arguments: command: echo "Override me"name: node-ciextends: base-ci
states: build: tool: bash arguments: command: npm install && npm run build next: test
test: tool: bash arguments: command: npm testPause and Resume
Section titled “Pause and Resume”The pause tool halts workflow execution until manually resumed:
await-approval: tool: pause arguments: reason: "Waiting for deployment approval" next: deployPause with Conditions
Section titled “Pause with Conditions”Specify a condition that must be met before resuming:
wait-for-build: tool: pause arguments: reason: "Waiting for CI build to complete" condition: tool: bash command: '[ -f ./build-complete.flag ]' next: deployOn resume, FlowState checks the condition:
- If satisfied (exit 0), continues to
next - If not satisfied, remains paused
Listing Paused Instances
Section titled “Listing Paused Instances”fs list --pausedShows all paused instances with their pause reason and timestamp.
Resuming Workflows
Section titled “Resuming Workflows”# Resume specific instancefs resume my-instance
# Resume all paused instancesfs resume --all
# Resume all paused instances for a workflowfs resume --workflow my-workflow
# Force resume (skip condition check)fs resume my-instance --forceComposition Patterns
Section titled “Composition Patterns”Pipeline with Gates
Section titled “Pipeline with Gates”start-at: build
states: build: tool: bash arguments: command: make build next: test
test: tool: bash arguments: command: make test next: await-approval
await-approval: tool: pause arguments: reason: "Ready for production deployment" next: deploy
deploy: tool: bash arguments: command: make deploy-prodFan-Out/Fan-In
Section titled “Fan-Out/Fan-In”start-at: prepare
states: prepare: tool: bash arguments: command: echo "Starting parallel processing" next: process-parallel
process-parallel: tool: parallel arguments: tasks: - tool: sub-flow arguments: workflow: process-shard variables: shard: "1" - tool: sub-flow arguments: workflow: process-shard variables: shard: "2" - tool: sub-flow arguments: workflow: process-shard variables: shard: "3" next: aggregate
aggregate: tool: bash arguments: command: ./merge-shards.sh