@trevonistrevon/pi-loop 0.5.6 → 0.5.8

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 (53) hide show
  1. package/coverage/coverage-final.json +27 -27
  2. package/coverage/index.html +39 -39
  3. package/coverage/src/commands/index.html +1 -1
  4. package/coverage/src/commands/loop-command.ts.html +3 -3
  5. package/coverage/src/commands/tasks-command.ts.html +3 -3
  6. package/coverage/src/coordinator.ts.html +20 -20
  7. package/coverage/src/goal-coordinator.ts.html +1 -1
  8. package/coverage/src/goal-reducer.ts.html +1 -1
  9. package/coverage/src/goal-store.ts.html +1 -1
  10. package/coverage/src/goal-verifier.ts.html +1 -1
  11. package/coverage/src/index.html +33 -33
  12. package/coverage/src/index.ts.html +71 -71
  13. package/coverage/src/loop-parse.ts.html +62 -62
  14. package/coverage/src/loop-reducer.ts.html +28 -28
  15. package/coverage/src/monitor-completion-coordinator.ts.html +3 -3
  16. package/coverage/src/monitor-manager.ts.html +76 -70
  17. package/coverage/src/monitor-reducer.ts.html +28 -28
  18. package/coverage/src/notification-reducer.ts.html +15 -15
  19. package/coverage/src/reducer-backed-store.ts.html +54 -54
  20. package/coverage/src/runtime/index.html +53 -53
  21. package/coverage/src/runtime/monitor-ondone-runtime.ts.html +39 -39
  22. package/coverage/src/runtime/notification-runtime.ts.html +42 -42
  23. package/coverage/src/runtime/scope.ts.html +34 -34
  24. package/coverage/src/runtime/session-runtime.ts.html +141 -51
  25. package/coverage/src/runtime/task-backlog-runtime.ts.html +48 -48
  26. package/coverage/src/runtime/task-rpc.ts.html +81 -81
  27. package/coverage/src/scheduler.ts.html +41 -41
  28. package/coverage/src/store.ts.html +26 -26
  29. package/coverage/src/task-backlog-coordinator.ts.html +8 -8
  30. package/coverage/src/task-reducer.ts.html +39 -39
  31. package/coverage/src/task-store.ts.html +55 -55
  32. package/coverage/src/tools/index.html +43 -43
  33. package/coverage/src/tools/loop-tools.ts.html +93 -93
  34. package/coverage/src/tools/monitor-tools.ts.html +53 -53
  35. package/coverage/src/tools/native-task-tools.ts.html +66 -66
  36. package/coverage/src/trigger-system.ts.html +11 -11
  37. package/coverage/src/ui/index.html +1 -1
  38. package/coverage/src/ui/widget.ts.html +22 -22
  39. package/dist/commands/tasks-command.js +12 -9
  40. package/dist/monitor-manager.js +3 -1
  41. package/dist/runtime/session-runtime.js +29 -0
  42. package/dist/runtime/task-events.d.ts +15 -0
  43. package/dist/runtime/task-events.js +13 -0
  44. package/dist/runtime/task-rpc.js +2 -0
  45. package/dist/tools/native-task-tools.js +20 -9
  46. package/package.json +1 -1
  47. package/src/commands/tasks-command.ts +9 -9
  48. package/src/monitor-manager.ts +3 -1
  49. package/src/runtime/session-runtime.ts +30 -0
  50. package/src/runtime/task-events.ts +41 -0
  51. package/src/runtime/task-rpc.ts +2 -0
  52. package/src/tools/native-task-tools.ts +16 -9
  53. package/vitest.config.ts +7 -7
@@ -23,30 +23,30 @@
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">89.53% </span>
26
+ <span class="strong">90.09% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>77/86</span>
28
+ <span class='fraction'>91/101</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">76.92% </span>
33
+ <span class="strong">79.06% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>30/39</span>
35
+ <span class='fraction'>34/43</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'>12/12</span>
42
+ <span class='fraction'>16/16</span>
43
43
  </div>
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
- <span class="strong">94.66% </span>
47
+ <span class="strong">94.31% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>71/75</span>
49
+ <span class='fraction'>83/88</span>
50
50
  </div>
51
51
 
52
52
 
@@ -231,7 +231,37 @@
231
231
  <a name='L166'></a><a href='#L166'>166</a>
232
232
  <a name='L167'></a><a href='#L167'>167</a>
233
233
  <a name='L168'></a><a href='#L168'>168</a>
234
- <a name='L169'></a><a href='#L169'>169</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
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>
263
+ <a name='L198'></a><a href='#L198'>198</a>
264
+ <a name='L199'></a><a href='#L199'>199</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
235
265
  <span class="cline-any cline-neutral">&nbsp;</span>
236
266
  <span class="cline-any cline-neutral">&nbsp;</span>
237
267
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -242,6 +272,7 @@
242
272
  <span class="cline-any cline-neutral">&nbsp;</span>
243
273
  <span class="cline-any cline-neutral">&nbsp;</span>
244
274
  <span class="cline-any cline-neutral">&nbsp;</span>
275
+ <span class="cline-any cline-yes">4x</span>
245
276
  <span class="cline-any cline-neutral">&nbsp;</span>
246
277
  <span class="cline-any cline-neutral">&nbsp;</span>
247
278
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -277,25 +308,50 @@
277
308
  <span class="cline-any cline-neutral">&nbsp;</span>
278
309
  <span class="cline-any cline-neutral">&nbsp;</span>
279
310
  <span class="cline-any cline-neutral">&nbsp;</span>
280
- <span class="cline-any cline-yes">60x</span>
281
311
  <span class="cline-any cline-neutral">&nbsp;</span>
282
- <span class="cline-any cline-yes">60x</span>
283
- <span class="cline-any cline-yes">60x</span>
284
312
  <span class="cline-any cline-neutral">&nbsp;</span>
285
313
  <span class="cline-any cline-neutral">&nbsp;</span>
286
- <span class="cline-any cline-yes">51x</span>
287
- <span class="cline-any cline-yes">47x</span>
288
- <span class="cline-any cline-yes">45x</span>
314
+ <span class="cline-any cline-yes">65x</span>
289
315
  <span class="cline-any cline-neutral">&nbsp;</span>
290
- <span class="cline-any cline-yes">47x</span>
316
+ <span class="cline-any cline-yes">65x</span>
317
+ <span class="cline-any cline-yes">65x</span>
291
318
  <span class="cline-any cline-neutral">&nbsp;</span>
292
319
  <span class="cline-any cline-neutral">&nbsp;</span>
293
320
  <span class="cline-any cline-neutral">&nbsp;</span>
294
- <span class="cline-any cline-yes">7x</span>
295
- <span class="cline-any cline-yes">7x</span>
296
- <span class="cline-any cline-yes">7x</span>
297
- <span class="cline-any cline-yes">7x</span>
298
- <span class="cline-any cline-yes">7x</span>
321
+ <span class="cline-any cline-neutral">&nbsp;</span>
322
+ <span class="cline-any cline-neutral">&nbsp;</span>
323
+ <span class="cline-any cline-neutral">&nbsp;</span>
324
+ <span class="cline-any cline-neutral">&nbsp;</span>
325
+ <span class="cline-any cline-yes">56x</span>
326
+ <span class="cline-any cline-yes">49x</span>
327
+ <span class="cline-any cline-neutral">&nbsp;</span>
328
+ <span class="cline-any cline-neutral">&nbsp;</span>
329
+ <span class="cline-any cline-yes">93x</span>
330
+ <span class="cline-any cline-neutral">&nbsp;</span>
331
+ <span class="cline-any cline-yes">49x</span>
332
+ <span class="cline-any cline-neutral">&nbsp;</span>
333
+ <span class="cline-any cline-neutral">&nbsp;</span>
334
+ <span class="cline-any cline-neutral">&nbsp;</span>
335
+ <span class="cline-any cline-yes">6x</span>
336
+ <span class="cline-any cline-yes">6x</span>
337
+ <span class="cline-any cline-yes">6x</span>
338
+ <span class="cline-any cline-neutral">&nbsp;</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-yes">59x</span>
342
+ <span class="cline-any cline-yes">52x</span>
343
+ <span class="cline-any cline-yes">46x</span>
344
+ <span class="cline-any cline-neutral">&nbsp;</span>
345
+ <span class="cline-any cline-yes">52x</span>
346
+ <span class="cline-any cline-neutral">&nbsp;</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-yes">10x</span>
350
+ <span class="cline-any cline-yes">10x</span>
351
+ <span class="cline-any cline-yes">10x</span>
352
+ <span class="cline-any cline-yes">10x</span>
353
+ <span class="cline-any cline-yes">10x</span>
354
+ <span class="cline-any cline-no">&nbsp;</span>
299
355
  <span class="cline-any cline-no">&nbsp;</span>
