The Flow DSL
Flow DSL is a domain-specific language for defining execution graphs in a textual, versionable, deterministic format. It is declarative. It defines execution graphs and operational flows, not scripts. It has no general-purpose computation primitives.
Why text
Section titled “Why text”Visual tools historically trap their workflows inside proprietary formats. Flow treats the graph’s text form as a first-class representation:
- Deterministic translation. Text to execution graph is a pure function: the same DSL always yields the same graph.
- Round-trip with the canvas. Visual edits serialize to DSL; DSL definitions render back to canvas graphs without semantic loss.
- Version-control friendly. Plain text means flows live in source control. You get pull-request review, diffs across versions, branch promotion, and code-owner enforcement.
- Reuse and sharing. DSL files are the unit of team-level template sharing.
A taste
Section titled “A taste”flow "JCL Pipeline" v1.0.0
validate-jcl[ai: "Review JCL"] { modelId: "local-llm" system: "You are a JCL reviewer. Flag any errors in the job below." input: "{{input}}"}
submit-jcl[action: "Submit JCL"] { adapter: "cli" bin: "zowe" actionId: "cli-tool" command: "jobs submit local-file"}
notify[utility: "Log outcome"] { actionId: "log" level: "info"}
validate-jcl.pass --> submit-jclsubmit-jcl --> notifyA flow has one header line, then node blocks, then edge statements. Edges route
on .pass, on .fail, or on always when the outcome is omitted. They can also
carry optional labels and opaque when conditions. The full syntax is in the
grammar reference.
Round-trip semantics
Section titled “Round-trip semantics”| Direction | Preserved |
|---|---|
| Canvas to DSL to canvas | id, type, label, every data.* key, edge source/target/outcome/label/condition |
| DSL to canvas to DSL | byte-identical, modulo whitespace normalization |
serialize(parse(s)) produces a canonical form that is itself a fixed point. It
is an invariant that is preserved across every DSL change.
Positions are not part of the DSL. Layout is a presentation concern. The parser produces a graph with zero positions, and auto-layout runs before mounting on the canvas. A layout reshuffle never produces a noisy pull request.
Storage layout
Section titled “Storage layout”Each saved template writes two files:
templates/ jcl-pipeline.flow.json # canonical, includes positions; loaded by the canvas jcl-pipeline.flow # DSL projection, regenerated on every saveThe JSON form is the source of truth for visual users. The .flow form is the
source-control export artifact.
Canvas integration
Section titled “Canvas integration”The internal graph model is canonical. Both the canvas and the DSL are projections of it. In Flow Studio, click DSL in the header to swap the canvas for a full-pane editor. Edit the text and apply it, and the parsed graph is auto-laid-out back onto the canvas.
Natural-language authoring
Section titled “Natural-language authoring”The Generate screen lets a user describe a flow in plain language. It sends that description to a loaded local LLM, or to an explicitly enabled cloud provider. It then parses the returned DSL and renders the graph for review before execution.
- It is implemented as a constrained translation task. The model produces structured DSL output only, not open-ended generation.
- Generated DSL is validated before execution.
- The translation model has no execution authority. Execution stays with the orchestration engine.
Syntax highlighting
Section titled “Syntax highlighting”The DSL is highlighted both as .flow files in VS Code and inside the Flow Code
webviews. A TextMate grammar colors files on disk, and a shared highlighter
colors the DSL shown in the sidebar. See
DSL syntax highlighting.
Going deeper
Section titled “Going deeper”- Grammar reference - the normative syntax.
- Node types - per-type data shapes.
- Examples - canonical patterns with authoring rules.
- Syntax highlighting - the TextMate grammar and the shared webview highlighter.
- Adapter references - per-adapter actions and fields.