@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">66.66% </span>
26
+ <span class="strong">83.87% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>62/93</span>
28
+ <span class='fraction'>78/93</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">52.08% </span>
33
+ <span class="strong">80.2% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>50/96</span>
35
+ <span class='fraction'>77/96</span>
36
36
  </div>
37
37
 
38
38
 
39
39
  <div class='fl pad1y space-right2'>
40
- <span class="strong">87.5% </span>
40
+ <span class="strong">100% </span>
41
41
  <span class="quiet">Functions</span>
42
- <span class='fraction'>7/8</span>
42
+ <span class='fraction'>8/8</span>
43
43
  </div>
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
- <span class="strong">69.51% </span>
47
+ <span class="strong">85.36% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>57/82</span>
49
+ <span class='fraction'>70/82</span>
50
50
  </div>
51
51
 
52
52
 
@@ -61,7 +61,7 @@
61
61
  </div>
62
62
  </template>
63
63
  </div>
64
- <div class='status-line medium'></div>
64
+ <div class='status-line high'></div>
65
65
  <pre><table class="coverage">
66
66
  <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
67
  <a name='L2'></a><a href='#L2'>2</a>
@@ -417,36 +417,36 @@
417
417
  <span class="cline-any cline-neutral">&nbsp;</span>
418
418
  <span class="cline-any cline-neutral">&nbsp;</span>
419
419
  <span class="cline-any cline-neutral">&nbsp;</span>
420
- <span class="cline-any cline-yes">37x</span>
420
+ <span class="cline-any cline-yes">55x</span>
421
421
  <span class="cline-any cline-neutral">&nbsp;</span>
422
422
  <span class="cline-any cline-neutral">&nbsp;</span>
423
423
  <span class="cline-any cline-neutral">&nbsp;</span>
424
- <span class="cline-any cline-yes">15x</span>
425
- <span class="cline-any cline-yes">4x</span>
426
- <span class="cline-any cline-yes">4x</span>
424
+ <span class="cline-any cline-yes">28x</span>
425
+ <span class="cline-any cline-yes">13x</span>
426
+ <span class="cline-any cline-yes">13x</span>
427
427
  <span class="cline-any cline-no">&nbsp;</span>
428
428
  <span class="cline-any cline-neutral">&nbsp;</span>
429
- <span class="cline-any cline-yes">11x</span>
430
- <span class="cline-any cline-yes">11x</span>
431
- <span class="cline-any cline-no">&nbsp;</span>
429
+ <span class="cline-any cline-yes">15x</span>
430
+ <span class="cline-any cline-yes">14x</span>
431
+ <span class="cline-any cline-yes">1x</span>
432
432
  <span class="cline-any cline-neutral">&nbsp;</span>
433
- <span class="cline-any cline-no">&nbsp;</span>
434
- <span class="cline-any cline-no">&nbsp;</span>
435
- <span class="cline-any cline-no">&nbsp;</span>
433
+ <span class="cline-any cline-yes">1x</span>
434
+ <span class="cline-any cline-yes">1x</span>
435
+ <span class="cline-any cline-yes">1x</span>
436
436
  <span class="cline-any cline-no">&nbsp;</span>
437
437
  <span class="cline-any cline-neutral">&nbsp;</span>
438
- <span class="cline-any cline-no">&nbsp;</span>
438
+ <span class="cline-any cline-yes">1x</span>
439
439
  <span class="cline-any cline-no">&nbsp;</span>
440
440
  <span class="cline-any cline-neutral">&nbsp;</span>
441
441
  <span class="cline-any cline-neutral">&nbsp;</span>
442
- <span class="cline-any cline-yes">15x</span>
442
+ <span class="cline-any cline-yes">27x</span>
443
443
  <span class="cline-any cline-neutral">&nbsp;</span>
444
444
  <span class="cline-any cline-neutral">&nbsp;</span>
445
445
  <span class="cline-any cline-neutral">&nbsp;</span>
446
- <span class="cline-any cline-no">&nbsp;</span>
447
- <span class="cline-any cline-no">&nbsp;</span>
448
- <span class="cline-any cline-no">&nbsp;</span>
449
- <span class="cline-any cline-no">&nbsp;</span>
446
+ <span class="cline-any cline-yes">3x</span>
447
+ <span class="cline-any cline-yes">3x</span>
448
+ <span class="cline-any cline-yes">2x</span>
449
+ <span class="cline-any cline-yes">1x</span>
450
450
  <span class="cline-any cline-neutral">&nbsp;</span>
