prodigy 0.4.4

Turn ad-hoc Claude sessions into reproducible development pipelines with parallel AI agents
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
## Command-Level Options

All command types (`claude:`, `shell:`, `foreach:`) support additional fields for advanced control and orchestration. These options enable timeout management, output capture, error handling, conditional execution, and more.

## Core Options

### timeout

Sets a maximum execution time for the command (in seconds). If the command exceeds this duration, it will be terminated.

**Type**: `Option<u64>` (optional, no default timeout)

**Source**: `src/config/command.rs:383`

```yaml
commands:
  # 5 minute timeout for test suite
  - shell: "npm test"
    timeout: 300

  # 10 minute timeout for Claude implementation
  - claude: "/implement feature"
    timeout: 600

  # No timeout (runs until completion)
  - shell: "cargo build --release"
```

**Real-world examples**:
- `workflows/debtmap-reduce.yml:6` - 15 minute timeout for coverage generation
- `workflows/complex-build-pipeline.yml:23` - 10 minute timeout for benchmarks
- `workflows/documentation-drift.yml:48` - 5 minute timeout for doc tests

### id

Assigns an identifier to the command for referencing its outputs in subsequent commands via workflow variables.

**Type**: `Option<String>` (optional)

**Source**: `src/config/command.rs:351-352`

```yaml
commands:
  - shell: "git rev-parse --short HEAD"
    id: "get_commit"
    capture_output: "commit_hash"

  # Use the captured output
  - shell: "echo 'Building commit ${commit_hash}'"
```

### commit_required

Specifies whether the command is expected to create git commits. Prodigy tracks commits for workflow provenance and rollback.

**Type**: `bool` (default: `false`)

**Source**: `src/config/command.rs:354-356`

```yaml
commands:
  # Claude commands that modify code should commit
  - claude: "/prodigy-coverage"
    commit_required: true

  # Test commands typically don't commit
  - shell: "cargo test"
    commit_required: false

  # Linting fixes may commit changes
  - claude: "/prodigy-lint"
    commit_required: true
```

**Real-world examples**:
- `workflows/coverage.yml:5,11` - Coverage and implementation commands
- `workflows/documentation-drift.yml:19,23,27` - Documentation update commands
- `workflows/implement-with-tests.yml:27,31` - Test vs implementation distinction

## Output Capture Options

### capture_output

Captures command output and stores it in a workflow variable. Supports both boolean mode (captures to default variable) and variable name mode (captures to named variable).

**Type**: `Option<CaptureOutputConfig>` where `CaptureOutputConfig` is:
```rust
enum CaptureOutputConfig {
    Boolean(bool),      // Simple capture (true/false)
    Variable(String),   // Capture to named variable
}
```

**Source**: `src/config/command.rs:367-368, 403-411`

```yaml
commands:
  # Capture to default variable name (shell.output)
  - shell: "echo 'Starting analysis...'"
    capture_output: true

  # Capture to custom variable name
  - shell: "ls -la | wc -l"
    capture_output: "file_count"

  # Use the captured variable
  - shell: "echo 'Found ${file_count} files'"

  # Disable capture explicitly
  - shell: "cargo build"
    capture_output: false
```

**Real-world examples**:
- `examples/capture-output-custom-vars.yml:10-48` - Custom variable names
- `workflows/implement-with-tests.yml:26,55` - Test output capture
- `workflows/complex-build-pipeline.yml:17,24` - Build diagnostics

### capture_format

Specifies how to parse captured output. Determines the data type and structure of the captured variable.

**Type**: `Option<String>` with values: `string` (default), `json`, `lines`, `number`, `boolean`

**Source**: `src/config/command.rs:391-392`, `src/cook/workflow/variables.rs:250-265`

**Supported formats**:
- `string` - Raw string output (default)
- `json` - Parse as JSON object/array
- `lines` - Split into array of lines
- `number` - Parse as numeric value
- `boolean` - Parse as boolean (`true`/`false`)

```yaml
commands:
  # Capture as JSON object
  - shell: "cat package.json"
    capture_output: "package_info"
    capture_format: "json"

  # Access JSON fields
  - shell: "echo 'Package: ${package_info.name} v${package_info.version}'"

  # Capture as boolean
  - shell: "cargo test --quiet && echo true || echo false"
    capture_output: "tests_passed"
    capture_format: "boolean"

  # Capture as number
  - shell: "find src -name '*.rs' | wc -l"
    capture_output: "file_count"
    capture_format: "number"

  # Capture as array of lines
  - shell: "git diff --name-only"
    capture_output: "changed_files"
    capture_format: "lines"
```

**Real-world examples**:
- `examples/capture-json-processing.yml:9-54` - JSON metadata extraction
- `examples/capture-conditional-flow.yml:9-37` - Boolean and number formats
- `examples/capture-parallel-analysis.yml:9-101` - Multi-format capture pipeline

