Skip to content

DSL examples

These are worked examples that cover the patterns the flow generator is expected to handle. Each one pairs an English prompt, the kind of text you would type into the Generate tab, with the canonical DSL. Every example round-trips through the parser.

These rules prevent the most common runtime failures. A node that parses can still be rejected by its adapter or fail in the shell.

  1. Always emit every required field for the chosen adapter action. fs write-file requires content. fs edit-file requires both oldString and newString. All fs actions require workspaceRoot.
  2. content must match the target file’s real format. The content of a .yaml file must be YAML. Never write JSON into a file that is not JSON.
  3. Shell commands run under POSIX sh -c, so use no bash-only syntax. That means no process substitution, no [[ ... ]], and no &>.
  4. Don’t read a {{node.field}} output from a node that may not have produced one. Route values from fallible steps through a .fail branch. A node that consumes a branch’s output must be reached only from that branch.
  5. Use exactly the commands and arguments the request describes. Do not invent flags. Strict, frozen, and CI variants change the behavior.
  6. Never re-run a command just to read its output. Reference {{nodeId.payload.stdout}} or have the first command write a log file the next node reads.
  7. String literals are single-line, so escape rather than break them. Write inner quotes as \" and newlines as \n, and keep each string on one physical line.
  8. One edge per line. Never chain a --> b --> c.
  9. Fields are flat scalars or arrays, never nested objects.

“Install dependencies, build the project, then run the test suite.”

flow "linear-build" v1
deps[action: "Install"] {
adapter: "shell"
actionId: "pnpm"
args: "install"
}
build[action: "Build"] {
adapter: "shell"
actionId: "pnpm"
args: "build"
}
test[action: "Test"] {
adapter: "shell"
actionId: "cargo"
args: "test --workspace"
}
deps --> build
build --> test

“Run the test suite; if it passes, deploy; if it fails, post to the webhook.”

flow "test-and-route" v1
test[action: "Test"] {
adapter: "shell"
actionId: "cargo"
args: "test --workspace"
}
deploy[action: "Deploy"] {
adapter: "shell"
actionId: "kubectl"
args: "rollout restart deploy/api"
}
notify[action: "Notify"] {
adapter: "shell"
actionId: "curl"
args: "-fsS -X POST https://hooks.example.com/notify"
}
test.pass --> deploy
test.fail --> notify

“Run linting and unit tests in parallel, then commit if both pass.”

flow "parallel-checks" v1
lint[action: "Lint"] {
adapter: "shell"
actionId: "pnpm"
args: "run lint"
}
unit[action: "Unit tests"] {
adapter: "shell"
actionId: "pnpm"
args: "test"
}
commit[action: "Commit"] {
adapter: "shell"
actionId: "git"
args: "commit -am wip"
}
lint.pass --> commit
unit.pass --> commit

“Fetch the artifact; on failure, retry the same node.”

flow "fetch-with-retry" v1
fetch[action: "Fetch artefact"] {
adapter: "shell"
actionId: "curl"
args: "-fsSL https://example.com/artefact.tar.gz -o /tmp/a.tar.gz"
}
fetch.fail --> fetch

“Build the project; if it fails, ask the local model to suggest a fix.”

flow "build-then-explain" v1
build[action: "Build"] {
adapter: "shell"
actionId: "cargo"
args: "build --release"
}
explain[ai: "Explain failure"] {
modelId: "local-llm"
system: "You are a build engineer. Explain the failure concisely."
input: "{{input}}"
}
build.fail --> explain

“Have the local model interpret the build log, log a one-line summary, then run the suggested fix command.”

flow "interpret-and-act" v1
interpret[ai: "Interpret log"] {
modelId: "local-llm"
system: "Summarise the build log in one line and suggest a fix command."
input: "{{input}}"
}
log[utility: "Log summary"] {
actionId: "log"
level: "info"
}
run[action: "Run suggested fix"] {
adapter: "shell"
actionId: "run-command"
command: "true"
}
interpret --> log
log --> run

“List z/OS jobs with the zowe CLI.”

flow "list-jobs" v1
list[action: "List jobs"] {
adapter: "cli"
bin: "zowe"
actionId: "cli-tool"
command: "jobs list"
}

“Submit a job, wait, then run a shell command that fetches the result.”

flow "submit-wait-fetch" v1
submit[action: "Submit job"] {
adapter: "cli"
bin: "zowe"
actionId: "cli-tool"
command: "jobs submit local-file"
}
cooldown[utility: "Cool down"] {
actionId: "sleep"
durationMs: 5000
}
fetch[action: "Fetch result"] {
adapter: "shell"
actionId: "curl"
args: "-fsS https://example.com/result.json -o /tmp/result.json"
}
submit --> cooldown
cooldown --> fetch

“Download an installer from a URL, then run it locally.” The utility:download action writes into the downloads directory and exposes path on the node payload.

flow "fetch-and-run" v1
fetch[utility: "Fetch installer"] {
adapter: "utility"
actionId: "download"
url: "https://example.com/install.sh"
filename: "install.sh"
}
run[action: "Run installer"] {
adapter: "shell"
actionId: "run-command"
command: "sh {{fetch.payload.path}}"
}
fetch --> run

Capture the first error on failure, without re-running

Section titled “Capture the first error on failure, without re-running”

“Build the project; if the build fails, grep the first error from the build output and write it to a file. Don’t re-run the build, and don’t write the file when the build passes.”

flow "build-capture-error" v1
build[action: "Build"] {
adapter: "shell"
actionId: "run-command"
command: "./build.sh > build.log 2>&1"
workspaceRoot: "/abs/project"
}
capture[action: "Capture first error"] {
adapter: "shell"
actionId: "run-command"
command: "grep -iE 'error|fail' build.log | head -n 1 > build-error.txt"
workspaceRoot: "/abs/project"
}
build.fail --> capture

Three things this gets right: no re-run (the build redirects to a log the capture step greps), one inbound path (capture is reached only via build.fail), and portable shell with no flags the prompt didn’t ask for.

“Set up the project - install deps then build - and retry the whole setup up to twice if it fails; then run the tests.”

flow "setup-then-test" v1
subflow "Setup" retry 2 {
install[action: "Install deps"] {
adapter: "shell"
actionId: "pnpm"
args: "install"
}
build[action: "Build"] {
adapter: "shell"
actionId: "pnpm"
args: "build"
}
install --> build
}
test[action: "Run tests"] {
adapter: "shell"
actionId: "pnpm"
args: "test"
}
build --> test

The Setup unit runs install and then build. If either step fails, the whole unit re-runs, up to two extra times. Only group steps that form a coherent phase, and do not wrap the entire flow in a single sub-flow.