451
451
  <span class="cline-any cline-neutral">&nbsp;</span>
452
452
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -465,9 +465,9 @@
465
465
  <span class="cline-any cline-neutral">&nbsp;</span>
466
466
  <span class="cline-any cline-neutral">&nbsp;</span>
467
467
  <span class="cline-any cline-neutral">&nbsp;</span>
468
- <span class="cline-any cline-yes">60x</span>
468
+ <span class="cline-any cline-yes">74x</span>
469
469
  <span class="cline-any cline-neutral">&nbsp;</span>
470
- <span class="cline-any cline-yes">60x</span>
470
+ <span class="cline-any cline-yes">74x</span>
471
471
  <span class="cline-any cline-neutral">&nbsp;</span>
472
472
  <span class="cline-any cline-neutral">&nbsp;</span>
473
473
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -535,21 +535,21 @@
535
535
  <span class="cline-any cline-neutral">&nbsp;</span>
536
536
  <span class="cline-any cline-neutral">&nbsp;</span>
537
537
  <span class="cline-any cline-neutral">&nbsp;</span>
538
- <span class="cline-any cline-yes">15x</span>
538
+ <span class="cline-any cline-yes">28x</span>
539
539
  <span class="cline-any cline-neutral">&nbsp;</span>
540
540
  <span class="cline-any cline-neutral">&nbsp;</span>
541
- <span class="cline-any cline-yes">15x</span>
541
+ <span class="cline-any cline-yes">28x</span>
542
542
  <span class="cline-any cline-neutral">&nbsp;</span>
543
+ <span class="cline-any cline-yes">28x</span>
544
+ <span class="cline-any cline-yes">13x</span>
545
+ <span class="cline-any cline-yes">13x</span>
543
546
  <span class="cline-any cline-yes">15x</span>
544
- <span class="cline-any cline-yes">4x</span>
545
- <span class="cline-any cline-yes">4x</span>
546
- <span class="cline-any cline-yes">11x</span>
547
- <span class="cline-any cline-yes">11x</span>
547
+ <span class="cline-any cline-yes">14x</span>
548
548
  <span class="cline-any cline-neutral">&nbsp;</span>
549
- <span class="cline-any cline-no">&nbsp;</span>
550
- <span class="cline-any cline-no">&nbsp;</span>
551
- <span class="cline-any cline-no">&nbsp;</span>
552
- <span class="cline-any cline-no">&nbsp;</span>
549
+ <span class="cline-any cline-yes">1x</span>
550
+ <span class="cline-any cline-yes">1x</span>
551
+ <span class="cline-any cline-yes">1x</span>
552
+ <span class="cline-any cline-yes">1x</span>
553
553
  <span class="cline-any cline-neutral">&nbsp;</span>
554
554
  <span class="cline-any cline-neutral">&nbsp;</span>
555
555
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -557,10 +557,10 @@
557
557
  <span class="cline-any cline-neutral">&nbsp;</span>
558
558
  <span class="cline-any cline-neutral">&nbsp;</span>
559
559
  <span class="cline-any cline-neutral">&nbsp;</span>
560
- <span class="cline-any cline-yes">15x</span>
561
- <span class="cline-any cline-yes">15x</span>
560
+ <span class="cline-any cline-yes">28x</span>
561
+ <span class="cline-any cline-yes">28x</span>
562
562
  <span class="cline-any cline-neutral">&nbsp;</span>
563
- <span class="cline-any cline-yes">15x</span>
563
+ <span class="cline-any cline-yes">27x</span>
564
564
  <span class="cline-any cline-neutral">&nbsp;</span>
565
565
  <span class="cline-any cline-neutral">&nbsp;</span>
566
566
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -568,9 +568,9 @@
568
568
  <span class="cline-any cline-neutral">&nbsp;</span>
569
569
  <span class="cline-any cline-neutral">&nbsp;</span>
570
570
  <span class="cline-any cline-neutral">&nbsp;</span>
571
- <span class="cline-any cline-yes">15x</span>
571
+ <span class="cline-any cline-yes">28x</span>
572
572
  <span class="cline-any cline-neutral">&nbsp;</span>
573
- <span class="cline-any cline-yes">15x</span>
573
+ <span class="cline-any cline-yes">28x</span>
574
574
  <span class="cline-any cline-no">&nbsp;</span>
575
575
  <span class="cline-any cline-no">&nbsp;</span>
576
576
  <span class="cline-any cline-no">&nbsp;</span>
@@ -586,16 +586,16 @@
586
586
  <span class="cline-any cline-neutral">&nbsp;</span>
587
587
  <span class="cline-any cline-neutral">&nbsp;</span>
588
588
  <span class="cline-any cline-neutral">&nbsp;</span>
589
- <span class="cline-any cline-yes">15x</span>
590
- <span class="cline-any cline-yes">15x</span>
589
+ <span class="cline-any cline-yes">27x</span>
590
+ <span class="cline-any cline-yes">27x</span>
591
591
  <span class="cline-any cline-neutral">&nbsp;</span>
592
- <span class="cline-any cline-yes">15x</span>
592
+ <span class="cline-any cline-yes">27x</span>
593
593
  <span class="cline-any cline-neutral">&nbsp;</span>
594
594
  <span class="cline-any cline-neutral">&nbsp;</span>
595
595
  <span class="cline-any cline-neutral">&nbsp;</span>
596
596
  <span class="cline-any cline-neutral">&nbsp;</span>
597
597
  <span class="cline-any cline-neutral">&nbsp;</span>
598
- <span class="cline-any cline-yes">15x</span>
598
+ <span class="cline-any cline-yes">28x</span>
599
599
  <span class="cline-any cline-neutral">&nbsp;</span>
600
600
  <span class="cline-any cline-neutral">&nbsp;</span>
601
601
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -608,7 +608,7 @@
608
608
  <span class="cline-any cline-neutral">&nbsp;</span>
609
609
  <span class="cline-any cline-neutral">&nbsp;</span>
610
610
  <span class="cline-any cline-neutral">&nbsp;</span>
611
- <span class="cline-any cline-yes">60x</span>
611
+ <span class="cline-any cline-yes">74x</span>
612
612
  <span class="cline-any cline-neutral">&nbsp;</span>
613
613
  <span class="cline-any cline-neutral">&nbsp;</span>
614
614
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -616,35 +616,35 @@
616
616
  <span class="cline-any cline-neutral">&nbsp;</span>
617
617
  <span class="cline-any cline-neutral">&nbsp;</span>
618
618
  <span class="cline-any cline-neutral">&nbsp;</span>
619
- <span class="cline-any cline-yes">16x</span>
620
- <span class="cline-any cline-yes">16x</span>
619
+ <span class="cline-any cline-yes">18x</span>
620
+ <span class="cline-any cline-yes">18x</span>
621
621
  <span class="cline-any cline-neutral">&nbsp;</span>
622
- <span class="cline-any cline-yes">8x</span>
623
- <span class="cline-any cline-yes">8x</span>
624
- <span class="cline-any cline-yes">8x</span>
622
+ <span class="cline-any cline-yes">9x</span>
623
+ <span class="cline-any cline-yes">9x</span>
624
+ <span class="cline-any cline-yes">9x</span>
625
625
  <span class="cline-any cline-neutral">&nbsp;</span>
626
626
  <span class="cline-any cline-neutral">&nbsp;</span>
627
627
  <span class="cline-any cline-neutral">&nbsp;</span>
628
628
  <span class="cline-any cline-neutral">&nbsp;</span>
629
629
  <span class="cline-any cline-neutral">&nbsp;</span>
630
- <span class="cline-any cline-yes">8x</span>
631
- <span class="cline-any cline-yes">8x</span>
632
- <span class="cline-any cline-yes">8x</span>
633
- <span class="cline-any cline-yes">8x</span>
634
- <span class="cline-any cline-yes">8x</span>
630
+ <span class="cline-any cline-yes">9x</span>
631
+ <span class="cline-any cline-yes">9x</span>
632
+ <span class="cline-any cline-yes">9x</span>
633
+ <span class="cline-any cline-yes">9x</span>
634
+ <span class="cline-any cline-yes">9x</span>
635
635
  <span class="cline-any cline-yes">4x</span>
636
636
  <span class="cline-any cline-yes">4x</span>
637
637
  <span class="cline-any cline-neutral">&nbsp;</span>
638
- <span class="cline-any cline-yes">8x</span>
639
- <span class="cline-any cline-yes">8x</span>
640
- <span class="cline-any cline-yes">8x</span>
638
+ <span class="cline-any cline-yes">9x</span>
639
+ <span class="cline-any cline-yes">9x</span>
640
+ <span class="cline-any cline-yes">9x</span>
641
641
  <span class="cline-any cline-neutral">&nbsp;</span>
642
642
  <span class="cline-any cline-neutral">&nbsp;</span>
643
- <span class="cline-any cline-yes">8x</span>
643
+ <span class="cline-any cline-yes">9x</span>
644
644
  <span class="cline-any cline-neutral">&nbsp;</span>
645
645
  <span class="cline-any cline-neutral">&nbsp;</span>
646
646
  <span class="cline-any cline-neutral">&nbsp;</span>
647
- <span class="cline-any cline-yes">60x</span>
647
+ <span class="cline-any cline-yes">74x</span>
648
648
  <span class="cline-any cline-neutral">&nbsp;</span>
649
649
  <span class="cline-any cline-neutral">&nbsp;</span>
650
650
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -655,21 +655,21 @@
655
655
  <span class="cline-any cline-neutral">&nbsp;</span>
656
656
  <span class="cline-any cline-neutral">&nbsp;</span>
657
657
  <span class="cline-any cline-neutral">&nbsp;</span>
658
- <span class="cline-any cline-yes">6x</span>
658
+ <span class="cline-any cline-yes">9x</span>
659
659
  <span class="cline-any cline-neutral">&nbsp;</span>
660
- <span class="cline-any cline-yes">6x</span>
660
+ <span class="cline-any cline-yes">9x</span>
661
+ <span class="cline-any cline-yes">3x</span>
662
+ <span class="cline-any cline-yes">3x</span>
663
+ <span class="cline-any cline-yes">2x</span>
661
664
  <span class="cline-any cline-yes">2x</span>
662
665
  <span class="cline-any cline-yes">2x</span>
663
- <span class="cline-any cline-yes">1x</span>
664
- <span class="cline-any cline-yes">1x</span>
665
- <span class="cline-any cline-yes">1x</span>
666
666
  <span class="cline-any cline-neutral">&nbsp;</span>
667
667
  <span class="cline-any cline-neutral">&nbsp;</span>
668
- <span class="cline-any cline-yes">4x</span>
669
- <span class="cline-any cline-yes">4x</span>
670
- <span class="cline-any cline-yes">4x</span>
671
- <span class="cline-any cline-yes">4x</span>
672
- <span class="cline-any cline-yes">1x</span>
668
+ <span class="cline-any cline-yes">6x</span>
669
+ <span class="cline-any cline-yes">6x</span>
670
+ <span class="cline-any cline-yes">6x</span>
671
+ <span class="cline-any cline-yes">6x</span>
672
+ <span class="cline-any cline-yes">2x</span>
673
673
  <span class="cline-any cline-neutral">&nbsp;</span>
674
674
  <span class="cline-any cline-neutral">&nbsp;</span>
675
675
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -732,26 +732,26 @@ function validateTrigger(trigger: Trigger): string | null {
732
732
  <span class="cstat-no" title="statement not covered" > return `Invalid cron trigger. Expected 5 fields, got ${parts.length}: "${trigger.schedule}". Use formats like "5m", "1h", "0 9 * * 1-5", or set triggerType to "event" for event sources.`;</span>
733
733
  }
