@calmo/task-runner 3.0.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/.jules/nexus.md +5 -0
  2. package/CHANGELOG.md +26 -0
  3. package/coverage/coverage-final.json +8 -6
  4. package/coverage/index.html +13 -13
  5. package/coverage/lcov-report/index.html +13 -13
  6. package/coverage/lcov-report/src/EventBus.ts.html +4 -4
  7. package/coverage/lcov-report/src/TaskGraphValidator.ts.html +38 -38
  8. package/coverage/lcov-report/src/TaskRunner.ts.html +194 -20
  9. package/coverage/lcov-report/src/TaskRunnerBuilder.ts.html +1 -1
  10. package/coverage/lcov-report/src/TaskRunnerExecutionConfig.ts.html +17 -2
  11. package/coverage/lcov-report/src/TaskStateManager.ts.html +34 -34
  12. package/coverage/lcov-report/src/WorkflowExecutor.ts.html +30 -30
  13. package/coverage/lcov-report/src/contracts/RunnerEvents.ts.html +1 -1
  14. package/coverage/lcov-report/src/contracts/index.html +1 -1
  15. package/coverage/lcov-report/src/index.html +9 -9
  16. package/coverage/lcov-report/src/strategies/DryRunExecutionStrategy.ts.html +178 -0
  17. package/coverage/lcov-report/src/strategies/RetryingExecutionStrategy.ts.html +355 -0
  18. package/coverage/lcov-report/src/strategies/StandardExecutionStrategy.ts.html +3 -3
  19. package/coverage/lcov-report/src/strategies/index.html +35 -5
  20. package/coverage/lcov.info +328 -214
  21. package/coverage/src/EventBus.ts.html +4 -4
  22. package/coverage/src/TaskGraphValidator.ts.html +38 -38
  23. package/coverage/src/TaskRunner.ts.html +194 -20
  24. package/coverage/src/TaskRunnerBuilder.ts.html +1 -1
  25. package/coverage/src/TaskRunnerExecutionConfig.ts.html +17 -2
  26. package/coverage/src/TaskStateManager.ts.html +34 -34
  27. package/coverage/src/WorkflowExecutor.ts.html +30 -30
  28. package/coverage/src/contracts/RunnerEvents.ts.html +1 -1
  29. package/coverage/src/contracts/index.html +1 -1
  30. package/coverage/src/index.html +9 -9
  31. package/coverage/src/strategies/DryRunExecutionStrategy.ts.html +178 -0
  32. package/coverage/src/strategies/RetryingExecutionStrategy.ts.html +355 -0
  33. package/coverage/src/strategies/StandardExecutionStrategy.ts.html +3 -3
  34. package/coverage/src/strategies/index.html +35 -5
  35. package/dist/TaskRunner.d.ts +12 -0
  36. package/dist/TaskRunner.js +47 -2
  37. package/dist/TaskRunner.js.map +1 -1
  38. package/dist/TaskRunnerExecutionConfig.d.ts +5 -0
  39. package/dist/TaskStep.d.ts +3 -0
  40. package/dist/contracts/TaskRetryConfig.d.ts +8 -0
  41. package/dist/contracts/TaskRetryConfig.js +2 -0
  42. package/dist/contracts/TaskRetryConfig.js.map +1 -0
  43. package/dist/index.d.ts +2 -0
  44. package/dist/index.js +1 -0
  45. package/dist/index.js.map +1 -1
  46. package/dist/strategies/DryRunExecutionStrategy.d.ts +16 -0
  47. package/dist/strategies/DryRunExecutionStrategy.js +25 -0
  48. package/dist/strategies/DryRunExecutionStrategy.js.map +1 -0
  49. package/dist/strategies/RetryingExecutionStrategy.d.ts +12 -0
  50. package/dist/strategies/RetryingExecutionStrategy.js +74 -0
  51. package/dist/strategies/RetryingExecutionStrategy.js.map +1 -0
  52. package/openspec/changes/add-concurrency-control/proposal.md +6 -6
  53. package/openspec/changes/add-task-retry-policy/proposal.md +8 -5
  54. package/openspec/changes/archive/2026-01-18-add-workflow-preview/proposal.md +13 -0
  55. package/openspec/changes/archive/2026-01-18-add-workflow-preview/tasks.md +7 -0
  56. package/openspec/changes/feat-per-task-timeout/proposal.md +25 -0
  57. package/openspec/changes/feat-per-task-timeout/tasks.md +27 -0
  58. package/package.json +1 -1
  59. package/src/TaskRunner.ts +60 -2
  60. package/src/TaskRunnerExecutionConfig.ts +5 -0
  61. package/src/TaskStep.ts +3 -0
  62. package/src/contracts/TaskRetryConfig.ts +8 -0
  63. package/src/index.ts +2 -0
  64. package/src/strategies/DryRunExecutionStrategy.ts +31 -0
  65. package/src/strategies/RetryingExecutionStrategy.ts +90 -0
  66. package/test-report.xml +122 -82
  67. package/openspec/changes/add-workflow-preview/proposal.md +0 -12
  68. package/openspec/changes/add-workflow-preview/tasks.md +0 -7
