> ## Documentation Index
> Fetch the complete documentation index at: https://docs.codemachine.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Advanced Workflows

> Master workflow definitions with tracks, conditions, modules, and controllers.

This guide covers advanced workflow features: step types, configuration options, tracks, conditions, modules, and controllers.

***

## Workflow Definition

The workflow definition file (`.workflow.js`) is the core of your package. It defines what happens when someone runs your workflow.

### Minimum Workflow

A workflow only needs steps to run:

```javascript example.workflow.js theme={null}
export default {
  steps: [
    resolveStep('analyst-agent'),
    resolveStep('developer-agent'),
    resolveStep('reviewer-agent'),
  ],
};
```

### Full Structure

```javascript example.workflow.js theme={null}
export default {
  name: 'My Workflow',
  autonomousMode: 'never',
  specification: false,
  controller: controller('my-controller', {}),

  tracks: { /* ... */ },
  conditionGroups: [ /* ... */ ],

  steps: [ /* ... */ ],
  subAgentIds: [ /* ... */ ],
};
```

***

## Step Functions

Three functions are available globally in workflow files:

### resolveStep

Resolves a main agent from `config/main.agents.js`:

```javascript theme={null}
resolveStep('agent-id')
resolveStep('agent-id', { engine: 'claude', interactive: false })
```

### resolveModule

Resolves a module from `config/modules.js` with loop behavior:

```javascript theme={null}
resolveModule('review-module', { loopSteps: 2, loopMaxIterations: 5 })
```

### separator

Creates a visual phase separator in the workflow timeline:

```javascript theme={null}
separator("Planning Phase")
separator("⟲ Development Cycle ⟲")
```

### controller

Defines a controller agent for autonomous execution:

```javascript theme={null}
controller('controller-agent-id', { engine: 'claude' })
```

***

## Step Options

Configure how each step behaves:

| Option                 | Type                          | Description                               |
| ---------------------- | ----------------------------- | ----------------------------------------- |
| `engine`               | `string`                      | AI engine to use                          |
| `model`                | `string`                      | Specific model override                   |
| `modelReasoningEffort` | `'low' \| 'medium' \| 'high'` | Reasoning effort level                    |
| `interactive`          | `boolean`                     | Wait for user input between prompts       |
| `executeOnce`          | `boolean`                     | Run only once (skip on re-runs)           |
| `tracks`               | `string[]`                    | Only run for specified tracks             |
| `conditions`           | `string[]`                    | Only run when ALL conditions are selected |
| `conditionsAny`        | `string[]`                    | Run when ANY condition is selected        |
| `agentName`            | `string`                      | Override display name                     |
| `promptPath`           | `string \| string[]`          | Override default prompt path              |

### Engines

| Engine       | Description                |
| ------------ | -------------------------- |
| `'claude'`   | Anthropic Claude (default) |
| `'codex'`    | OpenAI Codex               |
| `'cursor'`   | Cursor AI                  |
| `'ccr'`      | Claude Code Runner         |
| `'opencode'` | OpenCode                   |

### Examples

```javascript theme={null}
// Basic step
resolveStep('analyst')

// With engine override
resolveStep('developer', { engine: 'codex' })

// Non-interactive step (auto-continues)
resolveStep('code-gen', { interactive: false })

// Conditional step
resolveStep('ui-designer', { conditions: ['has-ui'] })

// Track-specific step
resolveStep('mobile-dev', { tracks: ['mobile-app'] })

// Execute once (skip on workflow resume)
resolveStep('init', { executeOnce: true })
```

***

## Module Options

Modules extend step options with loop behavior:

| Option              | Type       | Description                            |
| ------------------- | ---------- | -------------------------------------- |
| `loopSteps`         | `number`   | How many steps to go back when looping |
| `loopMaxIterations` | `number`   | Maximum loop iterations                |
| `loopSkip`          | `string[]` | Agent IDs to skip when looping back    |

```javascript theme={null}
// Loop back 2 steps, max 5 iterations
resolveModule('review-agent', {
  loopSteps: 2,
  loopMaxIterations: 5
})

// Loop back 6 steps, skip certain agents
resolveModule('task-checker', {
  loopSteps: 6,
  loopMaxIterations: 20,
  loopSkip: ['runtime-prep', 'init']
})
```

