feat: add business hours scheduling to heartbeat

- Configurable start/end hours (0-23)
- Timezone support (default: UTC)
- Silent skip outside business hours (no log spam)
- Backward compatible (no schedule = always run)
This commit is contained in:
2026-02-16 11:27:27 +00:00
parent 9a77b433c9
commit b26ed1eb53

View File

@@ -31,6 +31,13 @@ export type HeartbeatConfig = {
enabled: boolean;
intervalSeconds: number;
maxPickupsPerTick: number;
schedule?: {
enabled_hours?: {
start: number; // 0-23
end: number; // 0-23
timezone?: string; // IANA timezone (default: UTC)
};
};
};
type Agent = {
@@ -165,6 +172,26 @@ function hasProjects(workspace: string): boolean {
);
}
/**
* Check if current time is within enabled hours.
*/
function isWithinBusinessHours(config: HeartbeatConfig): boolean {
if (!config.schedule?.enabled_hours) return true;
const { start, end, timezone = "UTC" } = config.schedule.enabled_hours;
// Get current hour in the configured timezone
const now = new Date();
const formatter = new Intl.DateTimeFormat("en-US", {
timeZone: timezone,
hour: "numeric",
hour12: false,
});
const currentHour = parseInt(formatter.format(now), 10);
return currentHour >= start && currentHour < end;
}
/**
* Run one heartbeat tick for all agents.
*/
@@ -174,6 +201,11 @@ async function runHeartbeatTick(
pluginConfig: Record<string, unknown> | undefined,
logger: ServiceContext["logger"],
): Promise<void> {
// Skip tick if outside business hours
if (!isWithinBusinessHours(config)) {
return; // Silent skip - no logging spam
}
try {
const result = await processAllAgents(agents, config, pluginConfig, logger);
logTickResult(result, logger);