300
356
  <span class="cline-any cline-no">&nbsp;</span>
301
357
  <span class="cline-any cline-no">&nbsp;</span>
@@ -304,37 +360,39 @@
304
360
  <span class="cline-any cline-neutral">&nbsp;</span>
305
361
  <span class="cline-any cline-neutral">&nbsp;</span>
306
362
  <span class="cline-any cline-neutral">&nbsp;</span>
307
- <span class="cline-any cline-yes">68x</span>
308
- <span class="cline-any cline-yes">68x</span>
309
- <span class="cline-any cline-yes">6x</span>
310
- <span class="cline-any cline-yes">6x</span>
311
- <span class="cline-any cline-yes">1x</span>
312
- <span class="cline-any cline-yes">1x</span>
313
- <span class="cline-any cline-yes">1x</span>
314
- <span class="cline-any cline-yes">1x</span>
315
- <span class="cline-any cline-yes">1x</span>
363
+ <span class="cline-any cline-yes">166x</span>
364
+ <span class="cline-any cline-yes">166x</span>
365
+ <span class="cline-any cline-yes">72x</span>
366
+ <span class="cline-any cline-yes">72x</span>
367
+ <span class="cline-any cline-yes">13x</span>
368
+ <span class="cline-any cline-yes">13x</span>
369
+ <span class="cline-any cline-yes">13x</span>
370
+ <span class="cline-any cline-yes">5x</span>
371
+ <span class="cline-any cline-yes">5x</span>
316
372
  <span class="cline-any cline-neutral">&nbsp;</span>
317
- <span class="cline-any cline-yes">68x</span>
373
+ <span class="cline-any cline-yes">166x</span>
318
374
  <span class="cline-any cline-neutral">&nbsp;</span>
319
375
  <span class="cline-any cline-neutral">&nbsp;</span>
320
- <span class="cline-any cline-yes">60x</span>
321
- <span class="cline-any cline-yes">44x</span>
322
- <span class="cline-any cline-yes">44x</span>
323
- <span class="cline-any cline-yes">44x</span>
324
- <span class="cline-any cline-yes">44x</span>
325
- <span class="cline-any cline-yes">44x</span>
326
- <span class="cline-any cline-yes">44x</span>
376
+ <span class="cline-any cline-yes">65x</span>
377
+ <span class="cline-any cline-yes">49x</span>
378
+ <span class="cline-any cline-yes">49x</span>
379
+ <span class="cline-any cline-yes">49x</span>
380
+ <span class="cline-any cline-yes">49x</span>
381
+ <span class="cline-any cline-yes">49x</span>
382
+ <span class="cline-any cline-yes">49x</span>
383
+ <span class="cline-any cline-yes">49x</span>
327
384
  <span class="cline-any cline-neutral">&nbsp;</span>
328
385
  <span class="cline-any cline-neutral">&nbsp;</span>