### capture_streams

Controls which output streams to capture from command execution. By default, only stdout is captured.

**Type**: `Option<String>` or structured configuration

**Source**: `src/config/command.rs:394-396`, `src/cook/workflow/variables.rs:267-292`

**Captured fields**:
- `stdout` - Standard output (default: `true`)
- `stderr` - Standard error (default: `false`)
- `exit_code` - Process exit code (default: `true`)
- `success` - Whether command succeeded (default: `true`)
- `duration` - Execution duration (default: `true`)

```yaml
commands:
  # Capture all streams and metadata
  - shell: "cargo build --release"
    capture_output: "build_result"
    capture_streams:
      stdout: true
      stderr: true
      exit_code: true
      success: true
      duration: true

  # Access captured fields
  - shell: |
      echo "Build Success: ${build_result.success}"
      echo "Exit Code: ${build_result.exit_code}"
      echo "Duration: ${build_result.duration}s"
```

**Real-world examples**:
- `examples/capture-conditional-flow.yml:44-51` - Multi-stream capture with conditionals

### output_file

Redirects command output to a file. This option is defined in the type definition but not yet widely used in the codebase.

**Type**: `Option<String>` (file path)

**Source**: `src/config/command.rs:398-400`

```yaml
commands:
  - shell: "cargo test --verbose"
    output_file: "test-results.txt"

  - shell: "cargo doc --no-deps"
    output_file: "docs/api-output.log"
```

**Note**: This feature is defined but no production examples currently exist. Consider contributing examples if you use this option.

## Error Handling

### on_failure

Specifies commands to execute when the main command fails. Supports automatic retry with configurable attempts and workflow failure control.

**Type**: `Option<TestDebugConfig>` with fields:
- `claude: String` - Claude command to run on failure
- `max_attempts: u32` - Maximum retry attempts (default: 3)
- `fail_workflow: bool` - Whether to fail workflow after max attempts (default: `false`)
- `commit_required: bool` - Whether debug command should commit (default: `true`)

**Source**: `src/config/command.rs:370-372, 166-183`

```yaml
commands:
  # Retry tests with automated fixing
  - shell: "cargo test"
    on_failure:
      claude: "/prodigy-debug-test-failure --output ${shell.output}"
      max_attempts: 3
      fail_workflow: false

  # Critical check that must pass
  - shell: "just fmt-check && just lint"
    on_failure:
      claude: "/prodigy-lint ${shell.output}"
      max_attempts: 5
      fail_workflow: true

  # Doc test failures with commit requirement
  - shell: "cargo test --doc"
    on_failure:
      claude: "/prodigy-fix-doc-tests --output ${shell.output}"
      max_attempts: 2
      fail_workflow: false
      commit_required: true
```

**Real-world examples**:
- `workflows/coverage-with-test-debug.yml:13-23` - Test debugging with retries
- `workflows/debtmap-reduce.yml:58-70` - Critical quality gates
- `workflows/documentation-drift.yml:47-53` - Doc test recovery

### on_success

Executes another command when the main command succeeds. Enables chaining of dependent operations.

**Type**: `Option<Box<WorkflowStepCommand>>` (nested command)

**Source**: `src/config/command.rs:374-376`

```yaml
commands:
  # Chain successful operations
  - shell: "cargo check"
    on_success:
      shell: "cargo build --release"
      on_success:
        shell: "cargo test --release"

  # Nested success/failure handlers
  - shell: "cargo test"
    capture_output: "test_output"
    on_failure:
      claude: "/prodigy-debug-test-failures '${test_output}'"
      commit_required: true
      on_success:
        # After fixing, verify tests pass
        shell: "cargo test"
        on_failure:
          claude: "/prodigy-fix-test-failures '${shell.output}' --deep-analysis"

  # Success notification
  - shell: "cargo test --release"
    capture_output: "final_results"
    on_success:
      shell: "echo '✅ All tests passing!'"
```

**Real-world examples**:
- `workflows/implement-with-tests.yml:28-40,61-63` - Nested test-fix-verify loops
- `workflows/complex-build-pipeline.yml:7-13` - Build pipeline chaining

## Conditional Execution

### when

Evaluates a boolean expression to determine whether to execute the command. Supports variable interpolation and boolean logic.

**Type**: `Option<String>` (boolean expression)

**Source**: `src/config/command.rs:387-388`

```yaml
commands:
  # Capture test status
  - shell: "cargo test --quiet && echo true || echo false"
    capture_output: "tests_passed"
    capture_format: "boolean"

  # Conditional execution based on test results
  - shell: "echo 'Running coverage analysis...'"
    when: "${tests_passed}"

  # Multiple conditions
  - shell: "cargo build --release"
    when: "${tests_passed} && ${lint_passed}"
    capture_output: "build_output"

  # Conditional deployment
  - shell: |
      if [ "${tests_passed}" = "true" ] && [ "${build_output.success}" = "true" ]; then
        echo "✅ Deployment ready!"
      fi
    when: "${tests_passed}"
```

