Skip to content

WorkflowRunner: add postCommand hook to workflow steps #500

@jahala

Description

@jahala

Problem

There's no way to run an action after a step completes — run tests, call a webhook, merge a branch, notify an external system. The only workaround is adding a separate dependent deterministic step for each post-action, which clutters the workflow and doubles the step count for common patterns.

There's also no built-in HTTP/webhook step type — WorkflowStepType is limited to agent | deterministic | worktree.

Suggestion

Add an optional postAction field to WorkflowStep supporting both shell commands and HTTP calls:

interface PostAction {
    command?: string;           // shell command
    webhook?: {                 // HTTP call
        url: string;
        method?: 'POST' | 'PUT' | 'PATCH';  // default POST
        headers?: Record<string, string>;
        body?: string;          // supports {{step.output}}, {{step.name}}, {{run.id}} interpolation
    };
    failAction?: 'fail' | 'warn';  // default: 'fail'
}

interface WorkflowStep {
    postAction?: PostAction;
}

Behavior:

  • Runs after the step completes successfully, before marking the step as completed in the DB
  • Shell commands run in the step's cwd with $STEP_OUTPUT env var set
  • Webhook body supports the same {{variable}} interpolation the runner already uses for task strings
  • If it fails and failAction is 'fail' — step is marked failed (triggers retry if configured)
  • If it fails and failAction is 'warn' — emit a warning event, still mark step completed

Use cases:

# Notify external system on completion
- name: implement-feature
  type: agent
  postAction:
    webhook:
      url: https://ci.example.com/trigger
      body: '{"step": "{{step.name}}", "run": "{{run.id}}"}'

# Run tests to validate agent output
- name: write-code
  type: agent
  postAction:
    command: npm test
    failAction: fail   # retry the step if tests fail

# Merge worktree branch after agent finishes
- name: implement
  type: agent
  postAction:
    command: git add -A && git commit -m "{{step.name}}" && git checkout main && git merge --squash {{step.branch}}

Location: In spawnAndWait (runner.js), after the agent exits successfully and output is captured, but before persisting the step as completed. Shell via child_process.execSync, HTTP via fetch.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions