@trevonistrevon/pi-loop 0.4.9 → 0.4.11
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/README.md +1 -1
- package/dist/index.js +27 -2
- package/dist/monitor-manager.d.ts +1 -0
- package/dist/monitor-manager.js +21 -0
- package/dist/types.d.ts +1 -0
- package/package.json +1 -1
- package/src/index.ts +28 -2
- package/src/monitor-manager.ts +19 -0
- package/src/types.ts +1 -0
package/README.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -403,6 +403,18 @@ export default function (pi) {
|
|
|
403
403
|
showPersistedLoops(isResume);
|
|
404
404
|
widget.update();
|
|
405
405
|
});
|
|
406
|
+
pi.on("tool_execution_end", async (event, ctx) => {
|
|
407
|
+
_latestCtx = ctx;
|
|
408
|
+
widget.setUICtx(ctx.ui);
|
|
409
|
+
if (event?.toolName !== "bash" || event?.isError)
|
|
410
|
+
return;
|
|
411
|
+
const command = event?.args?.command ?? event?.input?.command;
|
|
412
|
+
if (typeof command !== "string")
|
|
413
|
+
return;
|
|
414
|
+
if (!/^\s*git\s+commit\b/i.test(command))
|
|
415
|
+
return;
|
|
416
|
+
await cleanDoneTasks();
|
|
417
|
+
});
|
|
406
418
|
// ── Dynamic loop pump — fires cron/hybrid loops on idle instead of wall-clock timers ──
|
|
407
419
|
async function pumpLoops() {
|
|
408
420
|
const pendingTasks = new Map();
|
|
@@ -571,11 +583,24 @@ Skip this tool when the task is a one-off check (just do it directly) or when th
|
|
|
571
583
|
},
|
|
572
584
|
});
|
|
573
585
|
function handleMonitorDoneLoop(doneLoop, monitorId) {
|
|
574
|
-
|
|
586
|
+
const deliver = () => {
|
|
587
|
+
const current = store.get(doneLoop.id);
|
|
588
|
+
if (!current)
|
|
589
|
+
return;
|
|
590
|
+
debug(`onDone loop #${doneLoop.id} — monitor #${monitorId} completed, delivering directly`);
|
|
591
|
+
onLoopFire(current);
|
|
592
|
+
store.delete(doneLoop.id);
|
|
593
|
+
};
|
|
594
|
+
const registered = monitorManager.onComplete(monitorId, deliver);
|
|
595
|
+
if (registered)
|
|
596
|
+
return;
|
|
575
597
|
const monitor = monitorManager.get(monitorId);
|
|
576
598
|
if (monitor && monitor.status !== "running") {
|
|
599
|
+
if (monitor.status === "completed") {
|
|
600
|
+
deliver();
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
577
603
|
debug(`onDone loop #${doneLoop.id} — monitor #${monitorId} already ${monitor.status}, expiring`);
|
|
578
|
-
triggerSystem.remove(doneLoop.id);
|
|
579
604
|
store.delete(doneLoop.id);
|
|
580
605
|
}
|
|
581
606
|
}
|
package/dist/monitor-manager.js
CHANGED
|
@@ -30,6 +30,7 @@ export class MonitorManager {
|
|
|
30
30
|
proc: child,
|
|
31
31
|
abortController,
|
|
32
32
|
waiters: [],
|
|
33
|
+
completionCallbacks: [],
|
|
33
34
|
};
|
|
34
35
|
child.stdout?.on("data", (data) => {
|
|
35
36
|
const lines = data.toString().split("\n");
|
|
@@ -70,6 +71,11 @@ export class MonitorManager {
|
|
|
70
71
|
exitCode: code,
|
|
71
72
|
outputLines: entry.outputLines,
|
|
72
73
|
});
|
|
74
|
+
if (status === "completed") {
|
|
75
|
+
for (const callback of bp.completionCallbacks)
|
|
76
|
+
callback();
|
|
77
|
+
}
|
|
78
|
+
bp.completionCallbacks = [];
|
|
73
79
|
for (const resolve of bp.waiters)
|
|
74
80
|
resolve();
|
|
75
81
|
bp.waiters = [];
|
|
@@ -90,6 +96,7 @@ export class MonitorManager {
|
|
|
90
96
|
monitorId: id,
|
|
91
97
|
error: err.message,
|
|
92
98
|
});
|
|
99
|
+
bp.completionCallbacks = [];
|
|
93
100
|
for (const resolve of bp.waiters)
|
|
94
101
|
resolve();
|
|
95
102
|
bp.waiters = [];
|
|
@@ -134,11 +141,25 @@ export class MonitorManager {
|
|
|
134
141
|
});
|
|
135
142
|
});
|
|
136
143
|
bp.entry.completedAt = Date.now();
|
|
144
|
+
bp.completionCallbacks = [];
|
|
137
145
|
for (const resolve of bp.waiters)
|
|
138
146
|
resolve();
|
|
139
147
|
bp.waiters = [];
|
|
140
148
|
return true;
|
|
141
149
|
}
|
|
150
|
+
onComplete(id, callback) {
|
|
151
|
+
const bp = this.processes.get(id);
|
|
152
|
+
if (!bp)
|
|
153
|
+
return false;
|
|
154
|
+
if (bp.entry.status === "completed") {
|
|
155
|
+
callback();
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
158
|
+
if (bp.entry.status !== "running")
|
|
159
|
+
return false;
|
|
160
|
+
bp.completionCallbacks.push(callback);
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
142
163
|
getProcess(id) {
|
|
143
164
|
return this.processes.get(id);
|
|
144
165
|
}
|
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -441,6 +441,19 @@ export default function (pi: ExtensionAPI) {
|
|
|
441
441
|
widget.update();
|
|
442
442
|
});
|
|
443
443
|
|
|
444
|
+
pi.on("tool_execution_end", async (event: any, ctx: ExtensionContext) => {
|
|
445
|
+
_latestCtx = ctx;
|
|
446
|
+
widget.setUICtx(ctx.ui);
|
|
447
|
+
|
|
448
|
+
if (event?.toolName !== "bash" || event?.isError) return;
|
|
449
|
+
|
|
450
|
+
const command = event?.args?.command ?? event?.input?.command;
|
|
451
|
+
if (typeof command !== "string") return;
|
|
452
|
+
if (!/^\s*git\s+commit\b/i.test(command)) return;
|
|
453
|
+
|
|
454
|
+
await cleanDoneTasks();
|
|
455
|
+
});
|
|
456
|
+
|
|
444
457
|
// ── Dynamic loop pump — fires cron/hybrid loops on idle instead of wall-clock timers ──
|
|
445
458
|
|
|
446
459
|
async function pumpLoops(): Promise<void> {
|
|
@@ -621,11 +634,24 @@ Skip this tool when the task is a one-off check (just do it directly) or when th
|
|
|
621
634
|
});
|
|
622
635
|
|
|
623
636
|
function handleMonitorDoneLoop(doneLoop: LoopEntry, monitorId: string): void {
|
|
624
|
-
|
|
637
|
+
const deliver = () => {
|
|
638
|
+
const current = store.get(doneLoop.id);
|
|
639
|
+
if (!current) return;
|
|
640
|
+
debug(`onDone loop #${doneLoop.id} — monitor #${monitorId} completed, delivering directly`);
|
|
641
|
+
onLoopFire(current);
|
|
642
|
+
store.delete(doneLoop.id);
|
|
643
|
+
};
|
|
644
|
+
|
|
645
|
+
const registered = monitorManager.onComplete(monitorId, deliver);
|
|
646
|
+
if (registered) return;
|
|
647
|
+
|
|
625
648
|
const monitor = monitorManager.get(monitorId);
|
|
626
649
|
if (monitor && monitor.status !== "running") {
|
|
650
|
+
if (monitor.status === "completed") {
|
|
651
|
+
deliver();
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
627
654
|
debug(`onDone loop #${doneLoop.id} — monitor #${monitorId} already ${monitor.status}, expiring`);
|
|
628
|
-
triggerSystem.remove(doneLoop.id);
|
|
629
655
|
store.delete(doneLoop.id);
|
|
630
656
|
}
|
|
631
657
|
}
|
package/src/monitor-manager.ts
CHANGED
|
@@ -35,6 +35,7 @@ export class MonitorManager {
|
|
|
35
35
|
proc: child,
|
|
36
36
|
abortController,
|
|
37
37
|
waiters: [],
|
|
38
|
+
completionCallbacks: [],
|
|
38
39
|
};
|
|
39
40
|
|
|
40
41
|
child.stdout?.on("data", (data: Buffer) => {
|
|
@@ -74,6 +75,10 @@ export class MonitorManager {
|
|
|
74
75
|
exitCode: code,
|
|
75
76
|
outputLines: entry.outputLines,
|
|
76
77
|
});
|
|
78
|
+
if (status === "completed") {
|
|
79
|
+
for (const callback of bp.completionCallbacks) callback();
|
|
80
|
+
}
|
|
81
|
+
bp.completionCallbacks = [];
|
|
77
82
|
for (const resolve of bp.waiters) resolve();
|
|
78
83
|
bp.waiters = [];
|
|
79
84
|
// Remove completed/errored monitors after a brief delay so tool
|
|
@@ -95,6 +100,7 @@ export class MonitorManager {
|
|
|
95
100
|
monitorId: id,
|
|
96
101
|
error: err.message,
|
|
97
102
|
});
|
|
103
|
+
bp.completionCallbacks = [];
|
|
98
104
|
for (const resolve of bp.waiters) resolve();
|
|
99
105
|
bp.waiters = [];
|
|
100
106
|
}
|
|
@@ -143,11 +149,24 @@ export class MonitorManager {
|
|
|
143
149
|
});
|
|
144
150
|
|
|
145
151
|
bp.entry.completedAt = Date.now();
|
|
152
|
+
bp.completionCallbacks = [];
|
|
146
153
|
for (const resolve of bp.waiters) resolve();
|
|
147
154
|
bp.waiters = [];
|
|
148
155
|
return true;
|
|
149
156
|
}
|
|
150
157
|
|
|
158
|
+
onComplete(id: string, callback: () => void): boolean {
|
|
159
|
+
const bp = this.processes.get(id);
|
|
160
|
+
if (!bp) return false;
|
|
161
|
+
if (bp.entry.status === "completed") {
|
|
162
|
+
callback();
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
if (bp.entry.status !== "running") return false;
|
|
166
|
+
bp.completionCallbacks.push(callback);
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
|
|
151
170
|
getProcess(id: string): MonitorProcess | undefined {
|
|
152
171
|
return this.processes.get(id);
|
|
153
172
|
}
|