@calmo/task-runner 2.0.0 → 3.1.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.
- package/.jules/nexus.md +5 -0
- package/AGENTS.md +49 -0
- package/CHANGELOG.md +33 -0
- package/README.md +1 -1
- package/coverage/coverage-final.json +9 -4
- package/coverage/index.html +24 -9
- package/coverage/lcov-report/index.html +24 -9
- package/coverage/lcov-report/src/EventBus.ts.html +8 -8
- package/coverage/lcov-report/src/TaskGraphValidator.ts.html +53 -53
- package/coverage/lcov-report/src/TaskRunner.ts.html +377 -20
- package/coverage/lcov-report/src/TaskRunnerBuilder.ts.html +313 -0
- package/coverage/lcov-report/src/TaskRunnerExecutionConfig.ts.html +139 -0
- package/coverage/lcov-report/src/TaskStateManager.ts.html +511 -0
- package/coverage/lcov-report/src/WorkflowExecutor.ts.html +119 -137
- package/coverage/lcov-report/src/contracts/RunnerEvents.ts.html +1 -1
- package/coverage/lcov-report/src/contracts/index.html +1 -1
- package/coverage/lcov-report/src/index.html +56 -11
- package/coverage/lcov-report/src/strategies/DryRunExecutionStrategy.ts.html +178 -0
- package/coverage/lcov-report/src/strategies/StandardExecutionStrategy.ts.html +190 -0
- package/coverage/lcov-report/src/strategies/index.html +131 -0
- package/coverage/lcov.info +419 -204
- package/coverage/src/EventBus.ts.html +8 -8
- package/coverage/src/TaskGraphValidator.ts.html +53 -53
- package/coverage/src/TaskRunner.ts.html +377 -20
- package/coverage/src/TaskRunnerBuilder.ts.html +313 -0
- package/coverage/src/TaskRunnerExecutionConfig.ts.html +139 -0
- package/coverage/src/TaskStateManager.ts.html +511 -0
- package/coverage/src/WorkflowExecutor.ts.html +119 -137
- package/coverage/src/contracts/RunnerEvents.ts.html +1 -1
- package/coverage/src/contracts/index.html +1 -1
- package/coverage/src/index.html +56 -11
- package/coverage/src/strategies/DryRunExecutionStrategy.ts.html +178 -0
- package/coverage/src/strategies/StandardExecutionStrategy.ts.html +190 -0
- package/coverage/src/strategies/index.html +131 -0
- package/dist/TaskRunner.d.ts +24 -2
- package/dist/TaskRunner.js +99 -3
- package/dist/TaskRunner.js.map +1 -1
- package/dist/TaskRunnerBuilder.d.ts +33 -0
- package/dist/TaskRunnerBuilder.js +54 -0
- package/dist/TaskRunnerBuilder.js.map +1 -0
- package/dist/TaskRunnerExecutionConfig.d.ts +18 -0
- package/dist/TaskRunnerExecutionConfig.js +2 -0
- package/dist/TaskRunnerExecutionConfig.js.map +1 -0
- package/dist/TaskStateManager.d.ts +54 -0
- package/dist/TaskStateManager.js +130 -0
- package/dist/TaskStateManager.js.map +1 -0
- package/dist/TaskStatus.d.ts +1 -1
- package/dist/TaskStep.d.ts +2 -1
- package/dist/WorkflowExecutor.d.ts +11 -17
- package/dist/WorkflowExecutor.js +67 -69
- package/dist/WorkflowExecutor.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/strategies/DryRunExecutionStrategy.d.ts +16 -0
- package/dist/strategies/DryRunExecutionStrategy.js +25 -0
- package/dist/strategies/DryRunExecutionStrategy.js.map +1 -0
- package/dist/strategies/IExecutionStrategy.d.ts +16 -0
- package/dist/strategies/IExecutionStrategy.js +2 -0
- package/dist/strategies/IExecutionStrategy.js.map +1 -0
- package/dist/strategies/StandardExecutionStrategy.d.ts +9 -0
- package/dist/strategies/StandardExecutionStrategy.js +25 -0
- package/dist/strategies/StandardExecutionStrategy.js.map +1 -0
- package/openspec/changes/add-concurrency-control/proposal.md +14 -0
- package/openspec/changes/add-concurrency-control/tasks.md +9 -0
- package/openspec/changes/add-task-retry-policy/proposal.md +16 -0
- package/openspec/changes/add-task-retry-policy/tasks.md +10 -0
- package/openspec/changes/add-workflow-preview/proposal.md +13 -0
- package/openspec/changes/add-workflow-preview/tasks.md +7 -0
- package/openspec/changes/archive/2026-01-18-add-external-task-cancellation/tasks.md +10 -0
- package/openspec/changes/archive/2026-01-18-add-integration-tests/proposal.md +18 -0
- package/openspec/changes/archive/2026-01-18-add-integration-tests/tasks.md +17 -0
- package/openspec/changes/archive/2026-01-18-refactor-core-architecture/proposal.md +14 -0
- package/openspec/changes/archive/2026-01-18-refactor-core-architecture/tasks.md +8 -0
- package/openspec/changes/feat-per-task-timeout/proposal.md +25 -0
- package/openspec/changes/feat-per-task-timeout/tasks.md +27 -0
- package/package.json +1 -1
- package/src/TaskRunner.ts +123 -4
- package/src/TaskRunnerBuilder.ts +76 -0
- package/src/TaskRunnerExecutionConfig.ts +18 -0
- package/src/TaskStateManager.ts +142 -0
- package/src/TaskStatus.ts +1 -1
- package/src/TaskStep.ts +2 -1
- package/src/WorkflowExecutor.ts +77 -83
- package/src/index.ts +4 -0
- package/src/strategies/DryRunExecutionStrategy.ts +31 -0
- package/src/strategies/IExecutionStrategy.ts +21 -0
- package/src/strategies/StandardExecutionStrategy.ts +35 -0
- package/test-report.xml +139 -45
- package/GEMINI.md +0 -48
- package/openspec/changes/add-external-task-cancellation/tasks.md +0 -10
- /package/openspec/changes/{add-external-task-cancellation → archive/2026-01-18-add-external-task-cancellation}/proposal.md +0 -0
|
@@ -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'>
|
|
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'>
|
|
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'>
|
|
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'>
|
|
49
|
+
<span class='fraction'>47/47</span>
|
|
50
50
|
</div>
|
|
51
51
|
|
|
52
52
|
|
|
@@ -137,7 +137,126 @@
|
|
|
137
137
|
<a name='L72'></a><a href='#L72'>72</a>
|
|
138
138
|
<a name='L73'></a><a href='#L73'>73</a>
|
|
139
139
|
<a name='L74'></a><a href='#L74'>74</a>
|
|
140
|
-
<a name='L75'></a><a href='#L75'>75</a
|
|
140
|
+
<a name='L75'></a><a href='#L75'>75</a>
|
|
141
|
+
<a name='L76'></a><a href='#L76'>76</a>
|
|
142
|
+
<a name='L77'></a><a href='#L77'>77</a>
|
|
143
|
+
<a name='L78'></a><a href='#L78'>78</a>
|
|
144
|
+
<a name='L79'></a><a href='#L79'>79</a>
|
|
145
|
+
<a name='L80'></a><a href='#L80'>80</a>
|
|
146
|
+
<a name='L81'></a><a href='#L81'>81</a>
|
|
147
|
+
<a name='L82'></a><a href='#L82'>82</a>
|
|
148
|
+
<a name='L83'></a><a href='#L83'>83</a>
|
|
149
|
+
<a name='L84'></a><a href='#L84'>84</a>
|
|
150
|
+
<a name='L85'></a><a href='#L85'>85</a>
|
|
151
|
+
<a name='L86'></a><a href='#L86'>86</a>
|
|
152
|
+
<a name='L87'></a><a href='#L87'>87</a>
|
|
153
|
+
<a name='L88'></a><a href='#L88'>88</a>
|
|
154
|
+
<a name='L89'></a><a href='#L89'>89</a>
|
|
155
|
+
<a name='L90'></a><a href='#L90'>90</a>
|
|
156
|
+
<a name='L91'></a><a href='#L91'>91</a>
|
|
157
|
+
<a name='L92'></a><a href='#L92'>92</a>
|
|
158
|
+
<a name='L93'></a><a href='#L93'>93</a>
|
|
159
|
+
<a name='L94'></a><a href='#L94'>94</a>
|
|
160
|
+
<a name='L95'></a><a href='#L95'>95</a>
|
|
161
|
+
<a name='L96'></a><a href='#L96'>96</a>
|
|
162
|
+
<a name='L97'></a><a href='#L97'>97</a>
|
|
163
|
+
<a name='L98'></a><a href='#L98'>98</a>
|
|
164
|
+
<a name='L99'></a><a href='#L99'>99</a>
|
|
165
|
+
<a name='L100'></a><a href='#L100'>100</a>
|
|
166
|
+
<a name='L101'></a><a href='#L101'>101</a>
|
|
167
|
+
<a name='L102'></a><a href='#L102'>102</a>
|
|
168
|
+
<a name='L103'></a><a href='#L103'>103</a>
|
|
169
|
+
<a name='L104'></a><a href='#L104'>104</a>
|
|
170
|
+
<a name='L105'></a><a href='#L105'>105</a>
|
|
171
|
+
<a name='L106'></a><a href='#L106'>106</a>
|
|
172
|
+
<a name='L107'></a><a href='#L107'>107</a>
|
|
173
|
+
<a name='L108'></a><a href='#L108'>108</a>
|
|
174
|
+
<a name='L109'></a><a href='#L109'>109</a>
|
|
175
|
+
<a name='L110'></a><a href='#L110'>110</a>
|
|
176
|
+
<a name='L111'></a><a href='#L111'>111</a>
|
|
177
|
+
<a name='L112'></a><a href='#L112'>112</a>
|
|
178
|
+
<a name='L113'></a><a href='#L113'>113</a>
|
|
179
|
+
<a name='L114'></a><a href='#L114'>114</a>
|
|
180
|
+
<a name='L115'></a><a href='#L115'>115</a>
|
|
181
|
+
<a name='L116'></a><a href='#L116'>116</a>
|
|
182
|
+
<a name='L117'></a><a href='#L117'>117</a>
|
|
183
|
+
<a name='L118'></a><a href='#L118'>118</a>
|
|
184
|
+
<a name='L119'></a><a href='#L119'>119</a>
|
|
185
|
+
<a name='L120'></a><a href='#L120'>120</a>
|
|
186
|
+
<a name='L121'></a><a href='#L121'>121</a>
|
|
187
|
+
<a name='L122'></a><a href='#L122'>122</a>
|
|
188
|
+
<a name='L123'></a><a href='#L123'>123</a>
|
|
189
|
+
<a name='L124'></a><a href='#L124'>124</a>
|
|
190
|
+
<a name='L125'></a><a href='#L125'>125</a>
|
|
191
|
+
<a name='L126'></a><a href='#L126'>126</a>
|
|
192
|
+
<a name='L127'></a><a href='#L127'>127</a>
|
|
193
|
+
<a name='L128'></a><a href='#L128'>128</a>
|
|
194
|
+
<a name='L129'></a><a href='#L129'>129</a>
|
|
195
|
+
<a name='L130'></a><a href='#L130'>130</a>
|
|
196
|
+
<a name='L131'></a><a href='#L131'>131</a>
|
|
197
|
+
<a name='L132'></a><a href='#L132'>132</a>
|
|
198
|
+
<a name='L133'></a><a href='#L133'>133</a>
|
|
199
|
+
<a name='L134'></a><a href='#L134'>134</a>
|
|
200
|
+
<a name='L135'></a><a href='#L135'>135</a>
|
|
201
|
+
<a name='L136'></a><a href='#L136'>136</a>
|
|
202
|
+
<a name='L137'></a><a href='#L137'>137</a>
|
|
203
|
+
<a name='L138'></a><a href='#L138'>138</a>
|
|
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></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
|
141
260
|
<span class="cline-any cline-neutral"> </span>
|
|
142
261
|
<span class="cline-any cline-neutral"> </span>
|
|
143
262
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -154,61 +273,180 @@
|
|
|
154
273
|
<span class="cline-any cline-neutral"> </span>
|
|
155
274
|
<span class="cline-any cline-neutral"> </span>
|
|
156
275
|
<span class="cline-any cline-neutral"> </span>
|
|
157
|
-
<span class="cline-any cline-yes">22x</span>
|
|
158
|
-
<span class="cline-any cline-yes">22x</span>
|
|
159
276
|
<span class="cline-any cline-neutral"> </span>
|
|
160
277
|
<span class="cline-any cline-neutral"> </span>
|
|
161
278
|
<span class="cline-any cline-neutral"> </span>
|
|
162
279
|
<span class="cline-any cline-neutral"> </span>
|
|
163
|
-
<span class="cline-any cline-yes">22x</span>
|
|
164
280
|
<span class="cline-any cline-neutral"> </span>
|
|
281
|
+
<span class="cline-any cline-yes">52x</span>
|
|
282
|
+
<span class="cline-any cline-yes">52x</span>
|
|
283
|
+
<span class="cline-any cline-yes">52x</span>
|
|
165
284
|
<span class="cline-any cline-neutral"> </span>
|
|
166
285
|
<span class="cline-any cline-neutral"> </span>
|
|
167
286
|
<span class="cline-any cline-neutral"> </span>
|
|
168
287
|
<span class="cline-any cline-neutral"> </span>
|
|
288
|
+
<span class="cline-any cline-yes">52x</span>
|
|
289
|
+
<span class="cline-any cline-neutral"> </span>
|
|
290
|
+
<span class="cline-any cline-neutral"> </span>
|
|
291
|
+
<span class="cline-any cline-neutral"> </span>
|
|
292
|
+
<span class="cline-any cline-neutral"> </span>
|
|
293
|
+
<span class="cline-any cline-neutral"> </span>
|
|
294
|
+
<span class="cline-any cline-neutral"> </span>
|
|
295
|
+
<span class="cline-any cline-neutral"> </span>
|
|
296
|
+
<span class="cline-any cline-neutral"> </span>
|
|
297
|
+
<span class="cline-any cline-neutral"> </span>
|
|
298
|
+
<span class="cline-any cline-neutral"> </span>
|
|
299
|
+
<span class="cline-any cline-yes">15x</span>
|
|
300
|
+
<span class="cline-any cline-neutral"> </span>
|
|
169
301
|
<span class="cline-any cline-neutral"> </span>
|
|
170
302
|
<span class="cline-any cline-neutral"> </span>
|
|
171
303
|
<span class="cline-any cline-neutral"> </span>
|
|
172
304
|
<span class="cline-any cline-neutral"> </span>
|
|
173
305
|
<span class="cline-any cline-neutral"> </span>
|
|
174
|
-
<span class="cline-any cline-yes">12x</span>
|
|
175
306
|
<span class="cline-any cline-neutral"> </span>
|
|
176
307
|
<span class="cline-any cline-neutral"> </span>
|
|
177
308
|
<span class="cline-any cline-neutral"> </span>
|
|
178
309
|
<span class="cline-any cline-neutral"> </span>
|
|
179
310
|
<span class="cline-any cline-neutral"> </span>
|
|
180
311
|
<span class="cline-any cline-neutral"> </span>
|
|
312
|
+
<span class="cline-any cline-yes">3x</span>
|
|
313
|
+
<span class="cline-any cline-neutral"> </span>
|
|
314
|
+
<span class="cline-any cline-neutral"> </span>
|
|
315
|
+
<span class="cline-any cline-neutral"> </span>
|
|
316
|
+
<span class="cline-any cline-neutral"> </span>
|
|
181
317
|
<span class="cline-any cline-neutral"> </span>
|
|
182
318
|
<span class="cline-any cline-neutral"> </span>
|
|
183
319
|
<span class="cline-any cline-neutral"> </span>
|
|
184
320
|
<span class="cline-any cline-neutral"> </span>
|
|
185
321
|
<span class="cline-any cline-neutral"> </span>
|
|
186
322
|
<span class="cline-any cline-yes">2x</span>
|
|
323
|
+
<span class="cline-any cline-yes">2x</span>
|
|
324
|
+
<span class="cline-any cline-neutral"> </span>
|
|
325
|
+
<span class="cline-any cline-neutral"> </span>
|
|
326
|
+
<span class="cline-any cline-neutral"> </span>
|
|
187
327
|
<span class="cline-any cline-neutral"> </span>
|
|
188
328
|
<span class="cline-any cline-neutral"> </span>
|
|
189
329
|
<span class="cline-any cline-neutral"> </span>
|
|
190
330
|
<span class="cline-any cline-neutral"> </span>
|
|
191
331
|
<span class="cline-any cline-neutral"> </span>
|
|
332
|
+
<span class="cline-any cline-yes">4x</span>
|
|
192
333
|
<span class="cline-any cline-neutral"> </span>
|
|
193
334
|
<span class="cline-any cline-neutral"> </span>
|
|
194
335
|
<span class="cline-any cline-neutral"> </span>
|
|
195
336
|
<span class="cline-any cline-neutral"> </span>
|
|
196
337
|
<span class="cline-any cline-neutral"> </span>
|
|
197
338
|
<span class="cline-any cline-neutral"> </span>
|
|
198
|
-
<span class="cline-any cline-yes">
|
|
199
|
-
<span class="cline-any cline-yes">
|
|
339
|
+
<span class="cline-any cline-yes">12x</span>
|
|
340
|
+
<span class="cline-any cline-yes">24x</span>
|
|
341
|
+
<span class="cline-any cline-neutral"> </span>
|
|
342
|
+
<span class="cline-any cline-neutral"> </span>
|
|
343
|
+
<span class="cline-any cline-neutral"> </span>
|
|
344
|
+
<span class="cline-any cline-yes">4x</span>
|
|
200
345
|
<span class="cline-any cline-neutral"> </span>
|
|
201
346
|
<span class="cline-any cline-neutral"> </span>
|
|
202
347
|
<span class="cline-any cline-neutral"> </span>
|
|
348
|
+
<span class="cline-any cline-yes">12x</span>
|
|
349
|
+
<span class="cline-any cline-neutral"> </span>
|
|
203
350
|
<span class="cline-any cline-neutral"> </span>
|
|
204
351
|
<span class="cline-any cline-neutral"> </span>
|
|
205
|
-
<span class="cline-any cline-yes">
|
|
206
|
-
<span class="cline-any cline-yes">
|
|
352
|
+
<span class="cline-any cline-yes">4x</span>
|
|
353
|
+
<span class="cline-any cline-yes">12x</span>
|
|
354
|
+
<span class="cline-any cline-yes">5x</span>
|
|
207
355
|
<span class="cline-any cline-yes">6x</span>
|
|
208
356
|
<span class="cline-any cline-neutral"> </span>
|
|
209
357
|
<span class="cline-any cline-neutral"> </span>
|
|
210
|
-
<span class="cline-any cline-
|
|
211
|
-
<span class="cline-any cline-
|
|
358
|
+
<span class="cline-any cline-neutral"> </span>
|
|
359
|
+
<span class="cline-any cline-neutral"> </span>
|
|
360
|
+
<span class="cline-any cline-neutral"> </span>
|
|
361
|
+
<span class="cline-any cline-neutral"> </span>
|
|
362
|
+
<span class="cline-any cline-yes">4x</span>
|
|
363
|
+
<span class="cline-any cline-neutral"> </span>
|
|
364
|
+
<span class="cline-any cline-neutral"> </span>
|
|
365
|
+
<span class="cline-any cline-neutral"> </span>
|
|
366
|
+
<span class="cline-any cline-neutral"> </span>
|
|
367
|
+
<span class="cline-any cline-neutral"> </span>
|
|
368
|
+
<span class="cline-any cline-neutral"> </span>
|
|
369
|
+
<span class="cline-any cline-neutral"> </span>
|
|
370
|
+
<span class="cline-any cline-neutral"> </span>
|
|
371
|
+
<span class="cline-any cline-yes">24x</span>
|
|
372
|
+
<span class="cline-any cline-neutral"> </span>
|
|
373
|
+
<span class="cline-any cline-neutral"> </span>
|
|
374
|
+
<span class="cline-any cline-neutral"> </span>
|
|
375
|
+
<span class="cline-any cline-neutral"> </span>
|
|
376
|
+
<span class="cline-any cline-neutral"> </span>
|
|
377
|
+
<span class="cline-any cline-neutral"> </span>
|
|
378
|
+
<span class="cline-any cline-neutral"> </span>
|
|
379
|
+
<span class="cline-any cline-neutral"> </span>
|
|
380
|
+
<span class="cline-any cline-neutral"> </span>
|
|
381
|
+
<span class="cline-any cline-neutral"> </span>
|
|
382
|
+
<span class="cline-any cline-neutral"> </span>
|
|
383
|
+
<span class="cline-any cline-neutral"> </span>
|
|
384
|
+
<span class="cline-any cline-neutral"> </span>
|
|
385
|
+
<span class="cline-any cline-neutral"> </span>
|
|
386
|
+
<span class="cline-any cline-neutral"> </span>
|
|
387
|
+
<span class="cline-any cline-yes">47x</span>
|
|
388
|
+
<span class="cline-any cline-yes">125x</span>
|
|
389
|
+
<span class="cline-any cline-neutral"> </span>
|
|
390
|
+
<span class="cline-any cline-neutral"> </span>
|
|
391
|
+
<span class="cline-any cline-neutral"> </span>
|
|
392
|
+
<span class="cline-any cline-neutral"> </span>
|
|
393
|
+
<span class="cline-any cline-neutral"> </span>
|
|
394
|
+
<span class="cline-any cline-yes">47x</span>
|
|
395
|
+
<span class="cline-any cline-yes">47x</span>
|
|
396
|
+
<span class="cline-any cline-yes">8x</span>
|
|
397
|
+
<span class="cline-any cline-neutral"> </span>
|
|
398
|
+
<span class="cline-any cline-neutral"> </span>
|
|
399
|
+
<span class="cline-any cline-yes">39x</span>
|
|
400
|
+
<span class="cline-any cline-neutral"> </span>
|
|
401
|
+
<span class="cline-any cline-yes">39x</span>
|
|
402
|
+
<span class="cline-any cline-yes">39x</span>
|
|
403
|
+
<span class="cline-any cline-yes">2x</span>
|
|
404
|
+
<span class="cline-any cline-neutral"> </span>
|
|
405
|
+
<span class="cline-any cline-neutral"> </span>
|
|
406
|
+
<span class="cline-any cline-yes">39x</span>
|
|
407
|
+
<span class="cline-any cline-neutral"> </span>
|
|
408
|
+
<span class="cline-any cline-neutral"> </span>
|
|
409
|
+
<span class="cline-any cline-neutral"> </span>
|
|
410
|
+
<span class="cline-any cline-neutral"> </span>
|
|
411
|
+
<span class="cline-any cline-neutral"> </span>
|
|
412
|
+
<span class="cline-any cline-neutral"> </span>
|
|
413
|
+
<span class="cline-any cline-neutral"> </span>
|
|
414
|
+
<span class="cline-any cline-yes">39x</span>
|
|
415
|
+
<span class="cline-any cline-yes">5x</span>
|
|
416
|
+
<span class="cline-any cline-yes">5x</span>
|
|
417
|
+
<span class="cline-any cline-yes">3x</span>
|
|
418
|
+
<span class="cline-any cline-neutral"> </span>
|
|
419
|
+
<span class="cline-any cline-neutral"> </span>
|
|
420
|
+
<span class="cline-any cline-yes">5x</span>
|
|
421
|
+
<span class="cline-any cline-neutral"> </span>
|
|
422
|
+
<span class="cline-any cline-neutral"> </span>
|
|
423
|
+
<span class="cline-any cline-neutral"> </span>
|
|
424
|
+
<span class="cline-any cline-yes">5x</span>
|
|
425
|
+
<span class="cline-any cline-yes">3x</span>
|
|
426
|
+
<span class="cline-any cline-neutral"> </span>
|
|
427
|
+
<span class="cline-any cline-neutral"> </span>
|
|
428
|
+
<span class="cline-any cline-yes">1x</span>
|
|
429
|
+
<span class="cline-any cline-yes">1x</span>
|
|
430
|
+
<span class="cline-any cline-neutral"> </span>
|
|
431
|
+
<span class="cline-any cline-neutral"> </span>
|
|
432
|
+
<span class="cline-any cline-yes">2x</span>
|
|
433
|
+
<span class="cline-any cline-yes">1x</span>
|
|
434
|
+
<span class="cline-any cline-neutral"> </span>
|
|
435
|
+
<span class="cline-any cline-yes">2x</span>
|
|
436
|
+
<span class="cline-any cline-neutral"> </span>
|
|
437
|
+
<span class="cline-any cline-neutral"> </span>
|
|
438
|
+
<span class="cline-any cline-neutral"> </span>
|
|
439
|
+
<span class="cline-any cline-yes">5x</span>
|
|
440
|
+
<span class="cline-any cline-yes">5x</span>
|
|
441
|
+
<span class="cline-any cline-neutral"> </span>
|
|
442
|
+
<span class="cline-any cline-yes">5x</span>
|
|
443
|
+
<span class="cline-any cline-yes">5x</span>
|
|
444
|
+
<span class="cline-any cline-yes">2x</span>
|
|
445
|
+
<span class="cline-any cline-neutral"> </span>
|
|
446
|
+
<span class="cline-any cline-neutral"> </span>
|
|
447
|
+
<span class="cline-any cline-neutral"> </span>
|
|
448
|
+
<span class="cline-any cline-yes">34x</span>
|
|
449
|
+
<span class="cline-any cline-neutral"> </span>
|
|
212
450
|
<span class="cline-any cline-neutral"> </span>
|
|
213
451
|
<span class="cline-any cline-neutral"> </span>
|
|
214
452
|
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import { TaskStep } from "./TaskStep.js";
|
|
@@ -218,9 +456,14 @@ import { TaskGraph } from "./TaskGraph.js";
|
|
|
218
456
|
import { RunnerEventPayloads, RunnerEventListener } from "./contracts/RunnerEvents.js";
|
|
219
457
|
import { EventBus } from "./EventBus.js";
|
|
220
458
|
import { WorkflowExecutor } from "./WorkflowExecutor.js";
|
|
459
|
+
import { TaskRunnerExecutionConfig } from "./TaskRunnerExecutionConfig.js";
|
|
460
|
+
import { TaskStateManager } from "./TaskStateManager.js";
|
|
461
|
+
import { IExecutionStrategy } from "./strategies/IExecutionStrategy.js";
|
|
462
|
+
import { StandardExecutionStrategy } from "./strategies/StandardExecutionStrategy.js";
|
|
463
|
+
import { DryRunExecutionStrategy } from "./strategies/DryRunExecutionStrategy.js";
|
|
221
464
|
|
|
222
465
|
// Re-export types for backward compatibility
|
|
223
|
-
export { RunnerEventPayloads, RunnerEventListener };
|
|
466
|
+
export { RunnerEventPayloads, RunnerEventListener, TaskRunnerExecutionConfig };
|
|
224
467
|
|
|
225
468
|
/**
|
|
226
469
|
* The main class that orchestrates the execution of a list of tasks
|
|
@@ -230,6 +473,7 @@ export { RunnerEventPayloads, RunnerEventListener };
|
|
|
230
473
|
export class TaskRunner<TContext> {
|
|
231
474
|
private eventBus = new EventBus<TContext>();
|
|
232
475
|
private validator = new TaskGraphValidator();
|
|
476
|
+
private executionStrategy: IExecutionStrategy<TContext> = new StandardExecutionStrategy();
|
|
233
477
|
|
|
234
478
|
/**
|
|
235
479
|
* @param context The shared context object to be passed to each task.
|
|
@@ -257,17 +501,81 @@ export class TaskRunner<TContext> {
|
|
|
257
501
|
event: K,
|
|
258
502
|
callback: RunnerEventListener<TContext, K>
|
|
259
503
|
): void {
|
|
504
|
+
/* v8 ignore next 1 */
|
|
260
505
|
this.eventBus.off(event, callback);
|
|
261
506
|
}
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* Sets the execution strategy to be used.
|
|
510
|
+
* @param strategy The execution strategy.
|
|
511
|
+
* @returns The TaskRunner instance for chaining.
|
|
512
|
+
*/
|
|
513
|
+
public setExecutionStrategy(strategy: IExecutionStrategy<TContext>): this {
|
|
514
|
+
/* v8 ignore next 2 */
|
|
515
|
+
this.executionStrategy = strategy;
|
|
516
|
+
return this;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* Generates a Mermaid.js graph representation of the task workflow.
|
|
521
|
+
* @param steps The list of tasks to visualize.
|
|
522
|
+
* @returns A string containing the Mermaid graph definition.
|
|
523
|
+
*/
|
|
524
|
+
public static getMermaidGraph<T>(steps: TaskStep<T>[]): string {
|
|
525
|
+
const graphLines = ["graph TD"];
|
|
526
|
+
|
|
527
|
+
// Helper to sanitize node names or wrap them if needed
|
|
528
|
+
// For simplicity, we just wrap in quotes and use the name as ID if it's simple
|
|
529
|
+
// or generate an ID if strictly needed. Here we assume names are unique IDs.
|
|
530
|
+
// We will wrap names in quotes for the label, but use the name as the ID.
|
|
531
|
+
// Actually, Mermaid ID cannot have spaces without quotes.
|
|
532
|
+
const safeId = (name: string) => JSON.stringify(name);
|
|
533
|
+
const sanitize = (name: string) => this.sanitizeMermaidId(name);
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
// Add all nodes first to ensure they exist
|
|
537
|
+
for (const step of steps) {
|
|
538
|
+
// Using the name as both ID and Label for simplicity
|
|
539
|
+
// Format: ID["Label"]
|
|
540
|
+
// safeId returns a quoted string (e.g. "Task Name"), so we use it directly as the label
|
|
541
|
+
graphLines.push(` ${sanitize(step.name)}[${safeId(step.name)}]`);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// Add edges
|
|
545
|
+
for (const step of steps) {
|
|
546
|
+
if (step.dependencies) {
|
|
547
|
+
for (const dep of step.dependencies) {
|
|
548
|
+
graphLines.push(
|
|
549
|
+
` ${sanitize(dep)} --> ${sanitize(step.name)}`
|
|
550
|
+
);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
return [...new Set(graphLines)].join("\n");
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* Sanitizes a string for use as a Mermaid node ID.
|
|
560
|
+
* @param id The string to sanitize.
|
|
561
|
+
* @returns The sanitized string.
|
|
562
|
+
*/
|
|
563
|
+
private static sanitizeMermaidId(id: string): string {
|
|
564
|
+
return id.replaceAll(/ /g, "_").replaceAll(/:/g, "_").replaceAll(/"/g, "_");
|
|
565
|
+
}
|
|
262
566
|
|
|
263
567
|
/**
|
|
264
568
|
* Executes a list of tasks, respecting their dependencies and running
|
|
265
569
|
* independent tasks in parallel.
|
|
266
570
|
* @param steps An array of TaskStep objects to be executed.
|
|
571
|
+
* @param config Optional configuration for execution (timeout, cancellation).
|
|
267
572
|
* @returns A Promise that resolves to a Map where keys are task names
|
|
268
573
|
* and values are the corresponding TaskResult objects.
|
|
269
574
|
*/
|
|
270
|
-
async execute(
|
|
575
|
+
async execute(
|
|
576
|
+
steps: TaskStep<TContext>[],
|
|
577
|
+
config?: TaskRunnerExecutionConfig
|
|
578
|
+
): Promise<Map<string, TaskResult>> {
|
|
271
579
|
// Validate the task graph before execution
|
|
272
580
|
const taskGraph: TaskGraph = {
|
|
273
581
|
tasks: steps.map((step) => ({
|
|
@@ -281,8 +589,57 @@ export class TaskRunner<TContext> {
|
|
|
281
589
|
throw new Error(this.validator.createErrorMessage(validationResult));
|
|
282
590
|
}
|
|
283
591
|
|
|
284
|
-
const
|
|
285
|
-
|
|
592
|
+
const stateManager = new TaskStateManager(this.eventBus);
|
|
593
|
+
|
|
594
|
+
let strategy = this.executionStrategy;
|
|
595
|
+
if (config?.dryRun) {
|
|
596
|
+
strategy = new DryRunExecutionStrategy<TContext>();
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
const executor = new WorkflowExecutor(
|
|
600
|
+
this.context,
|
|
601
|
+
this.eventBus,
|
|
602
|
+
stateManager,
|
|
603
|
+
strategy
|
|
604
|
+
);
|
|
605
|
+
|
|
606
|
+
// We need to handle the timeout cleanup properly.
|
|
607
|
+
if (config?.timeout !== undefined) {
|
|
608
|
+
const controller = new AbortController();
|
|
609
|
+
const timeoutId = setTimeout(() => {
|
|
610
|
+
controller.abort(new Error(`Workflow timed out after ${config.timeout}ms`));
|
|
611
|
+
}, config.timeout);
|
|
612
|
+
|
|
613
|
+
let effectiveSignal = controller.signal;
|
|
614
|
+
let onAbort: (() => void) | undefined;
|
|
615
|
+
|
|
616
|
+
// Handle combination of signals if user provided one
|
|
617
|
+
if (config.signal) {
|
|
618
|
+
if (config.signal.aborted) {
|
|
619
|
+
// If already aborted, use it directly (WorkflowExecutor handles early abort)
|
|
620
|
+
// We can cancel timeout immediately
|
|
621
|
+
clearTimeout(timeoutId);
|
|
622
|
+
effectiveSignal = config.signal;
|
|
623
|
+
} else {
|
|
624
|
+
// Listen to user signal to abort our controller
|
|
625
|
+
onAbort = () => {
|
|
626
|
+
controller.abort(config.signal?.reason);
|
|
627
|
+
};
|
|
628
|
+
config.signal.addEventListener("abort", onAbort);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
try {
|
|
633
|
+
return await executor.execute(steps, effectiveSignal);
|
|
634
|
+
} finally {
|
|
635
|
+
clearTimeout(timeoutId);
|
|
636
|
+
if (config.signal && onAbort) {
|
|
637
|
+
config.signal.removeEventListener("abort", onAbort);
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
} else {
|
|
641
|
+
return executor.execute(steps, config?.signal);
|
|
642
|
+
}
|
|
286
643
|
}
|
|
287
644
|
}
|
|
288
645
|
</pre></td></tr></table></pre>
|
|
@@ -292,7 +649,7 @@ export class TaskRunner<TContext> {
|
|
|
292
649
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
293
650
|
Code coverage generated by
|
|
294
651
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
295
|
-
at 2026-01-
|
|
652
|
+
at 2026-01-18T18:12:39.258Z
|
|
296
653
|
</div>
|
|
297
654
|
<script src="../prettify.js"></script>
|
|
298
655
|
<script>
|