fix(heartbeat): add startedAt param, null prompt handling, timestamp updates

- Fix: Pass startedAt into resolveHeartbeatRunPrompt
- Fix: Return proper object instead of null for no-tasks-due
- Fix: Add early return when prompt is null
- Fix: Persist timestamps on successful exits
This commit is contained in:
Chinar Amrutkar
2026-04-03 23:56:20 +00:00
committed by Peter Steinberger
parent ba09426707
commit 5fffdc478e

View File

@@ -496,7 +496,7 @@ async function resolveHeartbeatPreflight(params: {
}
type HeartbeatPromptResolution = {
prompt: string;
prompt: string | null;
hasExecCompletion: boolean;
hasCronEvents: boolean;
};
@@ -519,6 +519,7 @@ function resolveHeartbeatRunPrompt(params: {
preflight: HeartbeatPreflight;
canRelayToUser: boolean;
workspaceDir: string;
startedAt: number;
}): HeartbeatPromptResolution {
const pendingEventEntries = params.preflight.pendingEventEntries;
const pendingEvents = params.preflight.shouldInspectPendingEvents
@@ -555,7 +556,7 @@ After completing all due tasks, reply HEARTBEAT_OK.`;
return { prompt, hasExecCompletion: false, hasCronEvents: false };
}
// No tasks due - skip this heartbeat to avoid wasteful API calls
return null;
return { prompt: null, hasExecCompletion: false, hasCronEvents: false };
}
// Fallback to original behavior
@@ -694,8 +695,14 @@ export async function runHeartbeatOnce(opts: {
preflight,
canRelayToUser,
workspaceDir,
startedAt,
});
// If no tasks are due, skip heartbeat entirely
if (prompt === null) {
return { status: "skipped", reason: "no-tasks-due" };
}
// Track if heartbeat completed successfully (for updating task timestamps)
let heartbeatSuccess = false;
@@ -834,6 +841,8 @@ export async function runHeartbeatOnce(opts: {
silent: !okSent,
indicatorType: visibility.useIndicator ? resolveIndicatorType("ok-empty") : undefined,
});
heartbeatSuccess = true;
await updateTaskTimestamps();
return { status: "ran", durationMs: Date.now() - startedAt };
}