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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions