@trevonistrevon/pi-loop 0.5.5 → 0.5.6
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/coverage/coverage-final.json +6 -6
- package/coverage/index.html +19 -19
- package/coverage/src/commands/index.html +1 -1
- package/coverage/src/commands/loop-command.ts.html +1 -1
- package/coverage/src/commands/tasks-command.ts.html +1 -1
- package/coverage/src/coordinator.ts.html +1 -1
- package/coverage/src/goal-coordinator.ts.html +1 -1
- package/coverage/src/goal-reducer.ts.html +1 -1
- package/coverage/src/goal-store.ts.html +1 -1
- package/coverage/src/goal-verifier.ts.html +1 -1
- package/coverage/src/index.html +25 -25
- package/coverage/src/index.ts.html +21 -12
- package/coverage/src/loop-parse.ts.html +22 -22
- package/coverage/src/loop-reducer.ts.html +1 -1
- package/coverage/src/monitor-completion-coordinator.ts.html +1 -1
- package/coverage/src/monitor-manager.ts.html +161 -92
- package/coverage/src/monitor-reducer.ts.html +31 -31
- package/coverage/src/notification-reducer.ts.html +1 -1
- package/coverage/src/reducer-backed-store.ts.html +10 -10
- package/coverage/src/runtime/index.html +1 -1
- package/coverage/src/runtime/monitor-ondone-runtime.ts.html +1 -1
- package/coverage/src/runtime/notification-runtime.ts.html +1 -1
- package/coverage/src/runtime/scope.ts.html +1 -1
- package/coverage/src/runtime/session-runtime.ts.html +1 -1
- package/coverage/src/runtime/task-backlog-runtime.ts.html +1 -1
- package/coverage/src/runtime/task-rpc.ts.html +1 -1
- package/coverage/src/scheduler.ts.html +1 -1
- package/coverage/src/store.ts.html +1 -1
- package/coverage/src/task-backlog-coordinator.ts.html +1 -1
- package/coverage/src/task-reducer.ts.html +1 -1
- package/coverage/src/task-store.ts.html +1 -1
- package/coverage/src/tools/index.html +1 -1
- package/coverage/src/tools/loop-tools.ts.html +1 -1
- package/coverage/src/tools/monitor-tools.ts.html +1 -1
- package/coverage/src/tools/native-task-tools.ts.html +1 -1
- package/coverage/src/trigger-system.ts.html +1 -1
- package/coverage/src/ui/index.html +1 -1
- package/coverage/src/ui/widget.ts.html +18 -18
- package/dist/index.js +3 -0
- package/dist/monitor-manager.d.ts +9 -0
- package/dist/monitor-manager.js +33 -12
- package/package.json +1 -1
- package/src/index.ts +3 -0
- package/src/monitor-manager.ts +35 -12
- package/tmp/perf-cap-data/loops.json +0 -455
- package/tmp/perf-cap-data/tasks.json +0 -1
- package/tmp/perf-data/loops-0.json +0 -1
- package/tmp/perf-data/loops-10.json +0 -1
- package/tmp/perf-data/loops-100.json +0 -1
- package/tmp/perf-data/loops-1000.json +0 -1
- package/tmp/perf-data/loops-500.json +0 -1
- package/tmp/perf-data/tasks-0.json +0 -1
- package/tmp/perf-data/tasks-10.json +0 -1
- package/tmp/perf-data/tasks-100.json +0 -1
- package/tmp/perf-data/tasks-1000.json +0 -1
- package/tmp/perf-data/tasks-500.json +0 -1
- package/tmp/perf-data-session/loops-0.json +0 -4
- package/tmp/perf-data-session/loops-100.json +0 -1805
- package/tmp/perf-data-session/loops-1000.json +0 -18005
- package/tmp/perf-data-session/loops-25.json +0 -455
- package/tmp/perf-data-session/loops-500.json +0 -9005
- package/tmp/perf-data-session/tasks-0.json +0 -1
- package/tmp/perf-data-session/tasks-100.json +0 -1
- package/tmp/perf-data-session/tasks-1000.json +0 -1
- package/tmp/perf-data-session/tasks-25.json +0 -1
- package/tmp/perf-data-session/tasks-500.json +0 -1
- package/tmp/perf-session-init.js +0 -98
- package/tmp/perf-startup-audit.js +0 -80
|
@@ -176,7 +176,7 @@
|
|
|
176
176
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
177
177
|
Code coverage generated by
|
|
178
178
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
179
|
-
at 2026-06-
|
|
179
|
+
at 2026-06-18T14:16:07.591Z
|
|
180
180
|
</div>
|
|
181
181
|
<script src="../../prettify.js"></script>
|
|
182
182
|
<script>
|
|
@@ -295,7 +295,7 @@ export function createMonitorOnDoneRuntime(options: MonitorOnDoneRuntimeOptions)
|
|
|
295
295
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
296
296
|
Code coverage generated by
|
|
297
297
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
298
|
-
at 2026-06-
|
|
298
|
+
at 2026-06-18T14:16:07.591Z
|
|
299
299
|
</div>
|
|
300
300
|
<script src="../../prettify.js"></script>
|
|
301
301
|
<script>
|
|
@@ -706,7 +706,7 @@ export function createNotificationRuntime(options: NotificationRuntimeOptions):
|
|
|
706
706
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
707
707
|
Code coverage generated by
|
|
708
708
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
709
|
-
at 2026-06-
|
|
709
|
+
at 2026-06-18T14:16:07.591Z
|
|
710
710
|
</div>
|
|
711
711
|
<script src="../../prettify.js"></script>
|
|
712
712
|
<script>
|
|
@@ -181,7 +181,7 @@ export function resolveTaskStorePath(options: ScopeOptions, sessionId?: string):
|
|
|
181
181
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
182
182
|
Code coverage generated by
|
|
183
183
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
184
|
-
at 2026-06-
|
|
184
|
+
at 2026-06-18T14:16:07.591Z
|
|
185
185
|
</div>
|
|
186
186
|
<script src="../../prettify.js"></script>
|
|
187
187
|
<script>
|
|
@@ -574,7 +574,7 @@ export function registerSessionRuntimeHooks(options: SessionRuntimeOptions): voi
|
|
|
574
574
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
575
575
|
Code coverage generated by
|
|
576
576
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
577
|
-
at 2026-06-
|
|
577
|
+
at 2026-06-18T14:16:07.591Z
|
|
578
578
|
</div>
|
|
579
579
|
<script src="../../prettify.js"></script>
|
|
580
580
|
<script>
|
|
@@ -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-
|
|
562
|
+
at 2026-06-18T14:16:07.591Z
|
|
563
563
|
</div>
|
|
564
564
|
<script src="../../prettify.js"></script>
|
|
565
565
|
<script>
|
|
@@ -520,7 +520,7 @@ export function createTaskRuntimeBridge(options: TaskRuntimeBridgeOptions): Task
|
|
|
520
520
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
521
521
|
Code coverage generated by
|
|
522
522
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
523
|
-
at 2026-06-
|
|
523
|
+
at 2026-06-18T14:16:07.591Z
|
|
524
524
|
</div>
|
|
525
525
|
<script src="../../prettify.js"></script>
|
|
526
526
|
<script>
|
|
@@ -385,7 +385,7 @@ export class CronScheduler {
|
|
|
385
385
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
386
386
|
Code coverage generated by
|
|
387
387
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
388
|
-
at 2026-06-
|
|
388
|
+
at 2026-06-18T14:16:07.591Z
|
|
389
389
|
</div>
|
|
390
390
|
<script src="../prettify.js"></script>
|
|
391
391
|
<script>
|
|
@@ -652,7 +652,7 @@ export class LoopStore extends ReducerBackedStore<LoopEntry, LoopReducerState
|
|
|
652
652
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
653
653
|
Code coverage generated by
|
|
654
654
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
655
|
-
at 2026-06-
|
|
655
|
+
at 2026-06-18T14:16:07.591Z
|
|
656
656
|
</div>
|
|
657
657
|
<script src="../prettify.js"></script>
|
|
658
658
|
<script>
|
|
@@ -166,7 +166,7 @@ export function reduceTaskBacklogEvent(event: TaskBacklogEvent): TaskBacklogEffe
|
|
|
166
166
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
167
167
|
Code coverage generated by
|
|
168
168
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
169
|
-
at 2026-06-
|
|
169
|
+
at 2026-06-18T14:16:07.591Z
|
|
170
170
|
</div>
|
|
171
171
|
<script src="../prettify.js"></script>
|
|
172
172
|
<script>
|
|
@@ -535,7 +535,7 @@ export function reduceTaskState(state: TaskReducerState, event: TaskReducerEvent
|
|
|
535
535
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
536
536
|
Code coverage generated by
|
|
537
537
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
538
|
-
at 2026-06-
|
|
538
|
+
at 2026-06-18T14:16:07.591Z
|
|
539
539
|
</div>
|
|
540
540
|
<script src="../prettify.js"></script>
|
|
541
541
|
<script>
|
|
@@ -511,7 +511,7 @@ export class TaskStore extends ReducerBackedStore<TaskEntry, TaskReducerState
|
|
|
511
511
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
512
512
|
Code coverage generated by
|
|
513
513
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
514
|
-
at 2026-06-
|
|
514
|
+
at 2026-06-18T14:16:07.591Z
|
|
515
515
|
</div>
|
|
516
516
|
<script src="../prettify.js"></script>
|
|
517
517
|
<script>
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
132
132
|
Code coverage generated by
|
|
133
133
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
134
|
-
at 2026-06-
|
|
134
|
+
at 2026-06-18T14:16:07.591Z
|
|
135
135
|
</div>
|
|
136
136
|
<script src="../../prettify.js"></script>
|
|
137
137
|
<script>
|
|
@@ -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-
|
|
988
|
+
at 2026-06-18T14:16:07.591Z
|
|
989
989
|
</div>
|
|
990
990
|
<script src="../../prettify.js"></script>
|
|
991
991
|
<script>
|
|
@@ -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-
|
|
535
|
+
at 2026-06-18T14:16:07.591Z
|
|
536
536
|
</div>
|
|
537
537
|
<script src="../../prettify.js"></script>
|
|
538
538
|
<script>
|
|
@@ -520,7 +520,7 @@ Parameters: id (required), status, subject, description`,
|
|
|
520
520
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
521
521
|
Code coverage generated by
|
|
522
522
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
523
|
-
at 2026-06-
|
|
523
|
+
at 2026-06-18T14:16:07.591Z
|
|
524
524
|
</div>
|
|
525
525
|
<script src="../../prettify.js"></script>
|
|
526
526
|
<script>
|
|
@@ -532,7 +532,7 @@ export class TriggerSystem {
|
|
|
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-
|
|
535
|
+
at 2026-06-18T14:16:07.591Z
|
|
536
536
|
</div>
|
|
537
537
|
<script src="../prettify.js"></script>
|
|
538
538
|
<script>
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
102
102
|
Code coverage generated by
|
|
103
103
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
104
|
-
at 2026-06-
|
|
104
|
+
at 2026-06-18T14:16:07.591Z
|
|
105
105
|
</div>
|
|
106
106
|
<script src="../../prettify.js"></script>
|
|
107
107
|
<script>
|
|
@@ -164,27 +164,27 @@
|
|
|
164
164
|
<span class="cline-any cline-neutral"> </span>
|
|
165
165
|
<span class="cline-any cline-neutral"> </span>
|
|
166
166
|
<span class="cline-any cline-neutral"> </span>
|
|
167
|
-
<span class="cline-any cline-yes">
|
|
168
|
-
<span class="cline-any cline-yes">
|
|
167
|
+
<span class="cline-any cline-yes">189x</span>
|
|
168
|
+
<span class="cline-any cline-yes">161x</span>
|
|
169
169
|
<span class="cline-any cline-neutral"> </span>
|
|
170
170
|
<span class="cline-any cline-neutral"> </span>
|
|
171
171
|
<span class="cline-any cline-neutral"> </span>
|
|
172
|
-
<span class="cline-any cline-yes">
|
|
173
|
-
<span class="cline-any cline-yes">
|
|
174
|
-
<span class="cline-any cline-yes">
|
|
172
|
+
<span class="cline-any cline-yes">161x</span>
|
|
173
|
+
<span class="cline-any cline-yes">161x</span>
|
|
174
|
+
<span class="cline-any cline-yes">161x</span>
|
|
175
175
|
<span class="cline-any cline-neutral"> </span>
|
|
176
|
-
<span class="cline-any cline-yes">
|
|
176
|
+
<span class="cline-any cline-yes">161x</span>
|
|
177
177
|
<span class="cline-any cline-yes">66x</span>
|
|
178
178
|
<span class="cline-any cline-neutral"> </span>
|
|
179
179
|
<span class="cline-any cline-neutral"> </span>
|
|
180
|
-
<span class="cline-any cline-yes">
|
|
181
|
-
<span class="cline-any cline-yes">
|
|
182
|
-
<span class="cline-any cline-yes">
|
|
183
|
-
<span class="cline-any cline-yes">
|
|
180
|
+
<span class="cline-any cline-yes">95x</span>
|
|
181
|
+
<span class="cline-any cline-yes">95x</span>
|
|
182
|
+
<span class="cline-any cline-yes">95x</span>
|
|
183
|
+
<span class="cline-any cline-yes">95x</span>
|
|
184
184
|
<span class="cline-any cline-neutral"> </span>
|
|
185
|
-
<span class="cline-any cline-yes">
|
|
186
|
-
<span class="cline-any cline-yes">
|
|
187
|
-
<span class="cline-any cline-yes">
|
|
185
|
+
<span class="cline-any cline-yes">95x</span>
|
|
186
|
+
<span class="cline-any cline-yes">95x</span>
|
|
187
|
+
<span class="cline-any cline-yes">95x</span>
|
|
188
188
|
<span class="cline-any cline-neutral"> </span>
|
|
189
189
|
<span class="cline-any cline-neutral"> </span>
|
|
190
190
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -193,13 +193,13 @@
|
|
|
193
193
|
<span class="cline-any cline-neutral"> </span>
|
|
194
194
|
<span class="cline-any cline-neutral"> </span>
|
|
195
195
|
<span class="cline-any cline-neutral"> </span>
|
|
196
|
-
<span class="cline-any cline-yes">
|
|
196
|
+
<span class="cline-any cline-yes">119x</span>
|
|
197
197
|
<span class="cline-any cline-neutral"> </span>
|
|
198
198
|
<span class="cline-any cline-neutral"> </span>
|
|
199
199
|
<span class="cline-any cline-neutral"> </span>
|
|
200
|
-
<span class="cline-any cline-yes">
|
|
201
|
-
<span class="cline-any cline-yes">
|
|
202
|
-
<span class="cline-any cline-yes">
|
|
200
|
+
<span class="cline-any cline-yes">44x</span>
|
|
201
|
+
<span class="cline-any cline-yes">43x</span>
|
|
202
|
+
<span class="cline-any cline-yes">6x</span>
|
|
203
203
|
<span class="cline-any cline-neutral"> </span>
|
|
204
204
|
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import type { ExtensionUIContext } from "@earendil-works/pi-coding-agent";
|
|
205
205
|
import type { MonitorManager } from "../monitor-manager.js";
|
|
@@ -277,7 +277,7 @@ function isStatusVisibleLoop(loop: LoopEntry): boolean {
|
|
|
277
277
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
278
278
|
Code coverage generated by
|
|
279
279
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
280
|
-
at 2026-06-
|
|
280
|
+
at 2026-06-18T14:16:07.591Z
|
|
281
281
|
</div>
|
|
282
282
|
<script src="../../prettify.js"></script>
|
|
283
283
|
<script>
|
package/dist/index.js
CHANGED
|
@@ -46,6 +46,9 @@ export default function (pi) {
|
|
|
46
46
|
let scheduler;
|
|
47
47
|
let triggerSystem;
|
|
48
48
|
const widget = new LoopWidget(store, monitorManager);
|
|
49
|
+
// Repaint the status bar when a monitor finishes/prunes on its own (no tool
|
|
50
|
+
// call), so stale monitors don't linger in the count between turns.
|
|
51
|
+
monitorManager.setOnChange(() => widget.update());
|
|
49
52
|
widget.setTaskSummaryProvider(() => {
|
|
50
53
|
if (!nativeTaskStore)
|
|
51
54
|
return { count: 0 };
|
|
@@ -4,9 +4,18 @@ export declare class MonitorManager {
|
|
|
4
4
|
private pi;
|
|
5
5
|
private processes;
|
|
6
6
|
private nextId;
|
|
7
|
+
private onChange;
|
|
7
8
|
constructor(pi: ExtensionAPI);
|
|
9
|
+
/**
|
|
10
|
+
* Register a callback fired when a monitor's status changes or it is pruned
|
|
11
|
+
* (e.g. autonomous completion/error/stop/prune with no tool call). Used to
|
|
12
|
+
* repaint the status widget, which otherwise only refreshes on turn
|
|
13
|
+
* boundaries and explicit tool actions. Not fired for output lines.
|
|
14
|
+
*/
|
|
15
|
+
setOnChange(cb: () => void): void;
|
|
8
16
|
private toReducerState;
|
|
9
17
|
private applyReducerEvent;
|
|
18
|
+
private schedulePrune;
|
|
10
19
|
create(command: string, description?: string, timeout?: number): MonitorEntry;
|
|
11
20
|
get(id: string): MonitorEntry | undefined;
|
|
12
21
|
list(): MonitorEntry[];
|
package/dist/monitor-manager.js
CHANGED
|
@@ -4,9 +4,19 @@ export class MonitorManager {
|
|
|
4
4
|
pi;
|
|
5
5
|
processes = new Map();
|
|
6
6
|
nextId = 1;
|
|
7
|
+
onChange;
|
|
7
8
|
constructor(pi) {
|
|
8
9
|
this.pi = pi;
|
|
9
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* Register a callback fired when a monitor's status changes or it is pruned
|
|
13
|
+
* (e.g. autonomous completion/error/stop/prune with no tool call). Used to
|
|
14
|
+
* repaint the status widget, which otherwise only refreshes on turn
|
|
15
|
+
* boundaries and explicit tool actions. Not fired for output lines.
|
|
16
|
+
*/
|
|
17
|
+
setOnChange(cb) {
|
|
18
|
+
this.onChange = cb;
|
|
19
|
+
}
|
|
10
20
|
toReducerState() {
|
|
11
21
|
return {
|
|
12
22
|
nextId: this.nextId,
|
|
@@ -24,8 +34,29 @@ export class MonitorManager {
|
|
|
24
34
|
}
|
|
25
35
|
process.entry = updated;
|
|
26
36
|
}
|
|
37
|
+
// Repaint on status/set transitions, but not on the frequent output-line
|
|
38
|
+
// events (which never change the visible count).
|
|
39
|
+
if (event.type !== "MONITOR_OUTPUT" && event.type !== "MONITOR_ONDONE_REGISTERED") {
|
|
40
|
+
this.onChange?.();
|
|
41
|
+
}
|
|
27
42
|
return result;
|
|
28
43
|
}
|
|
44
|
+
// Remove a finished monitor (completed/errored/stopped) after a brief delay so
|
|
45
|
+
// tool consumers can still read its final state via MonitorList. Shared by
|
|
46
|
+
// finish() and stop() so every terminal status is pruned consistently — a
|
|
47
|
+
// stopped monitor that is never pruned lingers in list() and the widget count.
|
|
48
|
+
schedulePrune(id) {
|
|
49
|
+
setTimeout(() => {
|
|
50
|
+
this.applyReducerEvent({
|
|
51
|
+
type: "MONITOR_PRUNED",
|
|
52
|
+
at: Date.now(),
|
|
53
|
+
source: "system",
|
|
54
|
+
entityType: "monitor",
|
|
55
|
+
entityId: id,
|
|
56
|
+
payload: { id },
|
|
57
|
+
});
|
|
58
|
+
}, 30000);
|
|
59
|
+
}
|
|
29
60
|
create(command, description, timeout = 300000) {
|
|
30
61
|
const now = Date.now();
|
|
31
62
|
const result = reduceMonitorState(this.toReducerState(), {
|
|
@@ -120,18 +151,7 @@ export class MonitorManager {
|
|
|
120
151
|
for (const resolve of bp.waiters)
|
|
121
152
|
resolve();
|
|
122
153
|
bp.waiters = [];
|
|
123
|
-
|
|
124
|
-
// consumers have time to read the final state via MonitorList.
|
|
125
|
-
setTimeout(() => {
|
|
126
|
-
this.applyReducerEvent({
|
|
127
|
-
type: "MONITOR_PRUNED",
|
|
128
|
-
at: Date.now(),
|
|
129
|
-
source: "system",
|
|
130
|
-
entityType: "monitor",
|
|
131
|
-
entityId: id,
|
|
132
|
-
payload: { id },
|
|
133
|
-
});
|
|
134
|
-
}, 30000);
|
|
154
|
+
this.schedulePrune(id);
|
|
135
155
|
};
|
|
136
156
|
child.on("close", (code) => {
|
|
137
157
|
if (bp.entry.status === "running") {
|
|
@@ -197,6 +217,7 @@ export class MonitorManager {
|
|
|
197
217
|
reason: "manual",
|
|
198
218
|
},
|
|
199
219
|
});
|
|
220
|
+
this.schedulePrune(id);
|
|
200
221
|
bp.proc.kill("SIGTERM");
|
|
201
222
|
await new Promise((resolve) => {
|
|
202
223
|
const timer = setTimeout(() => {
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -55,6 +55,9 @@ export default function (pi: ExtensionAPI) {
|
|
|
55
55
|
let scheduler: CronScheduler;
|
|
56
56
|
let triggerSystem: TriggerSystem;
|
|
57
57
|
const widget = new LoopWidget(store, monitorManager);
|
|
58
|
+
// Repaint the status bar when a monitor finishes/prunes on its own (no tool
|
|
59
|
+
// call), so stale monitors don't linger in the count between turns.
|
|
60
|
+
monitorManager.setOnChange(() => widget.update());
|
|
58
61
|
widget.setTaskSummaryProvider(() => {
|
|
59
62
|
if (!nativeTaskStore) return { count: 0 };
|
|
60
63
|
const tasks = nativeTaskStore.list().filter(t => t.status === "pending" || t.status === "in_progress");
|
package/src/monitor-manager.ts
CHANGED
|
@@ -11,9 +11,20 @@ import type { MonitorEntry, MonitorProcess } from "./types.js";
|
|
|
11
11
|
export class MonitorManager {
|
|
12
12
|
private processes = new Map<string, MonitorProcess>();
|
|
13
13
|
private nextId = 1;
|
|
14
|
+
private onChange: (() => void) | undefined;
|
|
14
15
|
|
|
15
16
|
constructor(private pi: ExtensionAPI) {}
|
|
16
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Register a callback fired when a monitor's status changes or it is pruned
|
|
20
|
+
* (e.g. autonomous completion/error/stop/prune with no tool call). Used to
|
|
21
|
+
* repaint the status widget, which otherwise only refreshes on turn
|
|
22
|
+
* boundaries and explicit tool actions. Not fired for output lines.
|
|
23
|
+
*/
|
|
24
|
+
setOnChange(cb: () => void): void {
|
|
25
|
+
this.onChange = cb;
|
|
26
|
+
}
|
|
27
|
+
|
|
17
28
|
private toReducerState(): MonitorReducerState {
|
|
18
29
|
return {
|
|
19
30
|
nextId: this.nextId,
|
|
@@ -34,9 +45,31 @@ export class MonitorManager {
|
|
|
34
45
|
}
|
|
35
46
|
process.entry = updated;
|
|
36
47
|
}
|
|
48
|
+
// Repaint on status/set transitions, but not on the frequent output-line
|
|
49
|
+
// events (which never change the visible count).
|
|
50
|
+
if (event.type !== "MONITOR_OUTPUT" && event.type !== "MONITOR_ONDONE_REGISTERED") {
|
|
51
|
+
this.onChange?.();
|
|
52
|
+
}
|
|
37
53
|
return result;
|
|
38
54
|
}
|
|
39
55
|
|
|
56
|
+
// Remove a finished monitor (completed/errored/stopped) after a brief delay so
|
|
57
|
+
// tool consumers can still read its final state via MonitorList. Shared by
|
|
58
|
+
// finish() and stop() so every terminal status is pruned consistently — a
|
|
59
|
+
// stopped monitor that is never pruned lingers in list() and the widget count.
|
|
60
|
+
private schedulePrune(id: string): void {
|
|
61
|
+
setTimeout(() => {
|
|
62
|
+
this.applyReducerEvent({
|
|
63
|
+
type: "MONITOR_PRUNED",
|
|
64
|
+
at: Date.now(),
|
|
65
|
+
source: "system",
|
|
66
|
+
entityType: "monitor",
|
|
67
|
+
entityId: id,
|
|
68
|
+
payload: { id },
|
|
69
|
+
});
|
|
70
|
+
}, 30000);
|
|
71
|
+
}
|
|
72
|
+
|
|
40
73
|
create(command: string, description?: string, timeout = 300000): MonitorEntry {
|
|
41
74
|
const now = Date.now();
|
|
42
75
|
const result = reduceMonitorState(this.toReducerState(), {
|
|
@@ -132,18 +165,7 @@ export class MonitorManager {
|
|
|
132
165
|
bp.completionCallbacks = [];
|
|
133
166
|
for (const resolve of bp.waiters) resolve();
|
|
134
167
|
bp.waiters = [];
|
|
135
|
-
|
|
136
|
-
// consumers have time to read the final state via MonitorList.
|
|
137
|
-
setTimeout(() => {
|
|
138
|
-
this.applyReducerEvent({
|
|
139
|
-
type: "MONITOR_PRUNED",
|
|
140
|
-
at: Date.now(),
|
|
141
|
-
source: "system",
|
|
142
|
-
entityType: "monitor",
|
|
143
|
-
entityId: id,
|
|
144
|
-
payload: { id },
|
|
145
|
-
});
|
|
146
|
-
}, 30000);
|
|
168
|
+
this.schedulePrune(id);
|
|
147
169
|
};
|
|
148
170
|
|
|
149
171
|
child.on("close", (code) => {
|
|
@@ -214,6 +236,7 @@ export class MonitorManager {
|
|
|
214
236
|
reason: "manual",
|
|
215
237
|
},
|
|
216
238
|
});
|
|
239
|
+
this.schedulePrune(id);
|
|
217
240
|
bp.proc.kill("SIGTERM");
|
|
218
241
|
|
|
219
242
|
await new Promise<void>((resolve) => {
|