329
- <span class="cline-any cline-yes">60x</span>
330
- <span class="cline-any cline-yes">4x</span>
331
- <span class="cline-any cline-yes">4x</span>
332
- <span class="cline-any cline-yes">4x</span>
333
- <span class="cline-any cline-yes">4x</span>
334
- <span class="cline-any cline-yes">4x</span>
386
+ <span class="cline-any cline-yes">65x</span>
387
+ <span class="cline-any cline-yes">7x</span>
388
+ <span class="cline-any cline-yes">7x</span>
389
+ <span class="cline-any cline-yes">7x</span>
390
+ <span class="cline-any cline-yes">7x</span>
391
+ <span class="cline-any cline-yes">7x</span>
392
+ <span class="cline-any cline-yes">7x</span>
335
393
  <span class="cline-any cline-neutral">&nbsp;</span>
336
394
  <span class="cline-any cline-neutral">&nbsp;</span>
337
- <span class="cline-any cline-yes">60x</span>
395
+ <span class="cline-any cline-yes">65x</span>
338
396
  <span class="cline-any cline-yes">20x</span>
339
397
  <span class="cline-any cline-neutral">&nbsp;</span>
340
398
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -343,7 +401,7 @@
343
401
  <span class="cline-any cline-yes">20x</span>
344
402
  <span class="cline-any cline-neutral">&nbsp;</span>
345
403
  <span class="cline-any cline-neutral">&nbsp;</span>
346
- <span class="cline-any cline-yes">60x</span>
404
+ <span class="cline-any cline-yes">65x</span>
347
405
  <span class="cline-any cline-yes">24x</span>
348
406
  <span class="cline-any cline-yes">24x</span>
349
407
  <span class="cline-any cline-yes">24x</span>
@@ -355,11 +413,13 @@
355
413
  <span class="cline-any cline-yes">24x</span>
356
414
  <span class="cline-any cline-neutral">&nbsp;</span>
357
415
  <span class="cline-any cline-neutral">&nbsp;</span>
358
- <span class="cline-any cline-yes">60x</span>
359
- <span class="cline-any cline-yes">2x</span>
416
+ <span class="cline-any cline-yes">65x</span>
417
+ <span class="cline-any cline-yes">3x</span>
418
+ <span class="cline-any cline-yes">3x</span>
360
419
  <span class="cline-any cline-neutral">&nbsp;</span>
361
420
  <span class="cline-any cline-neutral">&nbsp;</span>
362
- <span class="cline-any cline-yes">60x</span>
421
+ <span class="cline-any cline-yes">65x</span>
422
+ <span class="cline-any cline-yes">3x</span>
363
423
  <span class="cline-any cline-yes">3x</span>
364
424
  <span class="cline-any cline-yes">3x</span>
365
425
  <span class="cline-any cline-yes">3x</span>
@@ -379,7 +439,7 @@
379
439
  <span class="cline-any cline-yes">3x</span>
380
440
  <span class="cline-any cline-neutral">&nbsp;</span>
381
441
  <span class="cline-any cline-neutral">&nbsp;</span>
382
- <span class="cline-any cline-yes">60x</span>
442
+ <span class="cline-any cline-yes">65x</span>
383
443
  <span class="cline-any cline-yes">3x</span>
384
444
  <span class="cline-any cline-yes">3x</span>
385
445
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -408,6 +468,10 @@ export interface SessionSwitchEvent {
408
468
  reason?: string;
409
469
  }
410
470
  &nbsp;
471
+ // Wall-clock cadence for the idle heartbeat that pumps the scheduler. Cron is
472
+ // minute-granular, so 30s gives sub-minute wake latency while idle.
473
+ const HEARTBEAT_MS = 30_000;
474
+ &nbsp;
411
475
  export interface SessionRuntimeOptions {
412
476
  pi: ExtensionAPI;
413
477
  getLoopScope: () =&gt; LoopScope;
@@ -449,6 +513,27 @@ export function registerSessionRuntimeHooks(options: SessionRuntimeOptions): voi
449
513
  &nbsp;
450
514
  let storeUpgraded = false;
451
515
  let persistedShown = false;
516
+ let heartbeatTimer: ReturnType&lt;typeof setInterval&gt; | undefined;
517
+ &nbsp;
518
+ // The CronScheduler is pump-driven; without this heartbeat it only advances at
519
+ // turn boundaries (turn_start/agent_end), so a loop whose fire time elapses
520
+ // while the agent is idle would never fire and never re-wake the agent. The
521
+ // timer is unref'd so it never keeps a one-shot (`pi -p`) process alive.
522
+ function ensureHeartbeat(): void {
523
+ if (heartbeatTimer) return;
524
+ heartbeatTimer = setInterval(() =&gt; {
525
+ // Swallow pump failures so a transient error never surfaces as an
526
+ // unhandled rejection; the next tick retries.
527
+ void pumpLoops().catch(() =&gt; {});
528
+ }, HEARTBEAT_MS);
529
+ heartbeatTimer.unref?.();
530
+ }
531
+ &nbsp;
532
+ function stopHeartbeat(): void {
533
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (!heartbeatTimer) <span class="cstat-no" title="statement not covered" >return;</span>
534
+ clearInterval(heartbeatTimer);
535
+ heartbeatTimer = undefined;
536
+ }
452
537
  &nbsp;
453
538
  function upgradeStoreIfNeeded(ctx: ExtensionContext) {
454
539
  if (storeUpgraded) return;
@@ -467,6 +552,7 @@ export function registerSessionRuntimeHooks(options: SessionRuntimeOptions): voi
467
552
  <span class="cstat-no" title="statement not covered" > getStore().clearExpired();</span>
468
553
  <span class="cstat-no" title="statement not covered" > getStore().expireEventLoops(sessionStartedAt);</span>
469
554
  <span class="cstat-no" title="statement not covered" > getTriggerSystem().start();</span>
555
+ <span class="cstat-no" title="statement not covered" > ensureHeartbeat();</span>
470
556
  <span class="cstat-no" title="statement not covered" > widget.update();</span>
471
557
  }
472
558
  }
@@ -478,7 +564,7 @@ export function registerSessionRuntimeHooks(options: SessionRuntimeOptions): voi
478
564
  if (!entry.autoTask) continue;
479
565
  <span class="missing-if-branch" title="if path not taken" >I</span>if (entry.trigger.type !== "cron" &amp;&amp; <span class="branch-1 cbranch-no" title="branch not covered" >entry.trigger.type !== "hybrid") <span class="cstat-no" title="statement not covered" >c</span>ontinue;</span>
480
566
  const nextFire = getScheduler().nextFire(entry.id);
481
- <span class="missing-if-branch" title="if path not taken" >I</span>if (!nextFire || Date.now() &lt; nextFire) <span class="cstat-no" title="statement not covered" >continue;</span>
567
+ if (!nextFire || Date.now() &lt; nextFire) continue;
482
568
  const pending = await hasPendingTasks();
483
569
  <span class="missing-if-branch" title="else path not taken" >E</span>if (pending &lt;= 0) pendingTasks.set(entry.id, true);
484
570
  }
@@ -490,6 +576,7 @@ export function registerSessionRuntimeHooks(options: SessionRuntimeOptions): voi
490
576
  setSessionId(ctx.sessionManager.getSessionId());
491
577
  widget.setUICtx(ctx.ui);
492
578
  upgradeStoreIfNeeded(ctx);
579
+ ensureHeartbeat();
493
580
  widget.update();
494
581
  await pumpLoops();
495
582
  });
@@ -498,6 +585,7 @@ export function registerSessionRuntimeHooks(options: SessionRuntimeOptions): voi
498
585
  setLatestCtx(ctx);
499
586
  widget.setUICtx(ctx.ui);
500
587
  upgradeStoreIfNeeded(ctx);
588
+ ensureHeartbeat();
501
589
  showPersistedLoops();
502
590
  widget.update();
503
591
  });
@@ -524,6 +612,7 @@ export function registerSessionRuntimeHooks(options: SessionRuntimeOptions): voi
524
612
  });
525
613
  &nbsp;
526
614
  pi.on("session_shutdown", async () =&gt; {
615
+ stopHeartbeat();
527
616
  notificationRuntime.clear("session_shutdown");
528
617
  });
529
618
  &nbsp;
@@ -531,6 +620,7 @@ export function registerSessionRuntimeHooks(options: SessionRuntimeOptions): voi
531
620
  setLatestCtx(ctx);
532
621
  widget.setUICtx(ctx.ui);
533
622
  getTriggerSystem().stop();
623
+ stopHeartbeat();
534
624
  notificationRuntime.clear("session_switch");
535
625
  setSessionId(undefined);
536
626
  &nbsp;
@@ -574,7 +664,7 @@ export function registerSessionRuntimeHooks(options: SessionRuntimeOptions): voi
574
664
  <div class='footer quiet pad2 space-top1 center small'>
575
665
  Code coverage generated by
576
666
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
577
- at 2026-06-18T14:16:07.591Z
667
+ at 2026-06-19T00:56:38.236Z
578
668
  </div>
579
669
  <script src="../../prettify.js"></script>
580
670
  <script>
@@ -23,16 +23,16 @@
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">93.75% </span>
26
+ <span class="strong">95.83% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>45/48</span>
28
+ <span class='fraction'>46/48</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">76% </span>
33
+ <span class="strong">80% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>19/25</span>
35
+ <span class='fraction'>20/25</span>
36
36
  </div>
37
37
 
38
38
 
@@ -238,8 +238,8 @@
238
238
  <span class="cline-any cline-neutral">&nbsp;</span>
239
239
  <span class="cline-any cline-neutral">&nbsp;</span>
240
240
  <span class="cline-any cline-neutral">&nbsp;</span>
241
- <span class="cline-any cline-yes">3x</span>
242
- <span class="cline-any cline-yes">3x</span>
241
+ <span class="cline-any cline-yes">4x</span>
242
+ <span class="cline-any cline-yes">4x</span>
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>
@@ -279,92 +279,92 @@
279
279
  <span class="cline-any cline-neutral">&nbsp;</span>
280
280
  <span class="cline-any cline-neutral">&nbsp;</span>
281
281
  <span class="cline-any cline-neutral">&nbsp;</span>
282
- <span class="cline-any cline-yes">60x</span>
282
+ <span class="cline-any cline-yes">73x</span>
283
283
  <span class="cline-any cline-neutral">&nbsp;</span>
284
284
  <span class="cline-any cline-neutral">&nbsp;</span>
285
- <span class="cline-any cline-yes">2x</span>
285
+ <span class="cline-any cline-yes">15x</span>
286
286
  <span class="cline-any cline-neutral">&nbsp;</span>
287
287
  <span class="cline-any cline-neutral">&nbsp;</span>
288
288
  <span class="cline-any cline-neutral">&nbsp;</span>
289
289
  <span class="cline-any cline-neutral">&nbsp;</span>
290
290
  <span class="cline-any cline-neutral">&nbsp;</span>
291
- <span class="cline-any cline-yes">10x</span>
291
+ <span class="cline-any cline-yes">16x</span>
292
292
  <span class="cline-any cline-neutral">&nbsp;</span>
293
293
  <span class="cline-any cline-neutral">&nbsp;</span>
294
294
  <span class="cline-any cline-neutral">&nbsp;</span>
295
295
  <span class="cline-any cline-neutral">&nbsp;</span>
296
296
  <span class="cline-any cline-neutral">&nbsp;</span>
297
- <span class="cline-any cline-yes">7x</span>
297
+ <span class="cline-any cline-yes">11x</span>
298
298
  <span class="cline-any cline-neutral">&nbsp;</span>
299
299
  <span class="cline-any cline-neutral">&nbsp;</span>
300
300
  <span class="cline-any cline-neutral">&nbsp;</span>
301
- <span class="cline-any cline-yes">34x</span>
302
- <span class="cline-any cline-yes">34x</span>
301
+ <span class="cline-any cline-yes">39x</span>
302
+ <span class="cline-any cline-yes">39x</span>
303
303
  <span class="cline-any cline-neutral">&nbsp;</span>