<Info>
  Modules are agents that can loop back to earlier steps. Use them for review cycles or iterative refinement until a condition is met.
</Info>

***

## Tracks

Tracks let users choose different workflow paths. Only one track can be selected at runtime.

```javascript theme={null}
tracks: {
  question: 'Choose your project type:',
  options: {
    'landing-page': {
      label: 'Landing Page',
      description: 'Single page website'
    },
    'full-app': {
      label: 'Full Application',
      description: 'Complete web application'
    },
    'api-only': {
      label: 'API Only',
      description: 'Backend API without frontend'
    },
  },
},
```

Use tracks when you have mutually exclusive paths that significantly change the workflow.

### Track-Filtered Steps

```javascript theme={null}
steps: [
  resolveStep('planner'),
  resolveStep('frontend-dev', { tracks: ['landing-page', 'full-app'] }),
  resolveStep('backend-dev', { tracks: ['full-app', 'api-only'] }),
  resolveStep('deployer'),
]
```

***

## Condition Groups

Conditions are feature toggles that enable or disable specific steps. Unlike tracks, multiple conditions can be selected.

```javascript theme={null}
conditionGroups: [
  {
    id: 'features',
    question: 'What features do you need?',
    multiSelect: true,
    conditions: {
      'has-api': { label: 'API', description: 'REST or GraphQL API' },
      'has-auth': { label: 'Auth', description: 'User authentication' },
      'has-db': { label: 'Database', description: 'Database integration' },
    },
  },
],
```

### Nested Conditions

Conditions can have children that appear based on parent selection:

```javascript theme={null}
conditionGroups: [
  {
    id: 'deployment',
    question: 'Where will you deploy?',
    multiSelect: false,
    conditions: {
      'cloud': { label: 'Cloud', description: 'AWS, GCP, or Azure' },
      'self-hosted': { label: 'Self-hosted', description: 'Your own servers' },
    },
    children: {
      'cloud': {
        question: 'Which cloud provider?',
        multiSelect: false,
        conditions: {
          'aws': { label: 'AWS', description: 'Amazon Web Services' },
          'gcp': { label: 'GCP', description: 'Google Cloud Platform' },
          'azure': { label: 'Azure', description: 'Microsoft Azure' },
        },
      },
    },
  },
],
```

### Track-Specific Conditions

Condition groups can be limited to specific tracks:

```javascript theme={null}
conditionGroups: [
  {
    id: 'advanced-features',
    question: 'Select advanced features:',
    multiSelect: true,
    tracks: ['full-app'],  // Only shown when 'full-app' track is selected
    conditions: {
      'microservices': { label: 'Microservices', description: 'Service-based architecture' },
      'caching': { label: 'Caching', description: 'Redis or Memcached' },
    },
  },
],
```

### Condition-Filtered Steps

```javascript theme={null}
steps: [
  resolveStep('planner'),
  resolveStep('api-architect', { conditions: ['has-api'] }),
  resolveStep('auth-setup', { conditions: ['has-auth'] }),
  resolveStep('db-designer', { conditionsAny: ['has-db', 'has-api'] }),
]
```

<Note>
  Use `conditions` when ALL listed conditions must be selected. Use `conditionsAny` when ANY of the listed conditions enables the step.
</Note>

***

## Controllers

Controllers are special agents that drive workflows autonomously. They can approve step transitions without user input.

```javascript theme={null}
export default {
  name: 'My Workflow',
  controller: controller('my-controller-agent', { engine: 'claude' }),
  autonomousMode: 'always',
  // ...
};
```

<Warning>
  Controllers are in beta. The workflow can still run without a controller in manual mode.
</Warning>

### Workflow Signals MCP

Controllers and step agents communicate through the `workflow-signals` MCP. **Both must be configured** for autonomous mode to work.

<Tabs>
  <Tab title="Controller Agent">
    The controller approves or rejects step transitions.

    ```javascript main.agents.js theme={null}
    {
      id: 'my-controller-agent',
      name: 'Project Controller',
      role: 'controller',
      promptPath: path.join(promptsDir, 'controller', 'main.md'),
      mcp: [
        {
          server: 'workflow-signals',
          only: ['approve_step_transition', 'get_pending_proposal'],
        },
      ],
    }
    ```
  </Tab>

  <Tab title="Step Agents">
    Step agents propose when they're done.

    ```javascript main.agents.js theme={null}
    {
      id: 'developer',
      name: 'Developer',
      promptPath: path.join(promptsDir, 'developer', 'main.md'),
      mcp: [
        {
          server: 'workflow-signals',
          only: ['propose_step_completion'],
        },
      ],
    }
    ```
  </Tab>
</Tabs>

| Agent Type  | MCP Tools                                         |
| ----------- | ------------------------------------------------- |
| Controller  | `approve_step_transition`, `get_pending_proposal` |
| Step Agents | `propose_step_completion`                         |

<Card title="See Autonomous Example" icon="book-open" href="./workflow-examples#autonomous-greenfield-project-build">
  View a complete autonomous workflow with controller and step agents
</Card>

***

## Autonomous Mode

Control how the workflow runs:

| Value      | Behavior                                         | Toggle                                     |
| ---------- | ------------------------------------------------ | ------------------------------------------ |
| `'never'`  | Always manual - user controls each step          | Locked - can't switch to auto              |
| `'always'` | Always autonomous - controller drives everything | Locked - can't switch to manual            |
| `true`     | Defaults to autonomous mode                      | User can toggle to manual with `Shift+Tab` |
| `false`    | Defaults to manual mode                          | User can toggle to auto with `Shift+Tab`   |

```javascript theme={null}
export default {
  name: 'My Workflow',
  autonomousMode: true,  // Defaults to auto, user can toggle
  // ...
};
```

<Tip>
  Use `true` or `false` for most workflows - this gives users flexibility to switch modes. Use `'always'` or `'never'` only when you want to lock the mode.
</Tip>

***

## Sub-Agents

Sub-agents are helper agents that main agents can invoke for specialized tasks. **Both the workflow and main agent must be configured.**

### Workflow Configuration

Declare available sub-agents in your workflow file:

```javascript example.workflow.js theme={null}
export default {
  name: 'My Workflow',
  steps: [
    resolveStep('orchestrator', { interactive: false }),
  ],
  subAgentIds: [
    'code-generator',
    'test-runner',
    'doc-writer',
  ],
};
```

### Agent Coordination MCP

The main agent that orchestrates sub-agents needs the `agent-coordination` MCP:

```javascript main.agents.js theme={null}
{
  id: 'orchestrator',
  name: 'Orchestrator',
  description: 'Coordinates sub-agents for specialized tasks',
  promptPath: path.join(promptsDir, 'orchestrator', 'main.md'),
  mcp: [
    {
      server: 'agent-coordination',
      only: ['run_agents', 'get_agent_status', 'list_available_agents'],
      targets: ['code-generator', 'test-runner', 'doc-writer'],
    },
  ],
}
```

| Field     | Description                              |
| --------- | ---------------------------------------- |
| `server`  | Must be `'agent-coordination'`           |
| `only`    | Limit which MCP tools the agent can use  |
| `targets` | Restrict which sub-agents can be invoked |

<Warning>
  Both `subAgentIds` in the workflow and `agent-coordination` MCP on the main agent must be configured for sub-agent orchestration to work.
</Warning>

Sub-agents are defined in `config/sub.agents.js`.

<Card title="See Sub-Agent Example" icon="book-open" href="./workflow-examples#sub-agents-blueprint-orchestration">
  View a complete workflow using sub-agents
</Card>

***

## Specification Mode

Enable specification mode to require a spec file before running:

```javascript theme={null}
export default {
  name: 'My Workflow',
  specification: true,
  // ...
};
```

When `specification: true`, CodeMachine prompts for a specification file path at workflow start.

***

## Next Steps

<Card title="Workflow Examples" icon="code" href="./workflow-examples">
  See complete real-world workflow examples
</Card>
