In multi-agent sync mode every harborforge_calendar_* tool was returning
`calendarScheduler.<method> is not a function`. The cause: index.ts replaced
`calendarScheduler` (typed `CalendarScheduler | null`) with a `{ stop() }`
stub right after wiring the runSync/runCheck intervals, so `isRunning()`,
`getCurrentSlot()`, `completeCurrentSlot()`, `abortCurrentSlot()`,
`pauseCurrentSlot()`, `resumeCurrentSlot()`, `getState()`,
`isRestartPending()` and `getStateFilePath()` all blew up at call time.
Replaces the stub with a `MultiAgentSchedulerHandle` that:
- tracks the last slot dispatched per agent (recorded by `wakeAgent`)
- exposes status/complete/abort/pause/resume taking the calling agentId
- resolves the implicit "current slot" via woken-cursor first then a
cache scan over not_started/deferred/ongoing slots
- PATCHes via `bridge.updateSlotAs(agentId, …)` so audit headers reflect
the real caller (bridge constructor agentId is 'unused' in multi-agent)
- mirrors the legacy `isRunning/isProcessing/getState/...` surface so
the single-agent fallback (`CalendarScheduler`) keeps working unchanged
Each calendar tool factory now takes `OpenClawPluginToolContext`, reads
`ctx.agentId`, and dispatches through the handle. Single-agent path
(when `calendarScheduler` is a real `CalendarScheduler`) is preserved
behind `instanceof` checks.
Drops the dead `trackSessionCompletion` poll loop (only definition, no
caller) which referenced the removed `completeCurrentSlot`. Bumps
plugin version 0.2.0 → 0.3.2.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ESM conversion:
- plugin/package.json: add "type": "module".
- plugin/tsconfig.json: switch module/moduleResolution to "nodenext"; bump
target to ES2022.
- All relative imports across plugin/ now carry .js extensions as required
by Node ESM (nodenext module resolution).
- plugin/index.ts: replace `require('./calendar/schedule-cache')` with a
proper top-level import; switch `from 'os'` to `from 'node:os'`.
Plugin SDK convention update:
- Wrap default export with definePluginEntry({ id, name, description,
register }) per the current openclaw plugin authoring contract.
- Modernize plugin/openclaw.plugin.json: drop entry/version, add
activation.onStartup so gateway_start fires for this plugin at boot,
declare contracts.tools listing the five harborforge_* tools.
- Add a local plugin/openclaw-sdk.d.ts with ambient declarations for the
focused subpaths (openclaw/plugin-sdk/plugin-entry,
openclaw/plugin-sdk/core). We deliberately do NOT add openclaw as an
npm devDependency: the installer's `npm install --omit=dev` step trips
over openclaw's own (deeply nested) dependency graph when listed via
file:.../openclaw, and the runtime contract is provided by the gateway
loader anyway.
- The local PluginAPI interface is preserved (broader than the standard
OpenClawPluginApi — it surfaces `version`/`runtime`/`spawn`); the
register function is cast at the definePluginEntry boundary.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1. ScheduleCache: local cache of today's schedule, synced every 5 min
from HF backend via new getDaySchedule() API
2. Wakeup prompts updated to reference daily-routine skill workflows
(task-handson, plan-schedule, slot-complete)
3. Agent wakeup via dispatchInboundMessageWithDispatcher (in-process)
- Same mechanism as Discord plugin
- Creates unique session per slot: agent:{agentId}:hf-calendar:slot-{slotId}
- No WebSocket, CLI, or cron dependency
- Verified working on test environment
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 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
- Add CalendarScheduler class to manage periodic heartbeat and slot execution
- Implement agent wakeup logic when Idle and slots are pending
- Handle slot status transitions (attended, ongoing, deferred)
- Support both real and virtual slot materialization
- Add task context building for different event types (job, system, entertainment)
- Integrate scheduler into main plugin index.ts
- Add new plugin tools: harborforge_calendar_status, complete, abort