@@ -25,28 +25,28 @@
25
25
  <div class='fl pad1y space-right2'>
26
26
  <span class="strong">100% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>208/208</span>
28
+ <span class='fraction'>261/261</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
33
  <span class="strong">100% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>78/78</span>
35
+ <span class='fraction'>99/99</span>
36
36
  </div>
37
37
 
38
38
 
39
39
  <div class='fl pad1y space-right2'>
40
40
  <span class="strong">100% </span>
41
41
  <span class="quiet">Functions</span>
42
- <span class='fraction'>39/39</span>
42
+ <span class='fraction'>51/51</span>
43
43
  </div>
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
47
  <span class="strong">100% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>206/206</span>
49
+ <span class='fraction'>257/257</span>
50
50
  </div>
51
51
 
52
52
 
@@ -84,13 +84,13 @@
84
84
  <div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
85
85
  </td>
86
86
  <td data-value="100" class="pct high">100%</td>
87
- <td data-value="203" class="abs high">203/203</td>
87
+ <td data-value="219" class="abs high">219/219</td>
88
88
  <td data-value="100" class="pct high">100%</td>
89
- <td data-value="70" class="abs high">70/70</td>
89
+ <td data-value="74" class="abs high">74/74</td>
90
90
  <td data-value="100" class="pct high">100%</td>
91
- <td data-value="38" class="abs high">38/38</td>
91
+ <td data-value="42" class="abs high">42/42</td>
92
92
  <td data-value="100" class="pct high">100%</td>
93
- <td data-value="201" class="abs high">201/201</td>
93
+ <td data-value="215" class="abs high">215/215</td>
94
94
  </tr>
95
95
 
96
96
  <tr>
@@ -114,13 +114,13 @@
114
114
  <div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
115
115
  </td>
116
116
  <td data-value="100" class="pct high">100%</td>
117
- <td data-value="5" class="abs high">5/5</td>
117
+ <td data-value="42" class="abs high">42/42</td>
118
118
  <td data-value="100" class="pct high">100%</td>
119
- <td data-value="8" class="abs high">8/8</td>
119
+ <td data-value="25" class="abs high">25/25</td>
120
120
  <td data-value="100" class="pct high">100%</td>
121
- <td data-value="1" class="abs high">1/1</td>
121
+ <td data-value="9" class="abs high">9/9</td>
122
122
  <td data-value="100" class="pct high">100%</td>
123
- <td data-value="5" class="abs high">5/5</td>
123
+ <td data-value="42" class="abs high">42/42</td>
124
124
  </tr>
125
125
 
126
126
  </tbody>
@@ -131,7 +131,7 @@
131
131
  <div class='footer quiet pad2 space-top1 center small'>
132
132
  Code coverage generated by
133
133
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
134
- at 2026-01-18T16:53:50.068Z
134
+ at 2026-01-18T18:46:49.776Z
135
135
  </div>
136
136
  <script src="prettify.js"></script>
137
137
  <script>
@@ -158,7 +158,7 @@
158
158
  <span class="cline-any cline-neutral">&nbsp;</span>
159
159
  <span class="cline-any cline-neutral">&nbsp;</span>
160
160
  <span class="cline-any cline-neutral">&nbsp;</span>
161
- <span class="cline-any cline-yes">56x</span>
161
+ <span class="cline-any cline-yes">58x</span>
162
162
  <span class="cline-any cline-neutral">&nbsp;</span>
163
163
  <span class="cline-any cline-neutral">&nbsp;</span>
164
164
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -205,10 +205,10 @@
205
205
  <span class="cline-any cline-neutral">&nbsp;</span>
206
206
  <span class="cline-any cline-neutral">&nbsp;</span>
207
207
  <span class="cline-any cline-neutral">&nbsp;</span>
208
- <span class="cline-any cline-yes">294x</span>
208
+ <span class="cline-any cline-yes">306x</span>
209
209
  <span class="cline-any cline-neutral">&nbsp;</span>
210
210
  <span class="cline-any cline-neutral">&nbsp;</span>
211
- <span class="cline-any cline-yes">294x</span>
211
+ <span class="cline-any cline-yes">306x</span>
212
212
  <span class="cline-any cline-yes">14x</span>
213
213
  <span class="cline-any cline-yes">14x</span>
214
214
  <span class="cline-any cline-yes">14x</span>
