Build a flow with a coding agent
Copy page
In this tutorial, you prepare an empty repository for a coding agent with sluice init. Then you ask the agent for a flow. The agent writes the files, validates them, deploys them to your Sluice server, runs the flow and reads the result. When the run fails, the agent reads the logs and fixes the cause.
The tutorial uses Claude Code. Another agent works the same way when it reads AGENTS.md or the skill file. Use Sluice with coding agents shows the setup for Cursor.
Before you start
Section titled “Before you start”You need these things:
- A running Sluice server. The stack of Run your first flow works.
- The
sluicebinary on yourPATH, from a release after v0.1.2. Install it withcurl -fsSL https://raw.githubusercontent.com/alternayte/sluice/main/install.sh | sh.sluice versionprints its version. - Claude Code or another coding agent.
Create an API token for the agent
Section titled “Create an API token for the agent”The agent deploys files and runs flows. Both actions need a token with the editor role.
- In Sluice, click API tokens under Settings in the sidebar.
- Click Create token.
- Type
coding-agentin Name and select Editor in Role. - Type
30in Expiry in days. - Click Create token, then click Copy.
Prepare the repository
Section titled “Prepare the repository”-
Create an empty repository:
Terminal window mkdir my-flowscd my-flowsgit init -
Write the skill and the agent instructions:
Terminal window sluice initThe command prints the files that it wrote and the line that each flow file starts with:
wrote .claude/skills/sluice/SKILL.mdwrote AGENTS.mdStart each flow file with this line, so editors and agents validate it:# yaml-language-server: $schema=https://sluice-docs.pages.dev/schemas/flow.schema.json -
Set the URL of the server and the token in the shell that starts the agent:
Terminal window export SLUICE_URL=http://localhost:8080export SLUICE_TOKEN=slu_paste-your-token-here
sluice init writes two files:
| File | Content |
|---|---|
.claude/skills/sluice/SKILL.md |
The Sluice skill: the work loop, the exit codes, the flow rules, the task types, the templates and the outputs. Claude Code loads it when a task touches a flow file or the sluice CLI. |
AGENTS.md |
A Sluice section between <!-- sluice:begin --> and <!-- sluice:end -->. It tells every agent to read the skill and lists the three commands of the loop. |
This is the section in AGENTS.md:
<!-- sluice:begin -->## Sluice
This repository holds Sluice flows. Read `.claude/skills/sluice/SKILL.md` before you change a `*.flow.yaml` file or `namespace.yaml`.
- Validate a namespace directory: `sluice validate <dir> --json`.- Deploy it as a new version: `sluice namespaces push <dir> --namespace <name>`.- Run a flow and wait for the end: `sluice run <namespace>/<flow> --wait`.- The client commands read SLUICE_URL and SLUICE_TOKEN.<!-- sluice:end -->When AGENTS.md exists, sluice init adds the section at the end and keeps the rest of the file. A second run prints unchanged for each file. A file that you changed stays as it is, unless you add --force.
The skill matches the version of the sluice binary that wrote it. After you update the binary, run sluice init again.
Ask the agent for a flow
Section titled “Ask the agent for a flow”Start Claude Code in the repository:
claudeType a request with the directory, the namespace and the goal:
Write a Sluice flow in the directory orders/ for the namespace orders.The flow counts the orders of a day with a Python script and prints a summary.The day is an input. Create the namespace if it does not exist. Run the flow when it is valid.Claude Code asks before it runs a command. Allow the sluice commands.
Follow the loop
Section titled “Follow the loop”The skill gives the agent one loop for each change: edit, validate, deploy, run, read, fix. A session looks like the steps below. The files and the text of your session differ.
-
The agent writes
orders/orders.flow.yamlandorders/count_orders.py. The flow file starts with theyaml-language-serverline. -
The agent validates the directory offline:
Terminal window sluice validate orders --jsonThe first attempt has a task ID with a hyphen. The command exits with
1and prints each error with its line and code:{"code": "invalid_format","path": "tasks[0].id","line": 4,"column": 9,"message": "'count-orders' does not match pattern '^[a-z][a-z0-9_]*$'"}The agent renames the task to
count_ordersand validates again. The command exits with0. -
The agent deploys the directory as a new version of the namespace:
Terminal window sluice namespaces push orders --namespace orders --createcreated namespace ordersorders version 1: 2 added, 0 updated, 0 deleted+ count_orders.py+ orders.flow.yaml -
The agent runs the flow and waits for the end:
Terminal window sluice run orders/orders --waitThe script reads a variable that nobody set. The log lines stream to stderr, and the command exits with
10:[count_orders#1] KeyError: 'ORDER_COUNT'FAILED orders/orders 01a0d510-755e-7753-902c-f3730ff8f33a in 371mshttp://localhost:8080/executions/01a0d510-755e-7753-902c-f3730ff8f33atask count_orders failed: exit code 1: KeyError: 'ORDER_COUNT' -
The agent reads the failed execution and the logs of the failed task:
Terminal window sluice executions get 01a0d510-755e-7753-902c-f3730ff8f33asluice executions logs 01a0d510-755e-7753-902c-f3730ff8f33a --task count_ordersTASK ATTEMPT STATE DURATION EXIT ERRORcount_orders 1 FAILED 352ms 1 exit code 1: KeyError: 'ORDER_COUNT'summary 1 SKIPPED — — -
The agent fixes the script, validates, pushes and runs again.
sluice namespaces pushsends only the changed file. The run exits with0:[count_orders#1] counted 5 orders on 2026-09-24[summary#1] orders on 2026-09-24: 5SUCCESS orders/orders 01a0d510-54ac-7524-ac61-4a8d3a015a3c in 602ms
The agent knows the end state from the exit code alone: 0 for SUCCESS, 10 for FAILED, 11 for TIMED_OUT. Exit codes lists all codes.
Check the result
Section titled “Check the result”Open Sluice and click Namespaces, then orders. The Versions tab shows one version for each push, with the message Push from the sluice CLI. Click Executions in the sidebar. The list shows the failed run and the successful run of orders/orders.
This is a flow like the one the agent wrote:
# yaml-language-server: $schema=https://sluice-docs.pages.dev/schemas/flow.schema.jsonid: ordersdescription: Count the orders of a day, then print a summary.inputs: - { id: day, type: string, default: "2026-09-24" }tasks: - id: count_orders type: script file: count_orders.py args: ["--day", "${{ inputs.day }}"] - id: summary type: command depends_on: [count_orders] command: ["echo", "orders on ${{ inputs.day }}: ${{ tasks.count_orders.outputs.orders }}"]outputs: orders: ${{ tasks.count_orders.outputs.orders }}The first line connects the file to the flow JSON Schema. An editor with a YAML language server completes the fields and marks errors while you type.