v1.2.0
Powerful open source workflow environment for offline usage with multiple script compatibilities and background stable running content for better multi-tasking workflows.
Built for Linux and Termux on Android. No internet required. No cloud. Just your scripts, running the way you designed them.
snflow is a terminal-based workflow runner that lets you build, visualize, and execute pipelines made of connected nodes. Each node can run a script, output text, or pass through silently. Nodes can be connected in any configuration — linear chains, branching paths, or loops.
Loops and long-running processes (like ollama serve) run in the background automatically — flow never blocks waiting for them. It peeks at their first few lines of output, shows you the PID and log location.
- Fully offline — no network calls, no dependencies beyond bash and your chosen runtimes
- Multi-language scripts — bash, python3, node, ruby supported out of the box
- Fire-and-forget execution — scripts launch in background, flow continues immediately
- Loop detection — looping scripts get a live peek (up to 5 lines) then run detached
- Persistent background processes — daemons like
ollama serveare detected and handled gracefully - Live tree output — colored, numbered, branch-art run view as workflow executes
- Multiple projects — switch between isolated workflow projects at any time
- Interactive node editor — edit node body, subtype, and language inline in the REPL
- Sort children — reorder the execution order of a node's children interactively
- Export — export any workflow to a standalone runnable bash script
- Cycle guard — infinite loops in the graph are automatically prevented
- Decision node — true/false branching node that routes to first child (true) or second child (false)
- Loop node — for-loop only node (while loops blocked for security) that iterates over a range and executes children each iteration
- Automatic parent-child variable sharing — nodes inherit context from parents/loop containers with zero manual setup
- Node context variables — nodes automatically have access to parent info, children info, loop metadata during execution
| File | Role |
|---|---|
flow |
Entry point — backwards-compatible wrapper, calls flowM.sh |
flowM.sh |
Execution engine, tree view, sort, REPL loop |
commandM.sh |
All CRUD commands — add, edit, connect, export, help |
UIM |
UI layer — colors, storage helpers, node read/write functions |
Data is stored at ~/.flowterm/<project>/ with one .node file per node and a connections file per project.
git clone <repo>
cd flow
chmod +x flow flowM.sh
./flowNo package installs required. For script nodes you need the relevant runtime (python3, node, ruby) already available in your Termux environment.
init mybot
add fetch script bash
setbody fetch echo Hello world
add log text
setbody log Done!
connect start fetch
connect fetch log
connect log end
run
Output:
● 1. start [executing...] ✓ pass
├── 2. fetch [executing...] ✓ pass [bash]
│ ├ output [fetch]
│ │ Hello world
│ │ ✓ exited · PID: 1234
├── 3. log [executing...] ✓ text
│ ├ output [log]
│ │ Done!
└── 4. end ✓ workflow complete
| Command | Description |
|---|---|
init [name] |
Create a new project with start and end nodes |
switch <project> |
Switch to an existing project |
projects |
List all projects |
rmproj <project> |
Delete a project and all its data |
| Command | Description |
|---|---|
add <name> [sub] [lang] |
Add a node — sub: passthrough, text, script, decision, loop |
setbody <name> <content> |
Set a node's body inline |
edit <name> |
Interactively edit a node's subtype, lang, and body |
show <name> |
Inspect a node's full details |
delete <name> |
Remove a node |
| Command | Description |
|---|---|
connect <from> <to> |
Link two nodes |
disconnect <from> <to> |
Remove a link |
sort <node> |
Reorder a node's children interactively |
| Command | Description |
|---|---|
list |
List current project nodes and connections |
list --all |
List all projects and their nodes |
tree |
Show workflow as a tree (no execution) |
run |
Execute the workflow |
export [file.sh] |
Export workflow to a standalone bash script |
reset |
Wipe all nodes and connections in current project |
Does nothing, just connects flow from one point to another. Useful as a junction or placeholder.
add gate passthrough
Prints a static string when executed.
add welcome text
setbody welcome Hello from flow!
Runs code in the specified language. Supports bash, sh, python, python3, node, nodejs, ruby.
add fetch script bash
setbody fetch curl -s https://example.com
Scripts are detected as long-running if they contain a loop (while, for, until) or are short commands (≤ 3 words). Long-running scripts show a live peek and run detached. Quick scripts wait for completion.
Evaluates a condition and routes flow based on true/false result. First connected child is the true path, second child is the false path.
add check decision bash
setbody check [ -f "/path/to/file" ]
connect check process_true
connect check process_false
The body should contain a condition that returns exit code 0 for true, non-zero for false. All parent/child context variables are automatically available.
Executes a for-loop and runs connected children for each iteration. Only for loops are allowed (while loops are blocked for security).
add iterate loop bash
setbody iterate for i in 1 2 3 4 5
connect iterate process_item
During loop execution, children automatically receive loop context variables without any manual setup.
Children of a node execute in the order they were connected. To change the order:
sort start
── sort children of [start] ──
1. fetch
2. ai
3. sustain
enter new order as numbers separated by spaces
example: 3 1 2
▶ 2 3 1
✓ sorted children of start:
1. ai
2. sustain
3. fetch
Every script node writes its output to:
~/.flowterm/<node-id>_bg.log
You can tail any running script live:
tail -f ~/.flowterm/fetch_bg.logDuring workflow execution, each node has automatic access to environment variables that provide information about its context in the workflow graph. No manual setup required — variables are injected automatically.
| Variable | Description |
|---|---|
FLOW_NODE_NAME |
Current node name |
FLOW_NODE_TYPE |
Node type (start, end, command) |
FLOW_NODE_SUBTYPE |
Node subtype (passthrough, text, script, decision, loop) |
FLOW_PARENTS |
Space-separated list of parent nodes (nodes that connect to this node) |
FLOW_CHILDREN |
Space-separated list of child nodes (nodes this node connects to) |
FLOW_DEPTH |
Execution depth in the workflow (starts at 0 for start node) |
Inside a loop node's execution, children automatically receive these additional variables:
| Variable | Description |
|---|---|
FLOW_LOOP_VAR |
The loop variable name (e.g., i) |
FLOW_LOOP_VALUE |
Current iteration value |
FLOW_LOOP_ITER |
Current iteration number (1-based) |
FLOW_LOOP_PARENT |
Name of the loop node (parent) |
add validate script bash
setbody validate echo "Validating for $FLOW_PARENTS with $FLOW_LOOP_VALUE..."
add process script python3
setbody process print(f"Processing as child of: {os.environ.get('FLOW_PARENTS', 'N/A')}")
add save script bash
setbody save echo "Saving iteration $FLOW_LOOP_ITER to file"
When inside a loop, each child automatically knows:
- Which node spawned it (
$FLOW_PARENTS) - Its siblings (
$FLOW_CHILDREN) - The current iteration details (
$FLOW_LOOP_VALUE,$FLOW_LOOP_ITER)
No manual variable passing needed!
add check decision bash
setbody check [ "$USER_APPROVED" == "true" ]
add approve_action script bash
setbody approve_action echo "Approved! Context: $FLOW_PARENTS"
add deny_action script bash
setbody deny_action echo "Denied! Parent was $FLOW_PARENTS"
Both branches automatically inherit all parent context.
Defined in UIM:
| Variable | Code | Color |
|---|---|---|
OR |
\033[38;5;208m |
Orange — node names, prompt |
OD |
\033[38;5;166m |
Orange dim — arrows, warnings |
GR |
\033[38;5;114m |
Green — success, end node, numbers |
RE |
\033[38;5;203m |
Red — errors |
BL |
\033[38;5;111m |
Blue — executing tag, lang |
GL |
\033[38;5;245m |
Grey light — labels, info |
GY |
\033[38;5;240m |
Grey — tree lines, pipes |
WH |
\033[38;5;255m |
White — command node names |
WD |
\033[38;5;250m |
White dim — body text, output |
Features
-
AI agent integration
-
Remote access API support
-
Templates
-
Themes
-
Bob, Greg and Jimmy
- Automatic Parent-Child Variable Sharing — All context variables injected automatically without manual setup
- Enhanced Decision Node — Simplified logic with automatic validation and improved error handling
- Enhanced Loop Node — Loop variables automatically available to all children per iteration
- Execution Depth Tracking —
FLOW_DEPTHvariable for tracking workflow hierarchy - Loop Parent Reference —
FLOW_LOOP_PARENTto identify which loop spawned a child - Bug Fixes — Variable scope issues, nested execution stability, loop variable handling
- Fixed variable scope issues in nested execution contexts
- Improved loop variable handling across iterations
- Enhanced decision node stability with better error recovery
- Better error messages for misconfigured nodes
- Decision node — true/false branching node that routes to first child (true path) or second child (false path)
- Loop node — for-loop only execution node (while loops blocked for security) that iterates over a range and executes children each iteration
- Node context variables — nodes can access
FLOW_NODE_NAME,FLOW_NODE_TYPE,FLOW_NODE_SUBTYPE,FLOW_PARENTS,FLOW_CHILDRENenvironment variables during execution - Loop variables — inside loop nodes,
FLOW_LOOP_VAR,FLOW_LOOP_VALUE, andFLOW_LOOP_ITERare available - Bug Fixes