Claude
Skills
Sign in
Back

cpf-workflow-runner

Included with Lifetime
$97 forever

Run, resume, and manage checkpointflow workflows interactively. Use this skill whenever the user wants to run a workflow, execute a YAML pipeline, resume a paused run, check workflow status, cancel a run, or interact with cpf at runtime. Also triggers on phrases like "run the workflow", "execute this", "resume the run", "what's the status", or when the user provides input for a waiting workflow step.

General

What this skill does


# cpf-workflow-runner

Run checkpointflow workflows interactively, handling pause/resume cycles.

## Core concept: Audience-driven dispatch

Checkpointflow workflows pause at `await_event` steps. Each pause has an `audience` field in the envelope's `wait` block that tells you who should act:

- **`audience: "agent"`** — The prompt is your work assignment. Do the work (read code, write files, run tools), produce JSON matching `input_schema`, and resume immediately. Never present agent pauses to the user.
- **`audience: "user"`** — Present the prompt and collect input from the user via structured prompts, then resume with their answers.

This is the only dispatch you need. The envelope tells you everything — no need to read the workflow YAML to figure out what to do.

### Agent pause example

```json
{
  "wait": {
    "audience": "agent",
    "event_name": "codebase_analysis",
    "prompt": "Analyze the codebase for feature \"run-delete\" in area \"gui\".\nScan src/checkpointflow/gui/ and identify source files, tests, dependencies...",
    "input_schema": {
      "type": "object",
      "required": ["area", "source_dir", "notes"],
      "properties": {
        "area": { "type": "string" },
        "source_dir": { "type": "string" },
        "notes": { "type": "string" }
      }
    }
  }
}
```

When you see this:
1. Read the prompt — it describes exactly what to do
2. Do the work (read files, explore code, run tools, etc.)
3. Build JSON matching `input_schema` with your real findings
4. Resume immediately: `cpf resume --run-id <id> --event codebase_analysis --input '<json>'`

### User pause example

```json
{
  "wait": {
    "audience": "user",
    "event_name": "scope_choice",
    "prompt": "Feature: run-delete\nHow should we scope this?\n- full: Complete implementation...\n- minimal: Core logic only...",
    "input_schema": {
      "type": "object",
      "required": ["scope"],
      "properties": {
        "scope": { "type": "string", "enum": ["full", "minimal", "spike", "cancel"] }
      }
    }
  }
}
```

When you see this:
1. Present the prompt context to the user
2. Collect their input via structured prompts
3. Resume: `cpf resume --run-id <id> --event scope_choice --input '{"scope": "full"}'`

## Critical: Collect input through structured prompts, not chat

Every time the workflow needs input from the user — whether collecting workflow inputs before `cpf run`, gathering event data at an `await_event` pause, or confirming a cancellation — present structured choices using whatever interactive prompt tool is available in your environment (e.g., a question/answer UI, a selection picker, a form). The user should experience the workflow as a guided flow where they pick options and provide values through structured prompts, not by typing free-form messages into chat.

Do not say "what would you like to do?" and wait for a text reply. Always present choices and collect input through a structured prompt tool.

## Running a workflow

### Step 1: Discover and understand the flow

Use `cpf flows` to list available workflows, then `cpf flows --detail <id>` to see everything about a specific flow — description, required/optional inputs with types and descriptions, step overview, and a ready-to-use run command:

```bash
cpf flows                        # List all available workflows
cpf flows --detail <id>          # Full detail: inputs, steps, run command
```

The detail output tells you exactly what inputs to collect and gives you the `cpf run` command template. No need to read the workflow YAML.

### Step 2: Collect inputs and execute

Use the inputs section from `cpf flows --detail` to collect values from the user via structured prompts. **Read the `description` field on each input** — it explains what the value should be and often includes examples or hints (e.g., "Directory containing the tools/ subdirectory").

For inputs you can infer from context, do so without asking:
- `repo_dir` → current working directory
- `artifact_dir` → create a temp directory
- `author` → `git config user.name`
- Paths referencing the current project → resolve from the working directory

Only prompt the user for inputs that are genuinely ambiguous. For each prompted input, build options using this priority:

1. **`enum` values** → one option per enum value (the user picks one)
2. **`type: boolean`** → two options: "Yes" / "No"
3. **`examples` array** → one option per example value (user picks one or types custom)
4. **No examples** → craft 2 realistic example values from the description

**Never create placeholder options** like "Type value" or "Enter value". Every option should be a real, plausible value the user might choose.

Then run:

```bash
cpf run -f <path> --input '<json>'
```

Parse the JSON envelope from stdout. The `ok`, `status`, and `exit_code` fields tell you what happened.

### Step 3: Handle the result

Based on `exit_code`:

| Exit code | What happened | What to do |
|-----------|--------------|------------|
| 0 | Completed | Show the `result` to the user. Done. |
| 40 | Waiting for input | Enter the interactive loop (dispatches on audience). |
| 10 | Validation error | Show `error.message`. Check inputs match the schema. |
| 30 | Step failed | Immediately run `cpf inspect --run-id <id>`, read the `stderr_path` from the failed step result, and diagnose the root cause before reporting to the user. |
| 80 | Unsupported step | Tell the user this step kind isn't implemented yet. |
| Other | Error | Show the error and suggest next steps. |

## Interactive loop (await_event handling)

This is the core of the skill. When a workflow pauses (exit code 40), the envelope contains a `wait` block. Dispatch on `wait.audience`:

### Agent audience (`wait.audience == "agent"`)

The prompt is your work assignment. Do not present it to the user.

1. **Read `wait.prompt`** — it describes the work to do, with full context from previous steps already interpolated in.
2. **Do the work** — read code, write files, run tools, explore the codebase — whatever the prompt asks for.
3. **Build event JSON** matching `wait.input_schema` with your real results.
4. **Resume immediately:**
   ```bash
   cpf resume --run-id <run_id> --event <event_name> --input '<event_json>'
   ```
5. **Parse the new envelope** and loop back.

### User audience (`wait.audience == "user"`)

Present the checkpoint to the user and collect their input.

1. **Read the wait block** — extract `prompt`, `input_schema`, `event_name`, and `run_id`.

2. **Collect input** — map each field in `input_schema` to a structured prompt using the same option-building rules from Step 2 above.

   **Multiple fields:** If `input_schema` has multiple `required` fields, ask them together in a single prompt call when possible. Optional fields can be asked in a follow-up or skipped.

   **Use the `prompt` from the wait block** as context when presenting the questions — it explains what the user is deciding on.

3. **Build the event JSON** from the user's answers. Map each answer back to the field name in `input_schema`. Make sure the result matches the schema types (strings stay strings, numbers get parsed).

4. **Resume the workflow:**
   ```bash
   cpf resume --run-id <run_id> --event <event_name> --input '<event_json>'
   ```

5. **Parse the new envelope** and loop back:
   - If exit code 0 → done, show result
   - If exit code 40 → another await_event, dispatch on audience again
   - If error → show it

Keep looping until the workflow completes, fails, or the user wants to stop.

## Status and inspection

When the user asks about a run:

```bash
cpf status --run-id <run_id>    # Quick status check
cpf inspect --run-id <run_id>   # Full execution history
```

If the user doesn't remember the run ID, check recent output from previous commands in the conversation — the `run_id` is in every envelope.

## Cancelling a run

When the user wants to cancel a waiting run:

```bash
cpf cancel --run-id <run_id> --reason "<reason>"
```

Use

Related in General