@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.
- package/coverage/coverage-final.json +27 -27
- package/coverage/index.html +39 -39
- package/coverage/src/commands/index.html +1 -1
- package/coverage/src/commands/loop-command.ts.html +3 -3
- package/coverage/src/commands/tasks-command.ts.html +3 -3
- package/coverage/src/coordinator.ts.html +20 -20
- 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 +33 -33
- package/coverage/src/index.ts.html +71 -71
- package/coverage/src/loop-parse.ts.html +62 -62
- package/coverage/src/loop-reducer.ts.html +28 -28
- package/coverage/src/monitor-completion-coordinator.ts.html +3 -3
- package/coverage/src/monitor-manager.ts.html +76 -70
- package/coverage/src/monitor-reducer.ts.html +28 -28
- package/coverage/src/notification-reducer.ts.html +15 -15
- package/coverage/src/reducer-backed-store.ts.html +54 -54
- package/coverage/src/runtime/index.html +53 -53
- package/coverage/src/runtime/monitor-ondone-runtime.ts.html +39 -39
- package/coverage/src/runtime/notification-runtime.ts.html +42 -42
- package/coverage/src/runtime/scope.ts.html +34 -34
- package/coverage/src/runtime/session-runtime.ts.html +141 -51
- package/coverage/src/runtime/task-backlog-runtime.ts.html +48 -48
- package/coverage/src/runtime/task-rpc.ts.html +81 -81
- package/coverage/src/scheduler.ts.html +41 -41
- package/coverage/src/store.ts.html +26 -26
- package/coverage/src/task-backlog-coordinator.ts.html +8 -8
- package/coverage/src/task-reducer.ts.html +39 -39
- package/coverage/src/task-store.ts.html +55 -55
- package/coverage/src/tools/index.html +43 -43
- package/coverage/src/tools/loop-tools.ts.html +93 -93
- package/coverage/src/tools/monitor-tools.ts.html +53 -53
- package/coverage/src/tools/native-task-tools.ts.html +66 -66
- package/coverage/src/trigger-system.ts.html +11 -11
- package/coverage/src/ui/index.html +1 -1
- package/coverage/src/ui/widget.ts.html +22 -22
- package/dist/commands/tasks-command.js +12 -9
- package/dist/monitor-manager.js +3 -1
- package/dist/runtime/session-runtime.js +29 -0
- package/dist/runtime/task-events.d.ts +15 -0
- package/dist/runtime/task-events.js +13 -0
- package/dist/runtime/task-rpc.js +2 -0
- package/dist/tools/native-task-tools.js +20 -9
- package/package.json +1 -1
- package/src/commands/tasks-command.ts +9 -9
- package/src/monitor-manager.ts +3 -1
- package/src/runtime/session-runtime.ts +30 -0
- package/src/runtime/task-events.ts +41 -0
- package/src/runtime/task-rpc.ts +2 -0
- package/src/tools/native-task-tools.ts +16 -9
- 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">
|
|
26
|
+
<span class="strong">100% </span>
|
|
27
27
|
<span class="quiet">Statements</span>
|
|
28
|
-
<span class='fraction'>
|
|
28
|
+
<span class='fraction'>50/50</span>
|
|
29
29
|
</div>
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
<div class='fl pad1y space-right2'>
|
|
33
|
-
<span class="strong">
|
|
33
|
+
<span class="strong">94.11% </span>
|
|
34
34
|
<span class="quiet">Branches</span>
|
|
35
|
-
<span class='fraction'>
|
|
35
|
+
<span class='fraction'>32/34</span>
|
|
36
36
|
</div>
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
<div class='fl pad1y space-right2'>
|
|
40
|
-
<span class="strong">
|
|
40
|
+
<span class="strong">100% </span>
|
|
41
41
|
<span class="quiet">Functions</span>
|
|
42
|
-
<span class='fraction'>
|
|
42
|
+
<span class='fraction'>6/6</span>
|
|
43
43
|
</div>
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
<div class='fl pad1y space-right2'>
|
|
47
|
-
<span class="strong">
|
|
47
|
+
<span class="strong">100% </span>
|
|
48
48
|
<span class="quiet">Lines</span>
|
|
49
|
-
<span class='fraction'>
|
|
49
|
+
<span class='fraction'>43/43</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
|
|
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>
|
|
@@ -230,13 +230,13 @@
|
|
|
230
230
|
<span class="cline-any cline-neutral"> </span>
|
|
231
231
|
<span class="cline-any cline-neutral"> </span>
|
|
232
232
|
<span class="cline-any cline-neutral"> </span>
|
|
233
|
-
<span class="cline-any cline-yes">
|
|
233
|
+
<span class="cline-any cline-yes">82x</span>
|
|
234
234
|
<span class="cline-any cline-neutral"> </span>
|
|
235
235
|
<span class="cline-any cline-neutral"> </span>
|
|
236
236
|
<span class="cline-any cline-neutral"> </span>
|
|
237
|
-
<span class="cline-any cline-yes">
|
|
237
|
+
<span class="cline-any cline-yes">55x</span>
|
|
238
238
|
<span class="cline-any cline-neutral"> </span>
|
|
239
|
-
<span class="cline-any cline-yes">
|
|
239
|
+
<span class="cline-any cline-yes">55x</span>
|
|
240
240
|
<span class="cline-any cline-neutral"> </span>
|
|
241
241
|
<span class="cline-any cline-neutral"> </span>
|
|
242
242
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -261,49 +261,50 @@
|
|
|
261
261
|
<span class="cline-any cline-neutral"> </span>
|
|
262
262
|
<span class="cline-any cline-neutral"> </span>
|
|
263
263
|
<span class="cline-any cline-neutral"> </span>
|
|
264
|
-
<span class="cline-any cline-yes">
|
|
265
|
-
<span class="cline-any cline-yes">
|
|
264
|
+
<span class="cline-any cline-yes">42x</span>
|
|
265
|
+
<span class="cline-any cline-yes">42x</span>
|
|
266
266
|
<span class="cline-any cline-neutral"> </span>
|
|
267
267
|
<span class="cline-any cline-neutral"> </span>
|
|
268
268
|
<span class="cline-any cline-neutral"> </span>
|
|
269
269
|
<span class="cline-any cline-neutral"> </span>
|
|
270
270
|
<span class="cline-any cline-neutral"> </span>
|
|
271
|
-
<span class="cline-any cline-yes">
|
|
272
|
-
<span class="cline-any cline-yes">
|
|
271
|
+
<span class="cline-any cline-yes">42x</span>
|
|
272
|
+
<span class="cline-any cline-yes">42x</span>
|
|
273
273
|
<span class="cline-any cline-neutral"> </span>
|
|
274
|
-
<span class="cline-any cline-yes">
|
|
274
|
+
<span class="cline-any cline-yes">42x</span>
|
|
275
275
|
<span class="cline-any cline-neutral"> </span>
|
|
276
276
|
<span class="cline-any cline-neutral"> </span>
|
|
277
|
-
<span class="cline-any cline-yes">
|
|
277
|
+
<span class="cline-any cline-yes">42x</span>
|
|
278
278
|
<span class="cline-any cline-neutral"> </span>
|
|
279
279
|
<span class="cline-any cline-neutral"> </span>
|
|
280
280
|
<span class="cline-any cline-neutral"> </span>
|
|
281
|
-
<span class="cline-any cline-yes">
|
|
281
|
+
<span class="cline-any cline-yes">55x</span>
|
|
282
282
|
<span class="cline-any cline-neutral"> </span>
|
|
283
283
|
<span class="cline-any cline-neutral"> </span>
|
|
284
284
|
<span class="cline-any cline-neutral"> </span>
|
|
285
285
|
<span class="cline-any cline-neutral"> </span>
|
|
286
286
|
<span class="cline-any cline-neutral"> </span>
|
|
287
|
-
<span class="cline-any cline-yes">
|
|
288
|
-
<span class="cline-any cline-yes">
|
|
287
|
+
<span class="cline-any cline-yes">7x</span>
|
|
288
|
+
<span class="cline-any cline-yes">7x</span>
|
|
289
289
|
<span class="cline-any cline-neutral"> </span>
|
|
290
|
-
<span class="cline-any cline-yes">
|
|
291
|
-
<span class="cline-any cline-yes">
|
|
290
|
+
<span class="cline-any cline-yes">6x</span>
|
|
291
|
+
<span class="cline-any cline-yes">6x</span>
|
|
292
292
|
<span class="cline-any cline-neutral"> </span>
|
|
293
293
|
<span class="cline-any cline-neutral"> </span>
|
|
294
294
|
<span class="cline-any cline-neutral"> </span>
|
|
295
295
|
<span class="cline-any cline-neutral"> </span>
|
|
296
|
-
<span class="cline-any cline-yes">5x</span>
|
|
297
296
|
<span class="cline-any cline-yes">6x</span>
|
|
297
|
+
<span class="cline-any cline-yes">8x</span>
|
|
298
|
+
<span class="cline-any cline-yes">8x</span>
|
|
299
|
+
<span class="cline-any cline-yes">8x</span>
|
|
300
|
+
<span class="cline-any cline-neutral"> </span>
|
|
298
301
|
<span class="cline-any cline-yes">6x</span>
|
|
299
302
|
<span class="cline-any cline-yes">6x</span>
|
|
300
303
|
<span class="cline-any cline-neutral"> </span>
|
|
301
|
-
<span class="cline-any cline-yes">5x</span>
|
|
302
|
-
<span class="cline-any cline-yes">5x</span>
|
|
303
304
|
<span class="cline-any cline-neutral"> </span>
|
|
304
305
|
<span class="cline-any cline-neutral"> </span>
|
|
306
|
+
<span class="cline-any cline-yes">55x</span>
|
|
305
307
|
<span class="cline-any cline-neutral"> </span>
|
|
306
|
-
<span class="cline-any cline-yes">44x</span>
|
|
307
308
|
<span class="cline-any cline-neutral"> </span>
|
|
308
309
|
<span class="cline-any cline-neutral"> </span>
|
|
309
310
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -321,45 +322,44 @@
|
|
|
321
322
|
<span class="cline-any cline-neutral"> </span>
|
|
322
323
|
<span class="cline-any cline-neutral"> </span>
|
|
323
324
|
<span class="cline-any cline-neutral"> </span>
|
|
325
|
+
<span class="cline-any cline-yes">31x</span>
|
|
326
|
+
<span class="cline-any cline-yes">31x</span>
|
|
327
|
+
<span class="cline-any cline-yes">31x</span>
|
|
324
328
|
<span class="cline-any cline-neutral"> </span>
|
|
325
|
-
<span class="cline-any cline-yes">
|
|
326
|
-
<span class="cline-any cline-yes">
|
|
327
|
-
<span class="cline-any cline-yes">
|
|
329
|
+
<span class="cline-any cline-yes">30x</span>
|
|
330
|
+
<span class="cline-any cline-yes">27x</span>
|
|
331
|
+
<span class="cline-any cline-yes">8x</span>
|
|
328
332
|
<span class="cline-any cline-neutral"> </span>
|
|
329
|
-
<span class="cline-any cline-yes">
|
|
330
|
-
<span class="cline-any cline-yes">
|
|
331
|
-
<span class="cline-any cline-yes">
|
|
333
|
+
<span class="cline-any cline-yes">30x</span>
|
|
334
|
+
<span class="cline-any cline-yes">30x</span>
|
|
335
|
+
<span class="cline-any cline-yes">1x</span>
|
|
332
336
|
<span class="cline-any cline-neutral"> </span>
|
|
333
|
-
<span class="cline-any cline-yes">
|
|
334
|
-
<span class="cline-any cline-yes">
|
|
335
|
-
<span class="cline-any cline-
|
|
337
|
+
<span class="cline-any cline-yes">30x</span>
|
|
338
|
+
<span class="cline-any cline-yes">30x</span>
|
|
339
|
+
<span class="cline-any cline-yes">30x</span>
|
|
340
|
+
<span class="cline-any cline-yes">30x</span>
|
|
341
|
+
<span class="cline-any cline-yes">31x</span>
|
|
336
342
|
<span class="cline-any cline-neutral"> </span>
|
|
337
|
-
<span class="cline-any cline-yes">26x</span>
|
|
338
|
-
<span class="cline-any cline-yes">26x</span>
|
|
339
|
-
<span class="cline-any cline-yes">26x</span>
|
|
340
|
-
<span class="cline-any cline-yes">26x</span>
|
|
341
|
-
<span class="cline-any cline-yes">26x</span>
|
|
342
343
|
<span class="cline-any cline-neutral"> </span>
|
|
344
|
+
<span class="cline-any cline-yes">31x</span>
|
|
343
345
|
<span class="cline-any cline-neutral"> </span>
|
|
344
|
-
<span class="cline-any cline-yes">26x</span>
|
|
345
346
|
<span class="cline-any cline-neutral"> </span>
|
|
346
347
|
<span class="cline-any cline-neutral"> </span>
|
|
348
|
+
<span class="cline-any cline-yes">55x</span>
|
|
347
349
|
<span class="cline-any cline-neutral"> </span>
|
|
348
|
-
<span class="cline-any cline-yes">44x</span>
|
|
349
350
|
<span class="cline-any cline-neutral"> </span>
|
|
350
351
|
<span class="cline-any cline-neutral"> </span>
|
|
351
352
|
<span class="cline-any cline-neutral"> </span>
|
|
352
353
|
<span class="cline-any cline-neutral"> </span>
|
|
353
354
|
<span class="cline-any cline-neutral"> </span>
|
|
354
355
|
<span class="cline-any cline-neutral"> </span>
|
|
356
|
+
<span class="cline-any cline-yes">2x</span>
|
|
357
|
+
<span class="cline-any cline-yes">2x</span>
|
|
358
|
+
<span class="cline-any cline-yes">2x</span>
|
|
359
|
+
<span class="cline-any cline-yes">1x</span>
|
|
360
|
+
<span class="cline-any cline-yes">1x</span>
|
|
355
361
|
<span class="cline-any cline-neutral"> </span>
|
|
356
|
-
<span class="cline-any cline-
|
|
357
|
-
<span class="cline-any cline-no"> </span>
|
|
358
|
-
<span class="cline-any cline-no"> </span>
|
|
359
|
-
<span class="cline-any cline-no"> </span>
|
|
360
|
-
<span class="cline-any cline-no"> </span>
|
|
361
|
-
<span class="cline-any cline-neutral"> </span>
|
|
362
|
-
<span class="cline-any cline-no"> </span>
|
|
362
|
+
<span class="cline-any cline-yes">1x</span>
|
|
363
363
|
<span class="cline-any cline-neutral"> </span>
|
|
364
364
|
<span class="cline-any cline-neutral"> </span>
|
|
365
365
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -435,7 +435,7 @@ Fields:
|
|
|
435
435
|
parameters: Type.Object({}),
|
|
436
436
|
execute() {
|
|
437
437
|
const tasks = taskStore.list();
|
|
438
|
-
|
|
438
|
+
if (tasks.length === 0) return Promise.resolve(textResult("No tasks."));
|
|
439
439
|
|
|
440
440
|
const lines: string[] = [];
|
|
441
441
|
const statuses: Record<"pending" | "in_progress" | "completed", number> = {
|
|
@@ -474,20 +474,20 @@ Parameters: id (required), status, subject, description`,
|
|
|
474
474
|
async execute(_toolCallId, params) {
|
|
475
475
|
const { id, status, subject, description } = params;
|
|
476
476
|
let entry = taskStore.get(id);
|
|
477
|
-
|
|
477
|
+
if (!entry) return Promise.resolve(textResult(`Task #${id} not found`));
|
|
478
478
|
|
|
479
479
|
if (status === "in_progress") entry = taskStore.start(id);
|
|
480
480
|
else if (status === "completed") entry = taskStore.complete(id);
|
|
481
|
-
else
|
|
481
|
+
else if (status === "pending") entry = taskStore.reopen(id);
|
|
482
482
|
|
|
483
|
-
<span class="missing-if-branch" title="if path not taken" >I</span>if (!entry)
|
|
484
|
-
|
|
485
|
-
|
|
483
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (!entry) return Promise.resolve(textResult(`Task #${id} not found`));
|
|
484
|
+
if (subject !== undefined || description !== undefined) {
|
|
485
|
+
entry = taskStore.updateDetails(id, { subject, description });
|
|
486
486
|
}
|
|
487
|
-
<span class="missing-if-branch" title="if path not taken" >I</span>if (!entry)
|
|
487
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (!entry) return Promise.resolve(textResult(`Task #${id} not found`));
|
|
488
488
|
updateWidget();
|
|
489
489
|
const backlog = await evaluateTaskBacklog(taskStore, taskStore.pendingCount());
|
|
490
|
-
const statusMsg = status ? ` → ${status}` :
|
|
490
|
+
const statusMsg = status ? ` → ${status}` : "";
|
|
491
491
|
const autoLoopMsg = backlog.created && backlog.entry
|
|
492
492
|
? `\nBacklog worker loop #${backlog.entry.id} created`
|
|
493
493
|
: "";
|
|
@@ -502,14 +502,14 @@ Parameters: id (required), status, subject, description`,
|
|
|
502
502
|
parameters: Type.Object({
|
|
503
503
|
id: Type.String({ description: "Task ID to delete" }),
|
|
504
504
|
}),
|
|
505
|
-
async
|
|
506
|
-
const deleted =
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
505
|
+
async execute(_toolCallId, params) {
|
|
506
|
+
const deleted = taskStore.delete(params.id);
|
|
507
|
+
updateWidget();
|
|
508
|
+
if (deleted) {
|
|
509
|
+
await evaluateTaskBacklog(taskStore, taskStore.pendingCount());
|
|
510
|
+
return Promise.resolve(textResult(`Task #${params.id} deleted`));
|
|
511
511
|
}
|
|
512
|
-
|
|
512
|
+
return Promise.resolve(textResult(`Task #${params.id} not found`));
|
|
513
513
|
},
|
|
514
514
|
});
|
|
515
515
|
}
|
|
@@ -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-19T00:56:38.236Z
|
|
524
524
|
</div>
|
|
525
525
|
<script src="../../prettify.js"></script>
|
|
526
526
|
<script>
|
|
@@ -224,15 +224,15 @@
|
|
|
224
224
|
<span class="cline-any cline-neutral"> </span>
|
|
225
225
|
<span class="cline-any cline-neutral"> </span>
|
|
226
226
|
<span class="cline-any cline-neutral"> </span>
|
|
227
|
-
<span class="cline-any cline-yes">
|
|
228
|
-
<span class="cline-any cline-yes">
|
|
229
|
-
<span class="cline-any cline-yes">
|
|
227
|
+
<span class="cline-any cline-yes">121x</span>
|
|
228
|
+
<span class="cline-any cline-yes">121x</span>
|
|
229
|
+
<span class="cline-any cline-yes">121x</span>
|
|
230
230
|
<span class="cline-any cline-neutral"> </span>
|
|
231
231
|
<span class="cline-any cline-neutral"> </span>
|
|
232
|
-
<span class="cline-any cline-yes">
|
|
233
|
-
<span class="cline-any cline-yes">
|
|
234
|
-
<span class="cline-any cline-yes">
|
|
235
|
-
<span class="cline-any cline-yes">
|
|
232
|
+
<span class="cline-any cline-yes">121x</span>
|
|
233
|
+
<span class="cline-any cline-yes">121x</span>
|
|
234
|
+
<span class="cline-any cline-yes">121x</span>
|
|
235
|
+
<span class="cline-any cline-yes">121x</span>
|
|
236
236
|
<span class="cline-any cline-neutral"> </span>
|
|
237
237
|
<span class="cline-any cline-neutral"> </span>
|
|
238
238
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -250,10 +250,10 @@
|
|
|
250
250
|
<span class="cline-any cline-neutral"> </span>
|
|
251
251
|
<span class="cline-any cline-neutral"> </span>
|
|
252
252
|
<span class="cline-any cline-neutral"> </span>
|
|
253
|
-
<span class="cline-any cline-yes">
|
|
254
|
-
<span class="cline-any cline-yes">
|
|
253
|
+
<span class="cline-any cline-yes">36x</span>
|
|
254
|
+
<span class="cline-any cline-yes">16x</span>
|
|
255
255
|
<span class="cline-any cline-neutral"> </span>
|
|
256
|
-
<span class="cline-any cline-yes">
|
|
256
|
+
<span class="cline-any cline-yes">36x</span>
|
|
257
257
|
<span class="cline-any cline-yes">29x</span>
|
|
258
258
|
<span class="cline-any cline-yes">29x</span>
|
|
259
259
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -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-19T00:56:38.236Z
|
|
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-19T00:56:38.236Z
|
|
105
105
|
</div>
|
|
106
106
|
<script src="../../prettify.js"></script>
|
|
107
107
|
<script>
|
|
@@ -147,44 +147,44 @@
|
|
|
147
147
|
<span class="cline-any cline-neutral"> </span>
|
|
148
148
|
<span class="cline-any cline-neutral"> </span>
|
|
149
149
|
<span class="cline-any cline-neutral"> </span>
|
|
150
|
-
<span class="cline-any cline-yes">
|
|
151
|
-
<span class="cline-any cline-yes">
|
|
150
|
+
<span class="cline-any cline-yes">68x</span>
|
|
151
|
+
<span class="cline-any cline-yes">68x</span>
|
|
152
152
|
<span class="cline-any cline-neutral"> </span>
|
|
153
153
|
<span class="cline-any cline-neutral"> </span>
|
|
154
154
|
<span class="cline-any cline-neutral"> </span>
|
|
155
|
-
<span class="cline-any cline-yes">
|
|
155
|
+
<span class="cline-any cline-yes">107x</span>
|
|
156
156
|
<span class="cline-any cline-neutral"> </span>
|
|
157
157
|
<span class="cline-any cline-neutral"> </span>
|
|
158
158
|
<span class="cline-any cline-neutral"> </span>
|
|
159
|
-
<span class="cline-any cline-yes">
|
|
159
|
+
<span class="cline-any cline-yes">46x</span>
|
|
160
160
|
<span class="cline-any cline-neutral"> </span>
|
|
161
161
|
<span class="cline-any cline-neutral"> </span>
|
|
162
162
|
<span class="cline-any cline-neutral"> </span>
|
|
163
|
-
<span class="cline-any cline-yes">
|
|
163
|
+
<span class="cline-any cline-yes">63x</span>
|
|
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">192x</span>
|
|
168
|
+
<span class="cline-any cline-yes">164x</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">164x</span>
|
|
173
|
+
<span class="cline-any cline-yes">164x</span>
|
|
174
|
+
<span class="cline-any cline-yes">164x</span>
|
|
175
175
|
<span class="cline-any cline-neutral"> </span>
|
|
176
|
-
<span class="cline-any cline-yes">
|
|
177
|
-
<span class="cline-any cline-yes">
|
|
176
|
+
<span class="cline-any cline-yes">164x</span>
|
|
177
|
+
<span class="cline-any cline-yes">68x</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">96x</span>
|
|
181
|
+
<span class="cline-any cline-yes">96x</span>
|
|
182
|
+
<span class="cline-any cline-yes">96x</span>
|
|
183
|
+
<span class="cline-any cline-yes">96x</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">96x</span>
|
|
186
|
+
<span class="cline-any cline-yes">96x</span>
|
|
187
|
+
<span class="cline-any cline-yes">96x</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,12 +193,12 @@
|
|
|
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">120x</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">45x</span>
|
|
200
201
|
<span class="cline-any cline-yes">44x</span>
|
|
201
|
-
<span class="cline-any cline-yes">43x</span>
|
|
202
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";
|
|
@@ -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-19T00:56:38.236Z
|
|
281
281
|
</div>
|
|
282
282
|
<script src="../../prettify.js"></script>
|
|
283
283
|
<script>
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
+
import { emitNativeTaskEvent } from "../runtime/task-events.js";
|
|
1
2
|
export function registerTasksCommand(options) {
|
|
2
3
|
const { pi, getNativeTaskStore, evaluateTaskBacklog, updateWidget } = options;
|
|
3
4
|
async function emitCreated(entry) {
|
|
4
|
-
pi
|
|
5
|
-
taskId: entry.id,
|
|
6
|
-
subject: entry.subject,
|
|
7
|
-
description: entry.description,
|
|
8
|
-
status: entry.status,
|
|
9
|
-
});
|
|
5
|
+
emitNativeTaskEvent(pi, "tasks:created", entry);
|
|
10
6
|
const taskStore = getNativeTaskStore();
|
|
11
7
|
if (!taskStore)
|
|
12
8
|
return { created: false };
|
|
@@ -75,18 +71,25 @@ export function registerTasksCommand(options) {
|
|
|
75
71
|
return viewNativeTasks(ui);
|
|
76
72
|
if (action === "x Delete") {
|
|
77
73
|
taskStore.delete(task.id);
|
|
74
|
+
emitNativeTaskEvent(pi, "tasks:deleted", task, task.status);
|
|
78
75
|
ui.notify(`Task #${task.id} deleted`, "info");
|
|
79
76
|
}
|
|
80
77
|
else if (action === "> Start") {
|
|
81
|
-
taskStore.start(task.id);
|
|
78
|
+
const next = taskStore.start(task.id);
|
|
79
|
+
if (next)
|
|
80
|
+
emitNativeTaskEvent(pi, "tasks:started", next, task.status);
|
|
82
81
|
ui.notify(`Task #${task.id} started`, "info");
|
|
83
82
|
}
|
|
84
83
|
else if (action === "ok Complete") {
|
|
85
|
-
taskStore.complete(task.id);
|
|
84
|
+
const next = taskStore.complete(task.id);
|
|
85
|
+
if (next)
|
|
86
|
+
emitNativeTaskEvent(pi, "tasks:completed", next, task.status);
|
|
86
87
|
ui.notify(`Task #${task.id} completed`, "info");
|
|
87
88
|
}
|
|
88
89
|
else if (action === "* Return to pending" || action === "* Reopen") {
|
|
89
|
-
taskStore.reopen(task.id);
|
|
90
|
+
const next = taskStore.reopen(task.id);
|
|
91
|
+
if (next)
|
|
92
|
+
emitNativeTaskEvent(pi, "tasks:reopened", next, task.status);
|
|
90
93
|
ui.notify(`Task #${task.id} reopened`, "info");
|
|
91
94
|
}
|
|
92
95
|
updateWidget();
|
package/dist/monitor-manager.js
CHANGED
|
@@ -46,7 +46,8 @@ export class MonitorManager {
|
|
|
46
46
|
// finish() and stop() so every terminal status is pruned consistently — a
|
|
47
47
|
// stopped monitor that is never pruned lingers in list() and the widget count.
|
|
48
48
|
schedulePrune(id) {
|
|
49
|
-
|
|
49
|
+
// unref so a pending prune never keeps a one-shot (`pi -p`) process alive.
|
|
50
|
+
const timer = setTimeout(() => {
|
|
50
51
|
this.applyReducerEvent({
|
|
51
52
|
type: "MONITOR_PRUNED",
|
|
52
53
|
at: Date.now(),
|
|
@@ -56,6 +57,7 @@ export class MonitorManager {
|
|
|
56
57
|
payload: { id },
|
|
57
58
|
});
|
|
58
59
|
}, 30000);
|
|
60
|
+
timer.unref?.();
|
|
59
61
|
}
|
|
60
62
|
create(command, description, timeout = 300000) {
|
|
61
63
|
const now = Date.now();
|
|
@@ -1,7 +1,31 @@
|
|
|
1
|
+
// Wall-clock cadence for the idle heartbeat that pumps the scheduler. Cron is
|
|
2
|
+
// minute-granular, so 30s gives sub-minute wake latency while idle.
|
|
3
|
+
const HEARTBEAT_MS = 30_000;
|
|
1
4
|
export function registerSessionRuntimeHooks(options) {
|
|
2
5
|
const { pi, getLoopScope, getPiLoopEnv, recreateSessionStore, clearAllLoops, getStore, getScheduler, getTriggerSystem, setLatestCtx, setSessionId, widget, notificationRuntime, flushPendingNotifications, cleanupTaskBacklogLoops, hasPendingTasks, cleanDoneTasks, } = options;
|
|
3
6
|
let storeUpgraded = false;
|
|
4
7
|
let persistedShown = false;
|
|
8
|
+
let heartbeatTimer;
|
|
9
|
+
// The CronScheduler is pump-driven; without this heartbeat it only advances at
|
|
10
|
+
// turn boundaries (turn_start/agent_end), so a loop whose fire time elapses
|
|
11
|
+
// while the agent is idle would never fire and never re-wake the agent. The
|
|
12
|
+
// timer is unref'd so it never keeps a one-shot (`pi -p`) process alive.
|
|
13
|
+
function ensureHeartbeat() {
|
|
14
|
+
if (heartbeatTimer)
|
|
15
|
+
return;
|
|
16
|
+
heartbeatTimer = setInterval(() => {
|
|
17
|
+
// Swallow pump failures so a transient error never surfaces as an
|
|
18
|
+
// unhandled rejection; the next tick retries.
|
|
19
|
+
void pumpLoops().catch(() => { });
|
|
20
|
+
}, HEARTBEAT_MS);
|
|
21
|
+
heartbeatTimer.unref?.();
|
|
22
|
+
}
|
|
23
|
+
function stopHeartbeat() {
|
|
24
|
+
if (!heartbeatTimer)
|
|
25
|
+
return;
|
|
26
|
+
clearInterval(heartbeatTimer);
|
|
27
|
+
heartbeatTimer = undefined;
|
|
28
|
+
}
|
|
5
29
|
function upgradeStoreIfNeeded(ctx) {
|
|
6
30
|
if (storeUpgraded)
|
|
7
31
|
return;
|
|
@@ -20,6 +44,7 @@ export function registerSessionRuntimeHooks(options) {
|
|
|
20
44
|
getStore().clearExpired();
|
|
21
45
|
getStore().expireEventLoops(sessionStartedAt);
|
|
22
46
|
getTriggerSystem().start();
|
|
47
|
+
ensureHeartbeat();
|
|
23
48
|
widget.update();
|
|
24
49
|
}
|
|
25
50
|
}
|
|
@@ -46,6 +71,7 @@ export function registerSessionRuntimeHooks(options) {
|
|
|
46
71
|
setSessionId(ctx.sessionManager.getSessionId());
|
|
47
72
|
widget.setUICtx(ctx.ui);
|
|
48
73
|
upgradeStoreIfNeeded(ctx);
|
|
74
|
+
ensureHeartbeat();
|
|
49
75
|
widget.update();
|
|
50
76
|
await pumpLoops();
|
|
51
77
|
});
|
|
@@ -53,6 +79,7 @@ export function registerSessionRuntimeHooks(options) {
|
|
|
53
79
|
setLatestCtx(ctx);
|
|
54
80
|
widget.setUICtx(ctx.ui);
|
|
55
81
|
upgradeStoreIfNeeded(ctx);
|
|
82
|
+
ensureHeartbeat();
|
|
56
83
|
showPersistedLoops();
|
|
57
84
|
widget.update();
|
|
58
85
|
});
|
|
@@ -76,12 +103,14 @@ export function registerSessionRuntimeHooks(options) {
|
|
|
76
103
|
await pumpLoops();
|
|
77
104
|
});
|
|
78
105
|
pi.on("session_shutdown", async () => {
|
|
106
|
+
stopHeartbeat();
|
|
79
107
|
notificationRuntime.clear("session_shutdown");
|
|
80
108
|
});
|
|
81
109
|
pi.on("session_switch", async (event, ctx) => {
|
|
82
110
|
setLatestCtx(ctx);
|
|
83
111
|
widget.setUICtx(ctx.ui);
|
|
84
112
|
getTriggerSystem().stop();
|
|
113
|
+
stopHeartbeat();
|
|
85
114
|
notificationRuntime.clear("session_switch");
|
|
86
115
|
setSessionId(undefined);
|
|
87
116
|
const isResume = event?.reason === "resume";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import type { TaskEntry, TaskStatus } from "../task-types.js";
|
|
3
|
+
export type NativeTaskEventName = "tasks:created" | "tasks:started" | "tasks:completed" | "tasks:reopened" | "tasks:updated" | "tasks:deleted";
|
|
4
|
+
export interface NativeTaskEventPayload {
|
|
5
|
+
taskId: string;
|
|
6
|
+
subject: string;
|
|
7
|
+
description: string;
|
|
8
|
+
status: TaskStatus;
|
|
9
|
+
previousStatus?: TaskStatus;
|
|
10
|
+
createdAt: number;
|
|
11
|
+
updatedAt: number;
|
|
12
|
+
completedAt?: number;
|
|
13
|
+
metadata?: Record<string, unknown>;
|
|
14
|
+
}
|
|
15
|
+
export declare function emitNativeTaskEvent(pi: ExtensionAPI, name: NativeTaskEventName, entry: TaskEntry, previousStatus?: TaskStatus): void;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function emitNativeTaskEvent(pi, name, entry, previousStatus) {
|
|
2
|
+
pi.events.emit(name, {
|
|
3
|
+
taskId: entry.id,
|
|
4
|
+
subject: entry.subject,
|
|
5
|
+
description: entry.description,
|
|
6
|
+
status: entry.status,
|
|
7
|
+
previousStatus,
|
|
8
|
+
createdAt: entry.createdAt,
|
|
9
|
+
updatedAt: entry.updatedAt,
|
|
10
|
+
completedAt: entry.completedAt,
|
|
11
|
+
metadata: entry.metadata,
|
|
12
|
+
});
|
|
13
|
+
}
|
package/dist/runtime/task-rpc.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { emitNativeTaskEvent } from "./task-events.js";
|
|
2
3
|
export function createTaskRuntimeBridge(options) {
|
|
3
4
|
const { pi, isTasksAvailable, setTasksAvailable, getNativeTaskStore, onNativeTaskCreated, onNativeTasksPruned, debug, } = options;
|
|
4
5
|
function checkTasksVersion() {
|
|
@@ -52,6 +53,7 @@ export function createTaskRuntimeBridge(options) {
|
|
|
52
53
|
if (!nativeTaskStore)
|
|
53
54
|
return undefined;
|
|
54
55
|
const task = nativeTaskStore.create(entry.prompt.slice(0, 80), `Auto-created from loop #${entry.id}`, { loopId: entry.id, trigger: entry.trigger });
|
|
56
|
+
emitNativeTaskEvent(pi, "tasks:created", task);
|
|
55
57
|
onNativeTaskCreated?.(nativeTaskStore);
|
|
56
58
|
return task.id;
|
|
57
59
|
}
|