734
734
  } else if (trigger.type === "event") {
735
- <span class="missing-if-branch" title="if path not taken" >I</span>if (!trigger.source || trigger.source.trim().length === 0) {
736
- <span class="cstat-no" title="statement not covered" > return "Invalid event trigger. Event source must be non-empty (e.g., \"tool_execution_start\").";</span>
735
+ if (!trigger.source || trigger.source.trim().length === 0) {
736
+ return "Invalid event trigger. Event source must be non-empty (e.g., \"tool_execution_start\").";
737
737
  }
738
- } else <span class="cstat-no" title="statement not covered" ><span class="missing-if-branch" title="else path not taken" >E</span>if (trigger.type === "hybrid") {</span>
739
- const cronParts = <span class="cstat-no" title="statement not covered" >trigger.cron.trim().split(/\s+/);</span>
740
- <span class="cstat-no" title="statement not covered" > if (cronParts.length !== 5) {</span>
738
+ } else <span class="missing-if-branch" title="else path not taken" >E</span>if (trigger.type === "hybrid") {
739
+ const cronParts = trigger.cron.trim().split(/\s+/);
740
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (cronParts.length !== 5) {
741
741
  <span class="cstat-no" title="statement not covered" > return `Invalid hybrid trigger. Cron part must have 5 fields, got ${cronParts.length}: "${trigger.cron}".`;</span>
742
742
  }
743
- <span class="cstat-no" title="statement not covered" > if (!trigger.event.source || trigger.event.source.trim().length === 0) {</span>
743
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (!trigger.event.source || trigger.event.source.trim().length === 0) {
744
744
  <span class="cstat-no" title="statement not covered" > return "Invalid hybrid trigger. Event source must be non-empty (e.g., \"tool_execution_start\").";</span>
745
745
  }
746
746
  }
747
747
  return null;
748
748
  }
749
749
  &nbsp;
750
- function <span class="fstat-no" title="function not covered" >inferTriggerType(i</span>nput: string): "cron" | "event" | "hybrid" {
751
- <span class="cstat-no" title="statement not covered" > if (input.includes("hybrid") || (input.includes("cron") &amp;&amp; input.includes("event"))) <span class="cstat-no" title="statement not covered" >return "hybrid";</span></span>
752
- <span class="cstat-no" title="statement not covered" > if (/^\d+\s*[smhd]$/i.test(input.trim())) <span class="cstat-no" title="statement not covered" >return "cron";</span></span>
753
- <span class="cstat-no" title="statement not covered" > if (/^(\*|\d+)/.test(input.trim()) &amp;&amp; input.trim().split(/\s+/).length === 5) <span class="cstat-no" title="statement not covered" >return "cron";</span></span>
754
- <span class="cstat-no" title="statement not covered" > return "event";</span>
750
+ function inferTriggerType(input: string): "cron" | "event" | "hybrid" {
751
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (input.includes("hybrid") || (input.includes("cron") &amp;&amp; <span class="branch-2 cbranch-no" title="branch not covered" >input.includes("event"))) <span class="cstat-no" title="statement not covered" >r</span>eturn "hybrid";</span>
752
+ if (/^\d+\s*[smhd]$/i.test(input.trim())) return "cron";
753
+ if (/^(\*|\d+)/.test(input.trim()) &amp;&amp; input.trim().split(/\s+/).length === 5) return "cron";
754
+ return "event";
755
755
  }
756
756
  &nbsp;
757
757
  function formatRemaining(ms: number): string {
@@ -843,18 +843,18 @@ Skip this tool when the task is a one-off check (just do it directly) or when th
843
843
  const { trigger: triggerInput, prompt, recurring, autoTask, taskBacklog, triggerType, debounceMs, readOnly, maxFires } = params;
844
844
  &nbsp;
845
845
  let trigger: Trigger;
846
- const inferred = triggerType ?? <span class="branch-1 cbranch-no" title="branch not covered" >inferTriggerType(triggerInput);</span>
846
+ const inferred = triggerType ?? inferTriggerType(triggerInput);
847
847
  &nbsp;
848
848
  if (inferred === "cron") {
849
849
  const parsed = parseInterval(triggerInput);
850
850
  trigger = { type: "cron", schedule: parsed.cron };
851
851
  } else if (inferred === "event") {
852
852
  trigger = { type: "event", source: triggerInput };
853
- } else <span class="missing-if-branch" title="else path not taken" >E</span>{
854
- const cronPart = <span class="cstat-no" title="statement not covered" >triggerInput.match(/cron:?\s*(\S+)/)?.[1] || triggerInput;</span>
855
- const eventPart = <span class="cstat-no" title="statement not covered" >triggerInput.match(/event:?\s*(\S+)/)?.[1];</span>
856
- const <span class="cstat-no" title="statement not covered" >parsed = parseInterval(cronPart);</span>
857
- <span class="cstat-no" title="statement not covered" > trigger = {</span>
853
+ } else {
854
+ const cronPart = triggerInput.match(/cron:?\s*(\S+)/)?.[1] || triggerInput;
855
+ const eventPart = triggerInput.match(/event:?\s*(\S+)/)?.[1];
856
+ const parsed = parseInterval(cronPart);
857
+ trigger = {
858
858
  type: "hybrid",
859
859
  cron: parsed.cron,
860
860
  event: { source: eventPart || "tool_execution_start" },
@@ -863,7 +863,7 @@ Skip this tool when the task is a one-off check (just do it directly) or when th
863
863
  }
864
864
  &nbsp;
865
865
  const validationError = validateTrigger(trigger);
866
- <span class="missing-if-branch" title="if path not taken" >I</span>if (validationError) <span class="cstat-no" title="statement not covered" >return Promise.resolve(textResult(validationError));</span>
866
+ if (validationError) return Promise.resolve(textResult(validationError));
867
867
  &nbsp;
868
868
  const entry = getStore().create(trigger, prompt, {
869
869
  recurring: recurring ?? (inferred !== "event"),
@@ -898,7 +898,7 @@ Skip this tool when the task is a one-off check (just do it directly) or when th
898
898
  ? `schedule: ${trigger.schedule}`
899
899
  : trigger.type === "event"
900
900
  ? `event: ${trigger.source}`
901
- : <span class="branch-1 cbranch-no" title="branch not covered" >`hybrid: cron ${trigger.cron} + event ${trigger.event.source}`;</span>
901
+ : `hybrid: cron ${trigger.cron} + event ${trigger.event.source}`;
902
902
  &nbsp;
903
903
  return Promise.resolve(textResult(
904
904
  `Loop #${entry.id} created: ${entry.prompt.slice(0, 60)}\n` +
@@ -927,7 +927,7 @@ Use this before creating new loops to avoid duplicates, or to find IDs for LoopD
927
927
  const lines: string[] = [];
928
928
  for (const entry of loops) {
929
929
  const triggerDesc = entry.trigger.type === "cron"
930
- ? <span class="branch-0 cbranch-no" title="branch not covered" >`cron: ${entry.trigger.schedule}`</span>
930
+ ? `cron: ${entry.trigger.schedule}`
931
931
  : entry.trigger.type === "event"
932
932
  ? `event: ${entry.trigger.source}`
933
933
  : `hybrid: ${entry.trigger.cron} + ${entry.trigger.event.source}`;
@@ -985,7 +985,7 @@ Use "pause" to temporarily stop a loop without removing it. Use "delete" to perm
985
985
  <div class='footer quiet pad2 space-top1 center small'>
986
986
  Code coverage generated by
987
987
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
988
- at 2026-06-18T14:16:07.591Z
988
+ at 2026-06-19T00:56:38.236Z
989
989
  </div>
990
990
  <script src="../../prettify.js"></script>
991
991
  <script>
@@ -23,30 +23,30 @@
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">79.54% </span>
26
+ <span class="strong">93.18% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>35/44</span>
28
+ <span class='fraction'>41/44</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">66.66% </span>
33
+ <span class="strong">83.33% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>16/24</span>
35
+ <span class='fraction'>20/24</span>
36
36
  </div>
37
37
 
38
38
 
39
39
  <div class='fl pad1y space-right2'>
40
- <span class="strong">85.71% </span>
40
+ <span class="strong">100% </span>
41
41
  <span class="quiet">Functions</span>
42
- <span class='fraction'>6/7</span>
42
+ <span class='fraction'>7/7</span>
43
43
  </div>
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
- <span class="strong">84.21% </span>
47
+ <span class="strong">94.73% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>32/38</span>
49
+ <span class='fraction'>36/38</span>
50
50
  </div>
51
51
 
52
52
 
@@ -61,7 +61,7 @@
61
61
  </div>
62
62
  </template>
63
63
  </div>
64
- <div class='status-line medium'></div>
64
+ <div class='status-line high'></div>
65
65
  <pre><table class="coverage">
66
66
  <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
67
  <a name='L2'></a><a href='#L2'>2</a>
@@ -246,19 +246,19 @@
246
246
  <span class="cline-any cline-neutral">&nbsp;</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">18x</span>
249
+ <span class="cline-any cline-yes">25x</span>
250
250
  <span class="cline-any cline-neutral">&nbsp;</span>
251
251
  <span class="cline-any cline-neutral">&nbsp;</span>
252
252
  <span class="cline-any cline-neutral">&nbsp;</span>
253
- <span class="cline-any cline-yes">3x</span>
253
+ <span class="cline-any cline-yes">4x</span>
254
254
  <span class="cline-any cline-no">&nbsp;</span>
255
255
  <span class="cline-any cline-no">&nbsp;</span>
256
256
  <span class="cline-any cline-neutral">&nbsp;</span>
257
257
  <span class="cline-any cline-neutral">&nbsp;</span>
258
258
  <span class="cline-any cline-neutral">&nbsp;</span>
259
- <span class="cline-any cline-yes">60x</span>
259
+ <span class="cline-any cline-yes">68x</span>
260
260
  <span class="cline-any cline-neutral">&nbsp;</span>
261
- <span class="cline-any cline-yes">60x</span>
261
+ <span class="cline-any cline-yes">68x</span>
262
262
  <span class="cline-any cline-neutral">&nbsp;</span>
263
263
  <span class="cline-any cline-neutral">&nbsp;</span>
264
264
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -292,15 +292,15 @@
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
- <span class="cline-any cline-yes">11x</span>
296
- <span class="cline-any cline-no">&nbsp;</span>
295
+ <span class="cline-any cline-yes">25x</span>
296
+ <span class="cline-any cline-yes">1x</span>
297
297
  <span class="cline-any cline-neutral">&nbsp;</span>
298
298
  <span class="cline-any cline-neutral">&nbsp;</span>
299
- <span class="cline-any cline-yes">11x</span>
300
- <span class="cline-any cline-yes">11x</span>
299
+ <span class="cline-any cline-yes">13x</span>
300
+ <span class="cline-any cline-yes">13x</span>
301
301
  <span class="cline-any cline-neutral">&nbsp;</span>
302
- <span class="cline-any cline-yes">11x</span>
303
- <span class="cline-any cline-yes">11x</span>
302
+ <span class="cline-any cline-yes">13x</span>
303
+ <span class="cline-any cline-yes">13x</span>
304
304
  <span class="cline-any cline-neutral">&nbsp;</span>
305
305
  <span class="cline-any cline-neutral">&nbsp;</span>
306
306
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -310,13 +310,13 @@
310
310
  <span class="cline-any cline-neutral">&nbsp;</span>
311
311
  <span class="cline-any cline-neutral">&nbsp;</span>
312
312
  <span class="cline-any cline-neutral">&nbsp;</span>
313
- <span class="cline-any cline-yes">7x</span>
314
- <span class="cline-any cline-yes">7x</span>
315
- <span class="cline-any cline-yes">7x</span>
316
- <span class="cline-any cline-yes">7x</span>
313
+ <span class="cline-any cline-yes">8x</span>
314
+ <span class="cline-any cline-yes">8x</span>
315
+ <span class="cline-any cline-yes">8x</span>
316
+ <span class="cline-any cline-yes">8x</span>
317
317
  <span class="cline-any cline-neutral">&nbsp;</span>
318
318
  <span class="cline-any cline-neutral">&nbsp;</span>
319
- <span class="cline-any cline-yes">11x</span>
319
+ <span class="cline-any cline-yes">13x</span>
320
320
  <span class="cline-any cline-neutral">&nbsp;</span>
321
321
  <span class="cline-any cline-neutral">&nbsp;</span>
322
322
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -324,37 +324,37 @@
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
- <span class="cline-any cline-yes">60x</span>
327
+ <span class="cline-any cline-yes">68x</span>
328
328
  <span class="cline-any cline-neutral">&nbsp;</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-neutral">&nbsp;</span>
336
+ <span class="cline-any cline-yes">4x</span>
337
+ <span class="cline-any cline-yes">4x</span>
338
+ <span class="cline-any cline-yes">4x</span>
339
+ <span class="cline-any cline-yes">4x</span>
340
+ <span class="cline-any cline-yes">4x</span>
341
+ <span class="cline-any cline-yes">4x</span>
333
342
  <span class="cline-any cline-yes">4x</span>
334
343
  <span class="cline-any cline-yes">4x</span>
335
344
  <span class="cline-any cline-neutral">&nbsp;</span>
336
- <span class="cline-any cline-yes">3x</span>
337
- <span class="cline-any cline-yes">3x</span>
338
- <span class="cline-any cline-yes">3x</span>
339
- <span class="cline-any cline-yes">3x</span>
340
- <span class="cline-any cline-yes">3x</span>
341
- <span class="cline-any cline-yes">3x</span>
342
- <span class="cline-any cline-yes">3x</span>
343
- <span class="cline-any cline-yes">3x</span>
344
- <span class="cline-any cline-neutral">&nbsp;</span>
345
- <span class="cline-any cline-yes">3x</span>
346
- <span class="cline-any cline-no">&nbsp;</span>
347
- <span class="cline-any cline-no">&nbsp;</span>
348
- <span class="cline-any cline-no">&nbsp;</span>
345
+ <span class="cline-any cline-yes">4x</span>
346
+ <span class="cline-any cline-yes">1x</span>
347
+ <span class="cline-any cline-yes">1x</span>
348
+ <span class="cline-any cline-yes">2x</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
- <span class="cline-any cline-yes">3x</span>
353
+ <span class="cline-any cline-yes">4x</span>
354
354
  <span class="cline-any cline-neutral">&nbsp;</span>
355
355
  <span class="cline-any cline-neutral">&nbsp;</span>
356
356
  <span class="cline-any cline-neutral">&nbsp;</span>
357
- <span class="cline-any cline-yes">60x</span>
357
+ <span class="cline-any cline-yes">68x</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>
@@ -364,10 +364,10 @@
364
364
  <span class="cline-any cline-neutral">&nbsp;</span>
365
365
  <span class="cline-any cline-neutral">&nbsp;</span>
366
366
  <span class="cline-any cline-neutral">&nbsp;</span>
367
- <span class="cline-any cline-yes">3x</span>
368
- <span class="cline-any cline-yes">3x</span>
369
- <span class="cline-any cline-yes">3x</span>
370
- <span class="cline-any cline-yes">1x</span>
367
+ <span class="cline-any cline-yes">5x</span>
368
+ <span class="cline-any cline-yes">5x</span>
369
+ <span class="cline-any cline-yes">5x</span>
370
+ <span class="cline-any cline-yes">2x</span>
371
371
  <span class="cline-any cline-neutral">&nbsp;</span>
372
372
  <span class="cline-any cline-neutral">&nbsp;</span>
373
373
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -446,8 +446,8 @@ Pass onDone with a prompt and the monitor auto-creates a one-shot loop that fire
446
446
  onDone: Type.Optional(Type.String({ description: "Prompt to run when the monitor completes. Auto-creates a one-shot completion wake — no need for a separate LoopCreate." })),
447
447
  }),
448
448
  execute(_toolCallId, params) {
449
- <span class="missing-if-branch" title="if path not taken" >I</span>if (getMonitorManager().list().<span class="fstat-no" title="function not covered" >filter((m</span>) =&gt; <span class="cstat-no" title="statement not covered" >m.status === "running")</span>.length &gt;= 25) {
450
- <span class="cstat-no" title="statement not covered" > return Promise.resolve(textResult("Maximum of 25 running monitors reached. Stop some before creating new ones."));</span>
449
+ if (getMonitorManager().list().filter((m) =&gt; m.status === "running").length &gt;= 25) {
450
+ return Promise.resolve(textResult("Maximum of 25 running monitors reached. Stop some before creating new ones."));
451
451
  }
452
452
  &nbsp;
453
453
  const entry = getMonitorManager().create(params.command, params.description, params.timeout);
@@ -489,17 +489,17 @@ Pass onDone with a prompt and the monitor auto-creates a one-shot loop that fire
489
489
  &nbsp;
490
490
  const lines: string[] = [];
491
491
  for (const m of monitors) {
492
- const icon = m.status === "running" ? "&gt;" : m.status === "completed" ? <span class="branch-0 cbranch-no" title="branch not covered" >"ok" : "</span>x";
492
+ const icon = m.status === "running" ? "&gt;" : m.status === "completed" ? "ok" : "x";
493
493
  const age = Date.now() - m.startedAt;
494
494
  const ageStr = formatRemaining(age);
495
495
  let line = `${icon} #${m.id} [${m.status}] ${m.command.slice(0, 60)} — ${m.outputLines} lines (${ageStr})`;
496
- <span class="missing-if-branch" title="if path not taken" >I</span>if (m.exitCode !== undefined) <span class="cstat-no" title="statement not covered" >line += ` exit=${m.exitCode}`;</span>
496
+ if (m.exitCode !== undefined) line += ` exit=${m.exitCode}`;
497
497
  lines.push(line);
498
498
  &nbsp;
499
- <span class="missing-if-branch" title="if path not taken" >I</span>if (m.status !== "running" &amp;&amp; m.outputBuffer.length &gt; 0) {
500
- const tail = <span class="cstat-no" title="statement not covered" >m.outputBuffer.slice(-5);</span>
501
- <span class="cstat-no" title="statement not covered" > for (const out of tail) {</span>
502
- <span class="cstat-no" title="statement not covered" > lines.push(` | ${out.slice(0, 100)}`);</span>
499
+ if (m.status !== "running" &amp;&amp; m.outputBuffer.length &gt; 0) {
500
+ const tail = m.outputBuffer.slice(-5);
501
+ for (const out of tail) {
502
+ lines.push(` | ${out.slice(0, 100)}`);
503
503
  }
504
504
  }
505
505
  }
@@ -532,7 +532,7 @@ Use MonitorList to find the monitor ID, then stop it with this tool.`,
532
532
  <div class='footer quiet pad2 space-top1 center small'>
533
533
  Code coverage generated by
534
534
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
535
- at 2026-06-18T14:16:07.591Z
535
+ at 2026-06-19T00:56:38.236Z
536
536
  </div>
537
537
  <script src="../../prettify.js"></script>
538
538
  <script>