**Real-world examples**:
- `examples/capture-conditional-flow.yml:20-51` - Multi-stage conditional pipeline

## Advanced Options

### validate

Configures implementation completeness validation with automatic gap detection and filling.

**Type**: `Option<ValidationConfig>` (validation configuration)

**Source**: `src/config/command.rs:378-380`

```yaml
commands:
  - claude: "/implement-feature"
    validate:
      force_refresh: false
      max_cache_age: 300
```

**Note**: See validation documentation for comprehensive coverage of this feature.

### analysis

Specifies per-step analysis requirements for code quality and coverage tracking.

**Type**: `Option<AnalysisConfig>` with fields:
- `force_refresh: bool` - Force fresh analysis even if cached (default: `false`)
- `max_cache_age: u64` - Maximum cache age in seconds (default: 300)

**Source**: `src/config/command.rs:116-126`

```yaml
commands:
  - claude: "/implement-feature"
    analysis:
      force_refresh: true
      max_cache_age: 600
```

### env

Sets command-specific environment variables that override workflow-level and system environment variables.

**Type**: `HashMap<String, String>` (key-value pairs)

**Source**: `src/config/command.rs:143-145`

```yaml
commands:
  - shell: "cargo build"
    env:
      RUST_BACKTRACE: "1"
      CARGO_INCREMENTAL: "0"

  - claude: "/analyze-code"
    env:
      DEBUG_MODE: "true"
      LOG_LEVEL: "trace"
```

## Option Combinations

### Test-Fix-Verify Pattern

Combines output capture, error handling, and conditionals for robust test workflows:

```yaml
commands:
  # Initial test run
  - shell: "cargo test"
    capture_output: "test_output"
    commit_required: false
    on_failure:
      # Automated fix on failure
      claude: "/prodigy-debug-test-failures '${test_output}'"
      commit_required: true
      max_attempts: 3
      on_success:
        # Verify fix worked
        shell: "cargo test"
        commit_required: false
```

### Conditional Pipeline Pattern

Uses capture formats and conditionals for decision-making workflows:

```yaml
commands:
  # Capture test status as boolean
  - shell: "cargo test --quiet && echo true || echo false"
    capture_output: "tests_passed"
    capture_format: "boolean"

  # Capture coverage as number
  - shell: "cargo tarpaulin --output-dir coverage | grep -oP '\\d+\\.\\d+(?=%)' | head -1"
    capture_output: "coverage_percent"
    capture_format: "number"
    when: "${tests_passed}"

  # Deploy only if quality gates pass
  - shell: "echo 'Deploying to production...'"
    when: "${tests_passed} && ${coverage_percent} >= 80"
```

### Parallel Capture Pattern

Captures multiple metrics in parallel for aggregation:

```yaml
commands:
  # Capture metadata
  - shell: "find src -name '*.rs' | wc -l"
    capture_output: "total_files"
    capture_format: "number"

  # Build summary JSON
  - shell: |
      echo '{
        "repository": "'$(basename $(pwd))'",
        "total_files": ${total_files},
        "timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
      }'
    capture_output: "metadata"
    capture_format: "json"
```

## Troubleshooting

### Command Times Out

**Problem**: Command exceeds timeout and is terminated

**Solutions**:
- Increase `timeout` value
- Optimize command performance
- Split into multiple smaller commands
- Remove timeout for commands with unpredictable duration

### Capture Format Mismatch

**Problem**: Error parsing captured output with specified format

**Solutions**:
- Verify command output matches expected format (use `echo` to inspect)
- Add format validation to command output
- Use `capture_format: "string"` as fallback
- Check for extra whitespace or unexpected characters

### on_failure Not Triggering

**Problem**: Failure handler doesn't execute when command fails

**Solutions**:
- Verify command actually returns non-zero exit code
- Check `max_attempts` hasn't been exceeded
- Ensure `on_failure` syntax is correct (nested under command)
- Review workflow logs for execution details

### Variable Not Available

**Problem**: `${variable}` not found or empty in subsequent command

**Solutions**:
- Verify `capture_output` is set with correct variable name
- Check command actually produces output (not empty)
- Ensure `capture_format` matches output type
- Use default values: `${var|default:fallback}`

## See Also

- [Environment Configuration](environment-configuration.md) - Workflow-level environment configuration
- [Timeout Configuration](../advanced/timeout-configuration.md) - Advanced timeout strategies
- [Parallel Iteration with Foreach](../advanced/parallel-iteration-with-foreach.md) - Foreach command with parallel options
- [Examples](../examples.md) - Complete workflow examples