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

# Build and run custom workflows in dotbot

> Define a workflow.json pipeline with prompt, script, mcp, task_gen, barrier, and interview tasks, configure the kickstart form, and install the workflow into your project.

A dotbot workflow defines a multi-step pipeline that the AI runs in your project. Each workflow is a directory with two manifests: `workflow.json` declares the pipeline, and `manifest.json` holds the workflow's name and description. A project can have several workflows installed at once, and each one runs and re-runs independently with `dotbot run <name>`.

## When to create a custom workflow

Create a custom workflow when the built-in workflows do not match your process. Common reasons include:

* Your pipeline needs a specific sequence of AI and deterministic steps.
* You want to integrate with an internal system, such as an internal Jira project or a custom API.
* You need conditional tasks that run only when specific files or states exist.
* You want to share a standard engineering process across several teams.

If a built-in workflow covers your case, prefer it. Custom workflows need maintenance as your process changes.

## Anatomy of workflow\.json

`workflow.json` declares the workflow's identity, its prerequisites, the kickstart form, and the task pipeline. The example below shows the common top-level fields:

```json workflow.json theme={null}
{
  "name": "my-workflow",
  "version": "1.0",
  "description": "What this workflow does.",
  "icon": "terminal",
  "min_dotbot_version": "3.5",
  "requires": {
    "env_vars": [
      {
        "var": "AZURE_DEVOPS_PAT",
        "name": "Azure DevOps PAT",
        "message": "Required for repo operations",
        "hint": "Set AZURE_DEVOPS_PAT in .env.local"
      }
    ],
    "mcp_servers": [
      {
        "name": "atlassian",
        "message": "Atlassian MCP server must be registered",
        "hint": "Run 'claude mcp add atlassian'"
      }
    ],
    "cli_tools": [
      {
        "name": "git",
        "message": "git CLI is required",
        "hint": "Install from https://git-scm.com/"
      }
    ]
  },
  "form": {
    "modes": [
      {
        "id": "new_project",
        "condition": ["!.bot/workspace/product/mission.md"],
        "label": "New Project",
        "description": "Describe your project and dotbot will create your product documents.",
        "button": "LAUNCH PROJECT",
        "prompt_placeholder": "What are you building?",
        "show_interview": true,
        "show_files": true
      },
      {
        "id": "has_docs",
        "condition": ".bot/workspace/product/mission.md",
        "hidden": true
      }
    ]
  },
  "tasks": []
}
```

Accompany `workflow.json` with a `manifest.json` that carries the name and a longer description shown alongside the workflow:

```json manifest.json theme={null}
{
  "name": "my-workflow",
  "description": "Full description shown when listing and selecting the workflow."
}
```

## Task types

dotbot resolves each task by its `type` field against a registered executor. Six task types ship with the framework.

| Type        | What it does                                                                                                                                                                                                        |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `prompt`    | Two-phase AI execution: an analysis phase explores the codebase and builds context, then an implementation phase writes code. This is the most common type, and the only built-in type that runs an analysis phase. |
| `script`    | Runs a PowerShell script declared on the task, captures stdout and stderr, and reports success from the exit code. Use it for setup steps, data transforms, and anything where the output must be predictable.      |
| `mcp`       | Calls an MCP tool with declared arguments through the runtime's tool dispatch. Use it when you need to invoke a tool without an AI deciding how to call it.                                                         |
| `task_gen`  | Runs a PowerShell generator script that produces child task files, then validates and queues them. Use it to expand a pipeline dynamically based on what an earlier step discovered.                                |
| `barrier`   | Completes once its declared dependencies are satisfied. It runs no code itself and exists to synchronise a group of parallel tasks before the pipeline continues.                                                   |
| `interview` | Runs the interactive interview loop and verifies that `interview-summary.md` was produced. Use it to gather project details from the user before later tasks run.                                                   |

<Note>
  Only `prompt` and `interview` tasks involve the AI provider for their own execution. The `script`, `mcp`, `task_gen`, and `barrier` types run deterministically and do not run an analysis phase.
</Note>

## Common task fields

Each entry in the `tasks` array shares a common set of fields. A `prompt` task names a prompt file with `workflow`; a `script` or `task_gen` task names a script with `script`.

```json theme={null}
{
  "name": "Task Groups",
  "type": "prompt",
  "workflow": "03a-plan-task-groups.md",
  "depends_on": ["Generate Decisions"],
  "outputs": ["task-groups.json"],
  "model": "best",
  "commit": {
    "paths": ["workspace/product/"],
    "message": "chore(workflow): phase 2a — task groups"
  },
  "priority": 3
}
```

| Field                                | Purpose                                                                     |
| ------------------------------------ | --------------------------------------------------------------------------- |
| `name`                               | Unique task name, referenced by `depends_on` on other tasks.                |
| `type`                               | One of the six task types above.                                            |
| `workflow`                           | For `prompt` tasks, the prompt file in the workflow's `prompts/` directory. |
| `script`                             | For `script` and `task_gen` tasks, the script to run.                       |
| `depends_on`                         | Names of tasks that must complete before this task starts.                  |
| `outputs`                            | Files the task is expected to produce.                                      |
| `outputs_dir` and `min_output_count` | For generators, the directory and minimum number of files expected.         |
| `model`                              | Tier override (`fast`, `balanced`, or `best`) for this task.                |
| `commit`                             | A `paths` and `message` pair that commits the task's output.                |
| `priority`                           | Execution order within a dependency level.                                  |
| `on_failure`                         | Set to `halt` to stop the pipeline when this task fails.                    |

## Adding dependencies between tasks

Use `depends_on` to declare which tasks must finish before a task starts. Reference tasks by their `name`:

```json theme={null}
{
  "tasks": [
    {
      "name": "Product Documents",
      "type": "prompt",
      "workflow": "01-plan-product.md",
      "priority": 0
    },
    {
      "name": "Generate Decisions",
      "type": "prompt",
      "workflow": "01b-generate-decisions.md",
      "depends_on": ["Product Documents"],
      "priority": 2
    }
  ]
}
```

Use a `barrier` task to wait for a group of parallel tasks before continuing:

```json theme={null}
{
  "name": "Execute Research",
  "type": "barrier",
  "depends_on": ["Plan Internet Research", "Plan Atlassian Research"],
  "priority": 6
}
```

## Configuring the kickstart form

The `form` block controls what users see when they open the workflow in the dashboard before running it. Each entry in `modes` renders a different form state based on a file-existence condition:

* A condition without `!` is true when the file exists.
* A condition with a leading `!` is true when the file does not exist.

Set `hidden: true` on a mode to suppress the form when its condition is met. This is useful when a repeat run should skip the interview because the project is already set up.

<Tip>
  Set `show_interview: true` on the first-run mode to prompt users for project details, and set the follow-up mode to `hidden: true` so repeat runs go straight to execution.
</Tip>

## Workflow directory structure

A workflow directory holds the two manifests plus the supporting content the pipeline references:

```
<workflow>/
├── workflow.json      # Pipeline manifest
├── manifest.json      # Name and description
├── prompts/           # Prompt templates (.md files referenced by task workflow fields)
├── Scripts/           # PowerShell scripts referenced by script and task_gen tasks
├── settings/          # Workflow-specific settings overrides
├── hooks/             # Lifecycle and verify scripts
├── agents/            # Agent definitions (AGENT.md)
└── systems/mcp/tools/ # Optional MCP tools for this workflow
```

Built-in workflows live under `<install>/content/workflows/<name>/`. When you install or scaffold a workflow into a project, dotbot materialises it at `.bot/content/workflows/<name>/`, where you can edit it without changing the framework copy. A project workflow with the same name as a built-in one takes precedence, which is how you customise a built-in workflow without forking it.

Prompt files in `prompts/` are Markdown templates. The runtime injects context, such as the task description, product documents, and codebase index, before passing them to the provider.

## Installing and running the workflow

<Steps>
  <Step title="Install the workflow during project initialisation">
    Pass the workflow name to `dotbot init`:

    ```powershell theme={null}
    dotbot init -Workflow start-from-jira
    ```
  </Step>

  <Step title="Add a workflow to an existing project">
    Use `dotbot workflow add` after the project is initialised:

    ```powershell theme={null}
    dotbot workflow add <name>
    ```
  </Step>

  <Step title="Install from an enterprise registry">
    Prefix the workflow name with the registry name and a colon:

    ```powershell theme={null}
    dotbot init -Workflow registry:custom-workflow
    ```
  </Step>

  <Step title="Run the workflow">
    Start a run from the dashboard, or run it directly from the CLI:

    ```powershell theme={null}
    dotbot run <name>
    ```
  </Step>
</Steps>

<Warning>
  The `requires` block is validated before a workflow runs. If a required environment variable, MCP server, or CLI tool is missing, dotbot reports a clear error with the `hint` text so you know exactly what to configure before retrying.
</Warning>
