PLG-CAL-004: Implement ScheduledGatewayRestart handling in plugin

- Add state persistence (persistState/restoreState) for recovery after restart
- Add handleScheduledGatewayRestart method that:
  - Persists current scheduler state to disk
  - Sends final heartbeat to backend before shutdown
  - Stops the calendar scheduler (pauses scheduled tasks)
- Add isRestartPending flag to prevent new slot processing during restart
- Add isScheduledGatewayRestart helper to detect restart events
- Update scheduler to detect and handle ScheduledGatewayRestart events
- Add new tools: harborforge_restart_status, harborforge_calendar_pause/resume
- Export isRestartPending and getStateFilePath methods
- Bump plugin version to 0.3.1
This commit is contained in:
zhi
2026-04-01 09:41:02 +00:00
parent 24c4a7ad14
commit 3b0ea0ad12
6 changed files with 578 additions and 19 deletions

View File

@@ -2,6 +2,7 @@
* HarborForge Calendar Scheduler
*
* PLG-CAL-002: Plugin-side handling for pending slot execution.
* PLG-CAL-004: ScheduledGatewayRestart event handling with state persistence.
*
* Responsibilities:
* - Run calendar heartbeat every minute
@@ -9,6 +10,8 @@
* - Wake agent with task context
* - Handle slot status transitions (attended, ongoing, deferred)
* - Manage agent status transitions (idle → busy/on_call)
* - Persist state on ScheduledGatewayRestart and restore on startup
* - Send final heartbeat before graceful shutdown
*
* Design reference: NEXT_WAVE_DEV_DIRECTION.md §6 (Agent wakeup mechanism)
*/
@@ -32,6 +35,8 @@ export interface CalendarSchedulerConfig {
heartbeatIntervalMs?: number;
/** Enable verbose debug logging */
debug?: boolean;
/** Directory for state persistence (default: plugin data dir) */
stateDir?: string;
}
/**
* Context passed to agent when waking for slot execution.
@@ -63,6 +68,8 @@ interface SchedulerState {
deferredSlotIds: Set<string>;
/** Whether agent is currently processing a slot */
isProcessing: boolean;
/** Whether a gateway restart is scheduled/pending */
isRestartPending: boolean;
}
/**
* CalendarScheduler manages the periodic heartbeat and slot execution lifecycle.
@@ -70,7 +77,33 @@ interface SchedulerState {
export declare class CalendarScheduler {
private config;
private state;
private stateFilePath;
constructor(config: CalendarSchedulerConfig);
/**
* Get default state directory (plugin data directory or temp fallback).
*/
private getDefaultStateDir;
/**
* Persist current state to disk for recovery after restart.
*/
private persistState;
/**
* Restore state from disk if available.
*/
private restoreState;
/**
* Clear persisted state file after successful restore.
*/
private clearPersistedState;
/**
* Send a final heartbeat to the backend before shutdown.
*/
private sendFinalHeartbeat;
/**
* Handle ScheduledGatewayRestart event.
* PLG-CAL-004: Persist state, send final heartbeat, pause scheduled tasks.
*/
private handleScheduledGatewayRestart;
/**
* Start the calendar scheduler.
* Begins periodic heartbeat to check for pending slots.
@@ -96,6 +129,10 @@ export declare class CalendarScheduler {
* Select highest priority slot and wake agent.
*/
private handleIdleAgent;
/**
* Check if a slot is a ScheduledGatewayRestart system event.
*/
private isScheduledGatewayRestart;
/**
* Execute a slot by waking the agent.
*/
@@ -181,6 +218,14 @@ export declare class CalendarScheduler {
* Get the current slot being executed (if any).
*/
getCurrentSlot(): CalendarSlotResponse | null;
/**
* Check if a gateway restart is pending.
*/
isRestartPending(): boolean;
/**
* Get the path to the state file.
*/
getStateFilePath(): string;
}
/**
* Factory function to create a CalendarScheduler from plugin context.