feat: add local schedule cache + periodic sync to CalendarScheduler

- New ScheduleCache class: maintains today's full schedule locally
- CalendarBridgeClient.getDaySchedule(): fetch all slots for a date
- Scheduler now runs two intervals:
  - Heartbeat (60s): existing slot execution flow (unchanged)
  - Sync (5min): pulls full day schedule into local cache
- Exposes getScheduleCache() for tools and status reporting

This enables the plugin to detect slots assigned by other agents
between heartbeats and provides a complete local view of the schedule.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
operator
2026-04-18 17:45:32 +00:00
parent 9af8204376
commit 4a66a7cc90
5 changed files with 298 additions and 3 deletions

View File

@@ -169,6 +169,32 @@ export class CalendarBridgeClient {
return this.sendBoolean('POST', url, body);
}
/**
* Fetch the full day schedule for this agent.
*
* Unlike heartbeat() which only returns pending (NOT_STARTED/DEFERRED) slots,
* this returns ALL slots for the given date, enabling the plugin to maintain
* a complete local view of today's schedule.
*
* @param date Date string in YYYY-MM-DD format
* @returns Array of all slots for the day, or null if unreachable
*/
async getDaySchedule(date: string): Promise<CalendarSlotResponse[] | null> {
const url = `${this.baseUrl}/calendar/day?date=${encodeURIComponent(date)}`;
try {
const response = await this.fetchJson<{ slots: CalendarSlotResponse[] }>(url, {
method: 'GET',
headers: {
'X-Agent-ID': this.config.agentId,
'X-Claw-Identifier': this.config.clawIdentifier,
},
});
return response?.slots ?? null;
} catch {
return null;
}
}
// -------------------------------------------------------------------------
// Internal helpers
// -------------------------------------------------------------------------