304
- <span class="cline-any cline-yes">4x</span>
305
- <span class="cline-any cline-yes">4x</span>
304
+ <span class="cline-any cline-yes">8x</span>
305
+ <span class="cline-any cline-yes">8x</span>
306
306
  <span class="cline-any cline-neutral">&nbsp;</span>
307
- <span class="cline-any cline-yes">3x</span>
308
- <span class="cline-any cline-yes">3x</span>
309
- <span class="cline-any cline-yes">3x</span>
310
- <span class="cline-any cline-yes">3x</span>
307
+ <span class="cline-any cline-yes">5x</span>
308
+ <span class="cline-any cline-yes">5x</span>
309
+ <span class="cline-any cline-yes">5x</span>
310
+ <span class="cline-any cline-yes">5x</span>
311
311
  <span class="cline-any cline-neutral">&nbsp;</span>
312
- <span class="cline-any cline-yes">3x</span>
313
- <span class="cline-any cline-yes">3x</span>
312
+ <span class="cline-any cline-yes">5x</span>
313
+ <span class="cline-any cline-yes">5x</span>
314
314
  <span class="cline-any cline-neutral">&nbsp;</span>
315
315
  <span class="cline-any cline-neutral">&nbsp;</span>
316
316
  <span class="cline-any cline-neutral">&nbsp;</span>
317
- <span class="cline-any cline-yes">7x</span>
317
+ <span class="cline-any cline-yes">11x</span>
318
318
  <span class="cline-any cline-neutral">&nbsp;</span>
319
- <span class="cline-any cline-yes">7x</span>
320
- <span class="cline-any cline-yes">7x</span>
319
+ <span class="cline-any cline-yes">10x</span>
320
+ <span class="cline-any cline-yes">10x</span>
321
321
  <span class="cline-any cline-neutral">&nbsp;</span>
322
- <span class="cline-any cline-yes">6x</span>
322
+ <span class="cline-any cline-yes">8x</span>
323
323
  <span class="cline-any cline-neutral">&nbsp;</span>
324
324
  <span class="cline-any cline-neutral">&nbsp;</span>
325
325
  <span class="cline-any cline-neutral">&nbsp;</span>
326
326
  <span class="cline-any cline-neutral">&nbsp;</span>
327
327
  <span class="cline-any cline-neutral">&nbsp;</span>
328
- <span class="cline-any cline-yes">6x</span>
328
+ <span class="cline-any cline-yes">8x</span>
329
329
  <span class="cline-any cline-neutral">&nbsp;</span>
330
330
  <span class="cline-any cline-neutral">&nbsp;</span>
331
331
  <span class="cline-any cline-neutral">&nbsp;</span>
332
332
  <span class="cline-any cline-neutral">&nbsp;</span>
333
- <span class="cline-any cline-yes">6x</span>
334
- <span class="cline-any cline-yes">6x</span>
335
- <span class="cline-any cline-yes">6x</span>
336
- <span class="cline-any cline-yes">6x</span>
333
+ <span class="cline-any cline-yes">8x</span>
334
+ <span class="cline-any cline-yes">8x</span>
335
+ <span class="cline-any cline-yes">8x</span>
336
+ <span class="cline-any cline-yes">8x</span>
337
337
  <span class="cline-any cline-neutral">&nbsp;</span>
338
338
  <span class="cline-any cline-neutral">&nbsp;</span>
339
339
  <span class="cline-any cline-neutral">&nbsp;</span>
340
- <span class="cline-any cline-yes">60x</span>
341
- <span class="cline-any cline-yes">60x</span>
340
+ <span class="cline-any cline-yes">73x</span>
341
+ <span class="cline-any cline-yes">73x</span>
342
342
  <span class="cline-any cline-neutral">&nbsp;</span>
343
- <span class="cline-any cline-yes">60x</span>
344
- <span class="cline-any cline-yes">70x</span>
345
- <span class="cline-any cline-yes">70x</span>
343
+ <span class="cline-any cline-yes">73x</span>
344
+ <span class="cline-any cline-yes">72x</span>
345
+ <span class="cline-any cline-yes">72x</span>
346
346
  <span class="cline-any cline-neutral">&nbsp;</span>
