Pipelines
Pipelines are the core data structure in AgentFlow. They define a directed acyclic graph (DAG) of nodes connected by edges, stored as JSON files in your project.
File Format
Pipelines are stored as .claude/pipelines/{name}.pipeline.json in your project root. The name is sanitized from the pipeline's display name (lowercased, spaces to hyphens).
Pipeline Schema
| Property | Type | Description |
|---|---|---|
name* | string | Pipeline display name, used to generate the filename. |
description* | string | One-line summary of what this pipeline does. |
version* | string | Semantic version string, e.g. "1.0.0". |
variables* | Record<string, string> | Key-value pairs for runtime variable substitution. |
budget | number | Maximum cost (USD) per run. Execution halts when exceeded. |
nodes* | PipelineNode[] | Array of pipeline nodes (see Node Schema below). |
edges* | PipelineEdge[] | Array of connections between nodes. |
{
"name": "Review and Deploy",
"description": "AI code review followed by test and deploy",
"version": "1.0.0",
"variables": {
"BASE_BRANCH": "main",
"DEPLOY_TARGET": "staging"
},
"nodes": [
{
"id": "node-1",
"name": "Code Review",
"type": "ai-task",
"instructions": "Review all changed files for bugs and security issues",
"agent": "code-reviewer",
"inputs": [],
"outputs": [],
"position": { "x": 250, "y": 0 }
},
{
"id": "node-2",
"name": "Run Tests",
"type": "shell",
"instructions": "npm run test -- --coverage",
"inputs": [],
"outputs": [],
"retry": { "max": 2, "delay": 5 },
"timeout": 300,
"position": { "x": 250, "y": 150 }
},
{
"id": "node-3",
"name": "Deploy Approval",
"type": "approval-gate",
"instructions": "Review AI changes before deploying to ${DEPLOY_TARGET}",
"inputs": [],
"outputs": [],
"position": { "x": 250, "y": 300 }
},
{
"id": "node-4",
"name": "Deploy",
"type": "git",
"instructions": "git push origin HEAD:${BASE_BRANCH}",
"inputs": [],
"outputs": [],
"position": { "x": 250, "y": 450 }
}
],
"edges": [
{ "id": "edge-1", "from": "node-1", "to": "node-2", "condition": "success" },
{ "id": "edge-2", "from": "node-2", "to": "node-3", "condition": "success" },
{ "id": "edge-3", "from": "node-3", "to": "node-4" }
]
}Node Schema
| Property | Type | Description |
|---|---|---|
id* | string | Unique node identifier, e.g. "node-1". |
name* | string | Display name shown on the canvas. |
type* | string | "ai-task" | "shell" | "git" | "parallel" | "loop" | "approval-gate" | "sub-pipeline" | "comment" |
instructions* | string | The command, prompt, or instructions for this node. |
agent | string | Agent name for ai-task nodes. References .claude/agents/{name}.md. |
model | string | Claude model override: "opus", "sonnet", or "haiku". AI task nodes only. |
inputs* | string[] | Input variable names consumed by this node. |
outputs* | string[] | Output variable names produced by this node. |
retry | { max: number, delay: number } | Retry policy. max = attempts, delay = seconds between retries. |
timeout | number | Execution timeout in seconds. Process is killed if exceeded. |
children | string[] | Child node IDs. Required for parallel and loop nodes. |
pipeline_ref | string | Referenced pipeline name. Required for sub-pipeline nodes. |
loop_config | LoopConfig | Loop configuration: separator, max_iterations, timeout, model. Required for loop nodes. |
requires_tools | string[] | MCP tool names required for ai-task nodes. |
position* | { x: number, y: number } | Canvas coordinates for the node. |
Edge Schema
| Property | Type | Description |
|---|---|---|
id* | string | Unique edge identifier. |
from* | string | Source node ID. |
to* | string | Target node ID. |
condition | "success" | "failure" | string | Execution condition. Node only runs if predecessor matches this condition. |
Conditional branching
condition: "success" only fire when the source node succeeds (exit code 0). Edges with condition: "failure" fire on non-zero exit. Edges with no condition always fire.Pipeline Variables
Variables are defined at the pipeline level and substituted into node instructions at runtime.
# In pipeline variables:
{ "BASE_BRANCH": "main", "JIRA_KEY": "PROJ-123" }
# In node instructions, use ${VAR_NAME}:
"git merge origin/${BASE_BRANCH}"
"Fix issue ${JIRA_KEY}"
# Runtime inputs also work:
"{input.varname}" or "{{varname}}"Tip
Node Output Passing
Downstream nodes can reference the output of upstream nodes using the {output.NODE_ID} syntax in their instructions.
# Reference the output of a previous node by its ID:
"Summarize the following report: {output.node-1}"
# The placeholder is replaced at runtime with the full
# stdout captured from the referenced node's execution.Tip
Pipeline-Agent Namespace
When generating pipelines with AI, AgentFlow auto-creates agent Markdown files with a special prefix to avoid collisions with your existing agents.
# Auto-generated agents use the _pipeline-- prefix:
.claude/agents/_pipeline--code-reviewer.md
.claude/agents/_pipeline--security-scanner.md
# Your hand-written agents are unaffected:
.claude/agents/code-reviewer.md
.claude/agents/my-custom-agent.mdInfo
_pipeline-- prefix signals that the agent was auto-generated. You can edit these files freely — they won't be overwritten unless you regenerate the pipeline.Validation Rules
Before execution, AgentFlow validates pipelines:
- Sub-pipeline references: Every sub-pipeline node must have
pipeline_refset to an existing pipeline name. - MCP tools: If a node specifies
requires_tools, those tools must exist in.mcp.json. - Circular references: Sub-pipeline chains are tracked. Circular references (A → B → A) are blocked.
- Edge integrity: All edge
fromandtofields must reference existing node IDs. - Cycle detection: The DAG is checked for cycles before execution. Pipelines with circular node dependencies are rejected.
- Self-reference protection: Sub-pipeline nodes cannot reference the pipeline they belong to, preventing infinite recursion.
AI Pipeline Generation
AgentFlow can generate pipelines from natural language descriptions using the Claude CLI.
1. User provides a description:
"CI/CD pipeline that reviews code, runs tests, and deploys"
2. AgentFlow sends a comprehensive schema prompt to Claude CLI:
claude --print "{full_prompt_with_schema}"
3. Claude returns a JSON pipeline matching the schema
4. AgentFlow validates all edge references and applies defaults
5. The generated pipeline appears on the canvas ready for editingInfo
.claude/agents/ with names prefixed by _pipeline--.Atomic Pipeline Rename
Renaming a pipeline updates both the display name and the filename in a single atomic operation.
1. User edits the pipeline name in the header
2. AgentFlow sanitizes the new name (lowercase, spaces → hyphens)
3. The .pipeline.json file is renamed on disk
4. The file watcher detects the change and updates the sidebar
5. All sub-pipeline references to the old name are NOT auto-updated
(you must update them manually)Sub-pipeline references
pipeline_ref values after renaming. AgentFlow does not auto-update cross-pipeline references.