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

PropertyTypeDescription
name*stringPipeline display name, used to generate the filename.
description*stringOne-line summary of what this pipeline does.
version*stringSemantic version string, e.g. "1.0.0".
variables*Record<string, string>Key-value pairs for runtime variable substitution.
budgetnumberMaximum 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.
Example pipeline JSON
json
{
  "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

PropertyTypeDescription
id*stringUnique node identifier, e.g. "node-1".
name*stringDisplay name shown on the canvas.
type*string"ai-task" | "shell" | "git" | "parallel" | "loop" | "approval-gate" | "sub-pipeline" | "comment"
instructions*stringThe command, prompt, or instructions for this node.
agentstringAgent name for ai-task nodes. References .claude/agents/{name}.md.
modelstringClaude 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.
timeoutnumberExecution timeout in seconds. Process is killed if exceeded.
childrenstring[]Child node IDs. Required for parallel and loop nodes.
pipeline_refstringReferenced pipeline name. Required for sub-pipeline nodes.
loop_configLoopConfigLoop configuration: separator, max_iterations, timeout, model. Required for loop nodes.
requires_toolsstring[]MCP tool names required for ai-task nodes.
position*{ x: number, y: number }Canvas coordinates for the node.

Edge Schema

PropertyTypeDescription
id*stringUnique edge identifier.
from*stringSource node ID.
to*stringTarget node ID.
condition"success" | "failure" | stringExecution condition. Node only runs if predecessor matches this condition.

Conditional branching

Edges with 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.

Variable substitution syntax
text
# 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

Variables are prompted for when you run a pipeline if input fields are configured. You can set default values in the pipeline definition and override them at runtime.

Node Output Passing

Downstream nodes can reference the output of upstream nodes using the {output.NODE_ID} syntax in their instructions.

Output reference syntax
text
# 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

Output passing only works for nodes that have already completed successfully. If the referenced node was skipped or failed, the placeholder is replaced with an empty string.

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.

Naming convention
text
# 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.md

Info

The _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_ref set 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 from and to fields 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.

How generation works
text
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 editing

Info

Generated pipelines include auto-created agent markdown files in .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.

Rename behavior
text
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

If other pipelines reference this one via sub-pipeline nodes, you must manually update their pipeline_ref values after renaming. AgentFlow does not auto-update cross-pipeline references.