@trevonistrevon/pi-loop 0.5.6 → 0.5.7

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 (41) hide show
  1. package/coverage/coverage-final.json +23 -23
  2. package/coverage/index.html +18 -18
  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 +1 -1
  12. package/coverage/src/index.ts.html +73 -73
  13. package/coverage/src/loop-parse.ts.html +44 -44
  14. package/coverage/src/loop-reducer.ts.html +22 -22
  15. package/coverage/src/monitor-completion-coordinator.ts.html +1 -1
  16. package/coverage/src/monitor-manager.ts.html +6 -6
  17. package/coverage/src/monitor-reducer.ts.html +1 -1
  18. package/coverage/src/notification-reducer.ts.html +15 -15
  19. package/coverage/src/reducer-backed-store.ts.html +52 -52
  20. package/coverage/src/runtime/index.html +18 -18
  21. package/coverage/src/runtime/monitor-ondone-runtime.ts.html +5 -5
  22. package/coverage/src/runtime/notification-runtime.ts.html +42 -42
  23. package/coverage/src/runtime/scope.ts.html +17 -17
  24. package/coverage/src/runtime/session-runtime.ts.html +133 -49
  25. package/coverage/src/runtime/task-backlog-runtime.ts.html +7 -7
  26. package/coverage/src/runtime/task-rpc.ts.html +10 -10
  27. package/coverage/src/scheduler.ts.html +29 -29
  28. package/coverage/src/store.ts.html +17 -17
  29. package/coverage/src/task-backlog-coordinator.ts.html +1 -1
  30. package/coverage/src/task-reducer.ts.html +1 -1
  31. package/coverage/src/task-store.ts.html +5 -5
  32. package/coverage/src/tools/index.html +1 -1
  33. package/coverage/src/tools/loop-tools.ts.html +24 -24
  34. package/coverage/src/tools/monitor-tools.ts.html +5 -5
  35. package/coverage/src/tools/native-task-tools.ts.html +6 -6
  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/runtime/session-runtime.js +27 -0
  40. package/package.json +1 -1
  41. package/src/runtime/session-runtime.ts +28 -0
@@ -7,6 +7,10 @@ export interface SessionSwitchEvent {
7
7
  reason?: string;
8
8
  }
9
9
 
10
+ // Wall-clock cadence for the idle heartbeat that pumps the scheduler. Cron is
11
+ // minute-granular, so 30s gives sub-minute wake latency while idle.
12
+ const HEARTBEAT_MS = 30_000;
13
+
10
14
  export interface SessionRuntimeOptions {
11
15
  pi: ExtensionAPI;
12
16
  getLoopScope: () => LoopScope;
@@ -48,6 +52,25 @@ export function registerSessionRuntimeHooks(options: SessionRuntimeOptions): voi
48
52
 
49
53
  let storeUpgraded = false;
50
54
  let persistedShown = false;
55
+ let heartbeatTimer: ReturnType<typeof setInterval> | undefined;
56
+
57
+ // The CronScheduler is pump-driven; without this heartbeat it only advances at
58
+ // turn boundaries (turn_start/agent_end), so a loop whose fire time elapses
59
+ // while the agent is idle would never fire and never re-wake the agent. The
60
+ // timer is unref'd so it never keeps a one-shot (`pi -p`) process alive.
61
+ function ensureHeartbeat(): void {
62
+ if (heartbeatTimer) return;
63
+ heartbeatTimer = setInterval(() => {
64
+ void pumpLoops();
65
+ }, HEARTBEAT_MS);
66
+ heartbeatTimer.unref?.();
67
+ }
68
+
69
+ function stopHeartbeat(): void {
70
+ if (!heartbeatTimer) return;
71
+ clearInterval(heartbeatTimer);
72
+ heartbeatTimer = undefined;
73
+ }
51
74
 
52
75
  function upgradeStoreIfNeeded(ctx: ExtensionContext) {
53
76
  if (storeUpgraded) return;
@@ -66,6 +89,7 @@ export function registerSessionRuntimeHooks(options: SessionRuntimeOptions): voi
66
89
  getStore().clearExpired();
67
90
  getStore().expireEventLoops(sessionStartedAt);
68
91
  getTriggerSystem().start();
92
+ ensureHeartbeat();
69
93
  widget.update();
70
94
  }
71
95
  }
@@ -89,6 +113,7 @@ export function registerSessionRuntimeHooks(options: SessionRuntimeOptions): voi
89
113
  setSessionId(ctx.sessionManager.getSessionId());
90
114
  widget.setUICtx(ctx.ui);
91
115
  upgradeStoreIfNeeded(ctx);
116
+ ensureHeartbeat();
92
117
  widget.update();
93
118
  await pumpLoops();
94
119
  });
@@ -97,6 +122,7 @@ export function registerSessionRuntimeHooks(options: SessionRuntimeOptions): voi
97
122
  setLatestCtx(ctx);
98
123
  widget.setUICtx(ctx.ui);
99
124
  upgradeStoreIfNeeded(ctx);
125
+ ensureHeartbeat();
100
126
  showPersistedLoops();
101
127
  widget.update();
102
128
  });
@@ -123,6 +149,7 @@ export function registerSessionRuntimeHooks(options: SessionRuntimeOptions): voi
123
149
  });
124
150
 
125
151
  pi.on("session_shutdown", async () => {
152
+ stopHeartbeat();
126
153
  notificationRuntime.clear("session_shutdown");
127
154
  });
128
155
 
@@ -130,6 +157,7 @@ export function registerSessionRuntimeHooks(options: SessionRuntimeOptions): voi
130
157
  setLatestCtx(ctx);
131
158
  widget.setUICtx(ctx.ui);
132
159
  getTriggerSystem().stop();
160
+ stopHeartbeat();
133
161
  notificationRuntime.clear("session_switch");
134
162
  setSessionId(undefined);
135
163