347
347
  <span class="cline-any cline-neutral">&nbsp;</span>
348
- <span class="cline-any cline-yes">60x</span>
348
+ <span class="cline-any cline-yes">73x</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
- <span class="cline-any cline-yes">7x</span>
353
- <span class="cline-any cline-yes">7x</span>
352
+ <span class="cline-any cline-yes">8x</span>
353
+ <span class="cline-any cline-yes">8x</span>
354
354
  <span class="cline-any cline-neutral">&nbsp;</span>
355
355
  <span class="cline-any cline-neutral">&nbsp;</span>
356
- <span class="cline-any cline-yes">10x</span>
356
+ <span class="cline-any cline-yes">11x</span>
357
357
  <span class="cline-any cline-neutral">&nbsp;</span>
358
358
  <span class="cline-any cline-neutral">&nbsp;</span>
359
359
  <span class="cline-any cline-neutral">&nbsp;</span>
360
360
  <span class="cline-any cline-neutral">&nbsp;</span>
361
361
  <span class="cline-any cline-neutral">&nbsp;</span>
362
- <span class="cline-any cline-yes">70x</span>
363
- <span class="cline-any cline-yes">70x</span>
364
- <span class="cline-any cline-yes">70x</span>
365
- <span class="cline-any cline-yes">70x</span>
362
+ <span class="cline-any cline-yes">72x</span>
363
+ <span class="cline-any cline-yes">72x</span>
364
+ <span class="cline-any cline-yes">72x</span>
365
+ <span class="cline-any cline-yes">72x</span>
366
366
  <span class="cline-any cline-neutral">&nbsp;</span>
367
- <span class="cline-any cline-yes">70x</span>
367
+ <span class="cline-any cline-yes">72x</span>
368
368
  <span class="cline-any cline-neutral">&nbsp;</span>
369
369
  <span class="cline-any cline-neutral">&nbsp;</span>
370
370
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -372,15 +372,15 @@
372
372
  <span class="cline-any cline-neutral">&nbsp;</span>
373
373
  <span class="cline-any cline-neutral">&nbsp;</span>
374
374
  <span class="cline-any cline-neutral">&nbsp;</span>
375
- <span class="cline-any cline-yes">70x</span>
376
- <span class="cline-any cline-yes">70x</span>
375
+ <span class="cline-any cline-yes">72x</span>
376
+ <span class="cline-any cline-yes">72x</span>
377
377
  <span class="cline-any cline-neutral">&nbsp;</span>
378
378
  <span class="cline-any cline-neutral">&nbsp;</span>
379
379
  <span class="cline-any cline-neutral">&nbsp;</span>
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">60x</span>
383
+ <span class="cline-any cline-yes">73x</span>
384
384
  <span class="cline-any cline-neutral">&nbsp;</span>
385
385
  <span class="cline-any cline-neutral">&nbsp;</span>
386
386
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -477,7 +477,7 @@ export function createTaskBacklogRuntime(options: TaskBacklogRuntimeOptions): Ta
477
477
  }
478
478
  &nbsp;
479
479
  async function ensureAutoTaskWorkerLoop(taskStore: TaskStore): Promise&lt;{ entry?: LoopEntry; created: boolean }&gt; {
480
- <span class="missing-if-branch" title="if path not taken" >I</span>if (taskStore.pendingCount() &lt; AUTO_TASK_WORKER_THRESHOLD) <span class="cstat-no" title="statement not covered" >return { created: false };</span>
480
+ if (taskStore.pendingCount() &lt; AUTO_TASK_WORKER_THRESHOLD) return { created: false };
481
481
  &nbsp;
482
482
  const existing = findAutoTaskWorkerLoop();
483
483
  if (existing) return { entry: existing, created: false };
@@ -559,7 +559,7 @@ export function createTaskBacklogRuntime(options: TaskBacklogRuntimeOptions): Ta
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-06-18T14:16:07.591Z
562
+ at 2026-06-19T00:56:38.236Z
563
563
  </div>
564
564
  <script src="../../prettify.js"></script>
565
565
  <script>