@@ -322,7 +322,7 @@ export class EventBus&lt;TContext&gt; {
322
322
  <div class='footer quiet pad2 space-top1 center small'>
323
323
  Code coverage generated by
324
324
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
325
- at 2026-01-18T16:53:50.068Z
325
+ at 2026-01-18T18:46:49.776Z
326
326
  </div>
327
327
  <script src="../prettify.js"></script>
328
328
  <script>
@@ -243,26 +243,26 @@
243
243
  <span class="cline-any cline-neutral">&nbsp;</span>
244
244
  <span class="cline-any cline-neutral">&nbsp;</span>
245
245
  <span class="cline-any cline-neutral">&nbsp;</span>
246
- <span class="cline-any cline-yes">54x</span>
246
+ <span class="cline-any cline-yes">56x</span>
247
247
  <span class="cline-any cline-neutral">&nbsp;</span>
248
248
  <span class="cline-any cline-neutral">&nbsp;</span>
249
- <span class="cline-any cline-yes">54x</span>
250
- <span class="cline-any cline-yes">54x</span>
251
- <span class="cline-any cline-yes">20139x</span>
249
+ <span class="cline-any cline-yes">56x</span>
250
+ <span class="cline-any cline-yes">56x</span>
251
+ <span class="cline-any cline-yes">20143x</span>
252
252
  <span class="cline-any cline-yes">3x</span>
253
253
  <span class="cline-any cline-neutral">&nbsp;</span>
254
254
  <span class="cline-any cline-neutral">&nbsp;</span>
255
255
  <span class="cline-any cline-neutral">&nbsp;</span>
256
256
  <span class="cline-any cline-neutral">&nbsp;</span>
257
257
  <span class="cline-any cline-neutral">&nbsp;</span>
258
- <span class="cline-any cline-yes">20136x</span>
258
+ <span class="cline-any cline-yes">20140x</span>
259
259
  <span class="cline-any cline-neutral">&nbsp;</span>
260
260
  <span class="cline-any cline-neutral">&nbsp;</span>
261
261
  <span class="cline-any cline-neutral">&nbsp;</span>
262
262
  <span class="cline-any cline-neutral">&nbsp;</span>
263
- <span class="cline-any cline-yes">54x</span>
264
- <span class="cline-any cline-yes">20139x</span>
265
- <span class="cline-any cline-yes">20166x</span>
263
+ <span class="cline-any cline-yes">56x</span>
264
+ <span class="cline-any cline-yes">20143x</span>
265
+ <span class="cline-any cline-yes">20168x</span>
266
266
  <span class="cline-any cline-yes">6x</span>
267
267
  <span class="cline-any cline-neutral">&nbsp;</span>
268
268
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -274,9 +274,9 @@
274
274
  <span class="cline-any cline-neutral">&nbsp;</span>
275
275
  <span class="cline-any cline-neutral">&nbsp;</span>
276
276
  <span class="cline-any cline-neutral">&nbsp;</span>
277
- <span class="cline-any cline-yes">54x</span>
277
+ <span class="cline-any cline-yes">56x</span>
278
278
  <span class="cline-any cline-neutral">&nbsp;</span>
279
- <span class="cline-any cline-yes">54x</span>
279
+ <span class="cline-any cline-yes">56x</span>
280
280
  <span class="cline-any cline-yes">5x</span>
281
281
  <span class="cline-any cline-neutral">&nbsp;</span>
282
282
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -284,21 +284,21 @@
284
284
  <span class="cline-any cline-neutral">&nbsp;</span>
285
285
  <span class="cline-any cline-neutral">&nbsp;</span>
286
286
  <span class="cline-any cline-neutral">&nbsp;</span>
287
- <span class="cline-any cline-yes">49x</span>
288
- <span class="cline-any cline-yes">49x</span>
289
- <span class="cline-any cline-yes">20131x</span>
287
+ <span class="cline-any cline-yes">51x</span>
288
+ <span class="cline-any cline-yes">51x</span>
289
+ <span class="cline-any cline-yes">20135x</span>
290
290
  <span class="cline-any cline-neutral">&nbsp;</span>
291
291
  <span class="cline-any cline-neutral">&nbsp;</span>
292
- <span class="cline-any cline-yes">49x</span>
293
- <span class="cline-any cline-yes">49x</span>
292
+ <span class="cline-any cline-yes">51x</span>
293
+ <span class="cline-any cline-yes">51x</span>
294
294
  <span class="cline-any cline-neutral">&nbsp;</span>
295
- <span class="cline-any cline-yes">49x</span>
296
- <span class="cline-any cline-yes">20124x</span>
295
+ <span class="cline-any cline-yes">51x</span>
296
+ <span class="cline-any cline-yes">20128x</span>
297
297
  <span class="cline-any cline-yes">3x</span>
298
298
  <span class="cline-any cline-neutral">&nbsp;</span>
299
299
  <span class="cline-any cline-neutral">&nbsp;</span>
300
- <span class="cline-any cline-yes">20121x</span>
301
- <span class="cline-any cline-yes">20121x</span>
300
+ <span class="cline-any cline-yes">20125x</span>
301
+ <span class="cline-any cline-yes">20125x</span>
302
302
  <span class="cline-any cline-neutral">&nbsp;</span>
303
303
  <span class="cline-any cline-neutral">&nbsp;</span>
304
304
  <span class="cline-any cline-yes">5x</span>
@@ -315,7 +315,7 @@
315
315
  <span class="cline-any cline-neutral">&nbsp;</span>
316
316
  <span class="cline-any cline-neutral">&nbsp;</span>
317
317
  <span class="cline-any cline-neutral">&nbsp;</span>
318
- <span class="cline-any cline-yes">49x</span>
318
+ <span class="cline-any cline-yes">51x</span>
319
319
  <span class="cline-any cline-neutral">&nbsp;</span>
320
320
  <span class="cline-any cline-neutral">&nbsp;</span>
321
321
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -339,34 +339,34 @@
339
339
  <span class="cline-any cline-neutral">&nbsp;</span>
340
340
  <span class="cline-any cline-neutral">&nbsp;</span>
341
341
  <span class="cline-any cline-neutral">&nbsp;</span>
342
- <span class="cline-any cline-yes">20121x</span>
342
+ <span class="cline-any cline-yes">20125x</span>
343
343
  <span class="cline-any cline-neutral">&nbsp;</span>
344
- <span class="cline-any cline-yes">20121x</span>
345
- <span class="cline-any cline-yes">20121x</span>
346
- <span class="cline-any cline-yes">20121x</span>
344
+ <span class="cline-any cline-yes">20125x</span>
345
+ <span class="cline-any cline-yes">20125x</span>
346
+ <span class="cline-any cline-yes">20125x</span>
347
347
  <span class="cline-any cline-neutral">&nbsp;</span>
348
- <span class="cline-any cline-yes">20121x</span>
348
+ <span class="cline-any cline-yes">20125x</span>
349
349
  <span class="cline-any cline-neutral">&nbsp;</span>
350
350
  <span class="cline-any cline-neutral">&nbsp;</span>
351
351
  <span class="cline-any cline-neutral">&nbsp;</span>
352
352
  <span class="cline-any cline-neutral">&nbsp;</span>
353
353
  <span class="cline-any cline-neutral">&nbsp;</span>
354
354
  <span class="cline-any cline-neutral">&nbsp;</span>
355
- <span class="cline-any cline-yes">20121x</span>
356
- <span class="cline-any cline-yes">40273x</span>
357
- <span class="cline-any cline-yes">40273x</span>
355
+ <span class="cline-any cline-yes">20125x</span>
356
+ <span class="cline-any cline-yes">40279x</span>
357
+ <span class="cline-any cline-yes">40279x</span>
358
358
  <span class="cline-any cline-neutral">&nbsp;</span>
359
- <span class="cline-any cline-yes">40273x</span>
360
- <span class="cline-any cline-yes">20157x</span>
361
- <span class="cline-any cline-yes">20157x</span>
359
+ <span class="cline-any cline-yes">40279x</span>
360
+ <span class="cline-any cline-yes">20159x</span>
361
+ <span class="cline-any cline-yes">20159x</span>
362
362
  <span class="cline-any cline-neutral">&nbsp;</span>
363
- <span class="cline-any cline-yes">20157x</span>
363
+ <span class="cline-any cline-yes">20159x</span>
364
364
  <span class="cline-any cline-neutral">&nbsp;</span>
365
365
  <span class="cline-any cline-yes">5x</span>
366
366
  <span class="cline-any cline-yes">5x</span>
367
367
  <span class="cline-any cline-neutral">&nbsp;</span>
368
368
  <span class="cline-any cline-neutral">&nbsp;</span>
369
- <span class="cline-any cline-yes">20152x</span>
369
+ <span class="cline-any cline-yes">20154x</span>
370
370
  <span class="cline-any cline-yes">7x</span>
371
371
  <span class="cline-any cline-yes">7x</span>
372
372
  <span class="cline-any cline-yes">7x</span>
@@ -380,13 +380,13 @@
380
380
  <span class="cline-any cline-neutral">&nbsp;</span>
381
381
  <span class="cline-any cline-neutral">&nbsp;</span>
382
382
  <span class="cline-any cline-neutral">&nbsp;</span>
383
- <span class="cline-any cline-yes">20116x</span>
384
- <span class="cline-any cline-yes">20116x</span>
385
- <span class="cline-any cline-yes">20116x</span>
383
+ <span class="cline-any cline-yes">20120x</span>
384
+ <span class="cline-any cline-yes">20120x</span>
385
+ <span class="cline-any cline-yes">20120x</span>
386
386
  <span class="cline-any cline-neutral">&nbsp;</span>
387
387
  <span class="cline-any cline-neutral">&nbsp;</span>
388
388
  <span class="cline-any cline-neutral">&nbsp;</span>
389
- <span class="cline-any cline-yes">20116x</span>
389
+ <span class="cline-any cline-yes">20120x</span>
390
390
  <span class="cline-any cline-neutral">&nbsp;</span>
391
391
  <span class="cline-any cline-neutral">&nbsp;</span>
392
392
  <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import { ITaskGraphValidator } from "./contracts/ITaskGraphValidator.js";
@@ -559,7 +559,7 @@ export class TaskGraphValidator implements ITaskGraphValidator {
559
559
  <div class='footer quiet pad2 space-top1 center small'>
560
560
  Code coverage generated by
561
561
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
562
- at 2026-01-18T16:53:50.068Z
562
+ at 2026-01-18T18:46:49.776Z
563
563
  </div>
564
564
  <script src="../prettify.js"></script>
565
565
  <script>
@@ -25,28 +25,28 @@
25
25
  <div class='fl pad1y space-right2'>
26
26
  <span class="strong">100% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>33/33</span>
28
+ <span class='fraction'>49/49</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
33
  <span class="strong">100% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>14/14</span>
35
+ <span class='fraction'>18/18</span>
36
36
  </div>
37
37
 
38
38
 
39
39
  <div class='fl pad1y space-right2'>
40
40
  <span class="strong">100% </span>
41
41
  <span class="quiet">Functions</span>
42
- <span class='fraction'>8/8</span>
42
+ <span class='fraction'>12/12</span>
43
43
  </div>
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
47
  <span class="strong">100% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>33/33</span>
49
+ <span class='fraction'>47/47</span>
50
50
  </div>
51
51
 
52
52
 
@@ -201,7 +201,65 @@
201
201
  <a name='L136'></a><a href='#L136'>136</a>
202
202
  <a name='L137'></a><a href='#L137'>137</a>
203
203
  <a name='L138'></a><a href='#L138'>138</a>
204
- <a name='L139'></a><a href='#L139'>139</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
204
+ <a name='L139'></a><a href='#L139'>139</a>
205
+ <a name='L140'></a><a href='#L140'>140</a>
206
+ <a name='L141'></a><a href='#L141'>141</a>
207
+ <a name='L142'></a><a href='#L142'>142</a>
208
+ <a name='L143'></a><a href='#L143'>143</a>
209
+ <a name='L144'></a><a href='#L144'>144</a>
210
+ <a name='L145'></a><a href='#L145'>145</a>
211
+ <a name='L146'></a><a href='#L146'>146</a>
212
+ <a name='L147'></a><a href='#L147'>147</a>
213
+ <a name='L148'></a><a href='#L148'>148</a>
214
+ <a name='L149'></a><a href='#L149'>149</a>
215
+ <a name='L150'></a><a href='#L150'>150</a>
216
+ <a name='L151'></a><a href='#L151'>151</a>
217
+ <a name='L152'></a><a href='#L152'>152</a>
218
+ <a name='L153'></a><a href='#L153'>153</a>
219
+ <a name='L154'></a><a href='#L154'>154</a>
220
+ <a name='L155'></a><a href='#L155'>155</a>
221
+ <a name='L156'></a><a href='#L156'>156</a>
222
+ <a name='L157'></a><a href='#L157'>157</a>
223
+ <a name='L158'></a><a href='#L158'>158</a>
224
+ <a name='L159'></a><a href='#L159'>159</a>
225
+ <a name='L160'></a><a href='#L160'>160</a>
226
+ <a name='L161'></a><a href='#L161'>161</a>
227
+ <a name='L162'></a><a href='#L162'>162</a>
228
+ <a name='L163'></a><a href='#L163'>163</a>
229
+ <a name='L164'></a><a href='#L164'>164</a>
230
+ <a name='L165'></a><a href='#L165'>165</a>
231
+ <a name='L166'></a><a href='#L166'>166</a>
232
+ <a name='L167'></a><a href='#L167'>167</a>
233
+ <a name='L168'></a><a href='#L168'>168</a>
234
+ <a name='L169'></a><a href='#L169'>169</a>
235
+ <a name='L170'></a><a href='#L170'>170</a>
236
+ <a name='L171'></a><a href='#L171'>171</a>
237
+ <a name='L172'></a><a href='#L172'>172</a>
238
+ <a name='L173'></a><a href='#L173'>173</a>
239
+ <a name='L174'></a><a href='#L174'>174</a>
240
+ <a name='L175'></a><a href='#L175'>175</a>
241
+ <a name='L176'></a><a href='#L176'>176</a>
242
+ <a name='L177'></a><a href='#L177'>177</a>
243
+ <a name='L178'></a><a href='#L178'>178</a>
244
+ <a name='L179'></a><a href='#L179'>179</a>
245
+ <a name='L180'></a><a href='#L180'>180</a>
246
+ <a name='L181'></a><a href='#L181'>181</a>
247
+ <a name='L182'></a><a href='#L182'>182</a>
248
+ <a name='L183'></a><a href='#L183'>183</a>
249
+ <a name='L184'></a><a href='#L184'>184</a>
250
+ <a name='L185'></a><a href='#L185'>185</a>
251
+ <a name='L186'></a><a href='#L186'>186</a>
252
+ <a name='L187'></a><a href='#L187'>187</a>
253
+ <a name='L188'></a><a href='#L188'>188</a>
254
+ <a name='L189'></a><a href='#L189'>189</a>
255
+ <a name='L190'></a><a href='#L190'>190</a>
256
+ <a name='L191'></a><a href='#L191'>191</a>
257
+ <a name='L192'></a><a href='#L192'>192</a>
258
+ <a name='L193'></a><a href='#L193'>193</a>
259
+ <a name='L194'></a><a href='#L194'>194</a>
260
+ <a name='L195'></a><a href='#L195'>195</a>
261
+ <a name='L196'></a><a href='#L196'>196</a>
262
+ <a name='L197'></a><a href='#L197'>197</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
205
263
  <span class="cline-any cline-neutral">&nbsp;</span>
206
264
  <span class="cline-any cline-neutral">&nbsp;</span>
207
265
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -222,14 +280,18 @@
222
280
  <span class="cline-any cline-neutral">&nbsp;</span>
223
281
  <span class="cline-any cline-neutral">&nbsp;</span>
224
282
  <span class="cline-any cline-neutral">&nbsp;</span>
225
- <span class="cline-any cline-yes">50x</span>
226
- <span class="cline-any cline-yes">50x</span>
227
- <span class="cline-any cline-yes">50x</span>
228
283
  <span class="cline-any cline-neutral">&nbsp;</span>
229
284
  <span class="cline-any cline-neutral">&nbsp;</span>
285
+ <span class="cline-any cline-yes">52x</span>
286
+ <span class="cline-any cline-yes">52x</span>
287
+ <span class="cline-any cline-yes">52x</span>
230
288
  <span class="cline-any cline-neutral">&nbsp;</span>
231
289
  <span class="cline-any cline-neutral">&nbsp;</span>
232
- <span class="cline-any cline-yes">50x</span>
290
+ <span class="cline-any cline-neutral">&nbsp;</span>
291
+ <span class="cline-any cline-neutral">&nbsp;</span>
292
+ <span class="cline-any cline-neutral">&nbsp;</span>
293
+ <span class="cline-any cline-neutral">&nbsp;</span>
294
+ <span class="cline-any cline-yes">52x</span>
233
295
  <span class="cline-any cline-neutral">&nbsp;</span>
234
296
  <span class="cline-any cline-neutral">&nbsp;</span>
235
297
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -273,27 +335,81 @@
273
335
  <span class="cline-any cline-neutral">&nbsp;</span>
274
336
  <span class="cline-any cline-neutral">&nbsp;</span>
275
337
  <span class="cline-any cline-neutral">&nbsp;</span>
338
+ <span class="cline-any cline-yes">4x</span>
339
+ <span class="cline-any cline-neutral">&nbsp;</span>
340
+ <span class="cline-any cline-neutral">&nbsp;</span>
341
+ <span class="cline-any cline-neutral">&nbsp;</span>
342
+ <span class="cline-any cline-neutral">&nbsp;</span>
343
+ <span class="cline-any cline-neutral">&nbsp;</span>
344
+ <span class="cline-any cline-neutral">&nbsp;</span>
345
+ <span class="cline-any cline-yes">12x</span>
346
+ <span class="cline-any cline-yes">24x</span>
347
+ <span class="cline-any cline-neutral">&nbsp;</span>
348
+ <span class="cline-any cline-neutral">&nbsp;</span>
349
+ <span class="cline-any cline-neutral">&nbsp;</span>
350
+ <span class="cline-any cline-yes">4x</span>
351
+ <span class="cline-any cline-neutral">&nbsp;</span>
352
+ <span class="cline-any cline-neutral">&nbsp;</span>
353
+ <span class="cline-any cline-neutral">&nbsp;</span>
354
+ <span class="cline-any cline-yes">12x</span>
355
+ <span class="cline-any cline-neutral">&nbsp;</span>
356
+ <span class="cline-any cline-neutral">&nbsp;</span>
357
+ <span class="cline-any cline-neutral">&nbsp;</span>
358
+ <span class="cline-any cline-yes">4x</span>
359
+ <span class="cline-any cline-yes">12x</span>
360
+ <span class="cline-any cline-yes">5x</span>
361
+ <span class="cline-any cline-yes">6x</span>
362
+ <span class="cline-any cline-neutral">&nbsp;</span>
363
+ <span class="cline-any cline-neutral">&nbsp;</span>
364
+ <span class="cline-any cline-neutral">&nbsp;</span>
365
+ <span class="cline-any cline-neutral">&nbsp;</span>
366
+ <span class="cline-any cline-neutral">&nbsp;</span>
367
+ <span class="cline-any cline-neutral">&nbsp;</span>
368
+ <span class="cline-any cline-yes">4x</span>
369
+ <span class="cline-any cline-neutral">&nbsp;</span>
370
+ <span class="cline-any cline-neutral">&nbsp;</span>
371
+ <span class="cline-any cline-neutral">&nbsp;</span>
372
+ <span class="cline-any cline-neutral">&nbsp;</span>
373
+ <span class="cline-any cline-neutral">&nbsp;</span>
374
+ <span class="cline-any cline-neutral">&nbsp;</span>
375
+ <span class="cline-any cline-neutral">&nbsp;</span>
276
376
  <span class="cline-any cline-neutral">&nbsp;</span>
377
+ <span class="cline-any cline-yes">24x</span>
277
378
  <span class="cline-any cline-neutral">&nbsp;</span>
278
379
  <span class="cline-any cline-neutral">&nbsp;</span>
279
380
  <span class="cline-any cline-neutral">&nbsp;</span>
280
381
  <span class="cline-any cline-neutral">&nbsp;</span>
281
382
  <span class="cline-any cline-neutral">&nbsp;</span>
282
383
  <span class="cline-any cline-neutral">&nbsp;</span>
283
- <span class="cline-any cline-yes">45x</span>
284
- <span class="cline-any cline-yes">121x</span>
285
384
  <span class="cline-any cline-neutral">&nbsp;</span>
286
385
  <span class="cline-any cline-neutral">&nbsp;</span>
287
386
  <span class="cline-any cline-neutral">&nbsp;</span>
288
387
  <span class="cline-any cline-neutral">&nbsp;</span>
289
388
  <span class="cline-any cline-neutral">&nbsp;</span>
290
- <span class="cline-any cline-yes">45x</span>
291
- <span class="cline-any cline-yes">45x</span>
389
+ <span class="cline-any cline-neutral">&nbsp;</span>
390
+ <span class="cline-any cline-neutral">&nbsp;</span>
391
+ <span class="cline-any cline-neutral">&nbsp;</span>
392
+ <span class="cline-any cline-neutral">&nbsp;</span>
393
+ <span class="cline-any cline-yes">47x</span>
394
+ <span class="cline-any cline-yes">125x</span>
395
+ <span class="cline-any cline-neutral">&nbsp;</span>
396
+ <span class="cline-any cline-neutral">&nbsp;</span>
397
+ <span class="cline-any cline-neutral">&nbsp;</span>
398
+ <span class="cline-any cline-neutral">&nbsp;</span>
399
+ <span class="cline-any cline-neutral">&nbsp;</span>
400
+ <span class="cline-any cline-yes">47x</span>
401
+ <span class="cline-any cline-yes">47x</span>
292
402
  <span class="cline-any cline-yes">8x</span>
293
403
  <span class="cline-any cline-neutral">&nbsp;</span>
294
404
  <span class="cline-any cline-neutral">&nbsp;</span>
295
- <span class="cline-any cline-yes">37x</span>
296
- <span class="cline-any cline-yes">37x</span>
405
+ <span class="cline-any cline-yes">39x</span>
406
+ <span class="cline-any cline-neutral">&nbsp;</span>
407
+ <span class="cline-any cline-yes">39x</span>
408
+ <span class="cline-any cline-yes">39x</span>
409
+ <span class="cline-any cline-yes">2x</span>
410
+ <span class="cline-any cline-neutral">&nbsp;</span>
411
+ <span class="cline-any cline-neutral">&nbsp;</span>
412
+ <span class="cline-any cline-yes">39x</span>
297
413
  <span class="cline-any cline-neutral">&nbsp;</span>
298
414
  <span class="cline-any cline-neutral">&nbsp;</span>
299
415
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -301,7 +417,7 @@
301
417
  <span class="cline-any cline-neutral">&nbsp;</span>
302
418
  <span class="cline-any cline-neutral">&nbsp;</span>
303
419
  <span class="cline-any cline-neutral">&nbsp;</span>
304
- <span class="cline-any cline-yes">37x</span>
420
+ <span class="cline-any cline-yes">39x</span>
305
421
  <span class="cline-any cline-yes">5x</span>
306
422
  <span class="cline-any cline-yes">5x</span>
307
423
  <span class="cline-any cline-yes">3x</span>
@@ -335,7 +451,7 @@
335
451
  <span class="cline-any cline-neutral">&nbsp;</span>
336
452
  <span class="cline-any cline-neutral">&nbsp;</span>
337
453
  <span class="cline-any cline-neutral">&nbsp;</span>
338
- <span class="cline-any cline-yes">32x</span>
454
+ <span class="cline-any cline-yes">34x</span>
339
455
  <span class="cline-any cline-neutral">&nbsp;</span>
340
456
  <span class="cline-any cline-neutral">&nbsp;</span>
341
457
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -350,6 +466,8 @@ import { TaskRunnerExecutionConfig } from "./TaskRunnerExecutionConfig.js";
350
466
  import { TaskStateManager } from "./TaskStateManager.js";
351
467
  import { IExecutionStrategy } from "./strategies/IExecutionStrategy.js";
352
468
  import { StandardExecutionStrategy } from "./strategies/StandardExecutionStrategy.js";
469
+ import { RetryingExecutionStrategy } from "./strategies/RetryingExecutionStrategy.js";
470
+ import { DryRunExecutionStrategy } from "./strategies/DryRunExecutionStrategy.js";
353
471
  &nbsp;
354
472
  // Re-export types for backward compatibility
355
473
  export { RunnerEventPayloads, RunnerEventListener, TaskRunnerExecutionConfig };
@@ -362,7 +480,9 @@ export { RunnerEventPayloads, RunnerEventListener, TaskRunnerExecutionConfig };
362
480
  export class TaskRunner&lt;TContext&gt; {
363
481
  private eventBus = new EventBus&lt;TContext&gt;();
364
482
  private validator = new TaskGraphValidator();
365
- private executionStrategy: IExecutionStrategy&lt;TContext&gt; = new StandardExecutionStrategy();
483
+ private executionStrategy: IExecutionStrategy&lt;TContext&gt; = new RetryingExecutionStrategy(
484
+ new StandardExecutionStrategy()
485
+ );
366
486
  &nbsp;
367
487
  /**
368
488
  * @param context The shared context object to be passed to each task.
@@ -404,6 +524,54 @@ export class TaskRunner&lt;TContext&gt; {
404
524
  this.executionStrategy = strategy;
405
525
  return this;
406
526
  }
527
+ &nbsp;
528
+ /**
529
+ * Generates a Mermaid.js graph representation of the task workflow.
530
+ * @param steps The list of tasks to visualize.
531
+ * @returns A string containing the Mermaid graph definition.
532
+ */
533
+ public static getMermaidGraph&lt;T&gt;(steps: TaskStep&lt;T&gt;[]): string {
534
+ const graphLines = ["graph TD"];
535
+ &nbsp;
536
+ // Helper to sanitize node names or wrap them if needed
537
+ // For simplicity, we just wrap in quotes and use the name as ID if it's simple
538
+ // or generate an ID if strictly needed. Here we assume names are unique IDs.
539
+ // We will wrap names in quotes for the label, but use the name as the ID.
540
+ // Actually, Mermaid ID cannot have spaces without quotes.
541
+ const safeId = (name: string) =&gt; JSON.stringify(name);
542
+ const sanitize = (name: string) =&gt; this.sanitizeMermaidId(name);
543
+ &nbsp;
544
+ &nbsp;
545
+ // Add all nodes first to ensure they exist
546
+ for (const step of steps) {
547
+ // Using the name as both ID and Label for simplicity
548
+ // Format: ID["Label"]
549
+ // safeId returns a quoted string (e.g. "Task Name"), so we use it directly as the label
550
+ graphLines.push(` ${sanitize(step.name)}[${safeId(step.name)}]`);
551
+ }
552
+ &nbsp;
553
+ // Add edges
554
+ for (const step of steps) {
555
+ if (step.dependencies) {
556
+ for (const dep of step.dependencies) {
557
+ graphLines.push(
558
+ ` ${sanitize(dep)} --&gt; ${sanitize(step.name)}`
559
+ );
560
+ }
561
+ }
562
+ }
563
+ &nbsp;
564
+ return [...new Set(graphLines)].join("\n");
565
+ }
566
+ &nbsp;
567
+ /**
568
+ * Sanitizes a string for use as a Mermaid node ID.
569
+ * @param id The string to sanitize.
570
+ * @returns The sanitized string.
571
+ */
572
+ private static sanitizeMermaidId(id: string): string {
573
+ return id.replaceAll(/ /g, "_").replaceAll(/:/g, "_").replaceAll(/"/g, "_");
574
+ }
407
575
  &nbsp;
408
576
  /**
409
577
  * Executes a list of tasks, respecting their dependencies and running
@@ -431,11 +599,17 @@ export class TaskRunner&lt;TContext&gt; {
431
599
  }
432
600
  &nbsp;
433
601
  const stateManager = new TaskStateManager(this.eventBus);
602
+ &nbsp;
603
+ let strategy = this.executionStrategy;
604
+ if (config?.dryRun) {
605
+ strategy = new DryRunExecutionStrategy&lt;TContext&gt;();
606
+ }
607
+ &nbsp;
434
608
  const executor = new WorkflowExecutor(
435
609
  this.context,
436
610
  this.eventBus,
437
611
  stateManager,
438
- this.executionStrategy
612
+ strategy
439
613
  );
440
614
  &nbsp;
441
615
  // We need to handle the timeout cleanup properly.
@@ -484,7 +658,7 @@ export class TaskRunner&lt;TContext&gt; {
484
658
  <div class='footer quiet pad2 space-top1 center small'>
485
659
  Code coverage generated by
486
660
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
487
- at 2026-01-18T16:53:50.068Z
661
+ at 2026-01-18T18:46:49.776Z
488
662
  </div>
489
663
  <script src="../prettify.js"></script>
490
664
  <script>
@@ -298,7 +298,7 @@ export class TaskRunnerBuilder&lt;TContext&gt; {
298
298
  <div class='footer quiet pad2 space-top1 center small'>
299
299
  Code coverage generated by
300
300
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
301
- at 2026-01-18T16:53:50.068Z
301
+ at 2026-01-18T18:46:49.776Z
302
302
  </div>
303
303
  <script src="../prettify.js"></script>
304
304
  <script>