fix: lift calendarScheduler to module scope (multi-register singleton) #8

Merged
hzhang merged 1 commits from fix/scheduler-module-singleton into main 2026-05-21 09:54:55 +00:00
Contributor

After PR #7 made the multi-agent handle real, dind-t2 still showed Calendar scheduler not running from every harborforge_calendar_* call. The cause: register() runs once per agent (5 agents → 5 HarborForge plugin registered lines per gateway boot) and each creates its own let calendarScheduler binding, but only one of those closures actually runs startCalendarScheduler(). The other four register the same tool name with their own null-bound copy of calendarScheduler, and the host's router picks one of them most of the time.

Lifts the binding to module scope so all five closures share it; makes startCalendarScheduler() early-return when already initialised so duplicate gateway_start calls don't double-install intervals. Bumps to 0.3.3.

🤖 Generated with Claude Code

After PR #7 made the multi-agent handle real, dind-t2 still showed `Calendar scheduler not running` from every `harborforge_calendar_*` call. The cause: `register()` runs once per agent (5 agents → 5 `HarborForge plugin registered` lines per gateway boot) and each creates its own `let calendarScheduler` binding, but only one of those closures actually runs `startCalendarScheduler()`. The other four register the same tool name with their own null-bound copy of `calendarScheduler`, and the host's router picks one of them most of the time. Lifts the binding to module scope so all five closures share it; makes `startCalendarScheduler()` early-return when already initialised so duplicate `gateway_start` calls don't double-install intervals. Bumps to 0.3.3. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
hzhang added 1 commit 2026-05-21 09:54:50 +00:00
Trying the prior multi-agent-handle fix in dind-t2 surfaced a second bug
that PR #7 didn't reach: `harborforge_calendar_status` still returned
`Calendar scheduler not running` even though the gateway log showed the
scheduler had started 30+ seconds before the agent's call.

## Root cause

`register()` is invoked once per agent — `grep -c "HarborForge plugin
registered" /tmp/gw-stdout.log` reports 5 for a 5-agent claw. Every
invocation creates its own `let calendarScheduler` closure binding. But
`gateway_start` fires once and we only call `startCalendarScheduler()`
through that single hook, so exactly one of the five closures sees the
handle and the other four keep their bindings at `null`.

The host's tool router picks one of the five duplicate
`harborforge_calendar_status` registrations to dispatch to — most of the
time it's one of the four "null" closures, which is why every wakeup the
agent saw `Calendar scheduler not running`.

## Fix

Lift `let calendarScheduler` out of `register()` and into module scope.
All five register-call closures now reference the same binding; once the
single `gateway_start` initialises it, every tool sees it.

`startCalendarScheduler()` now early-returns when `calendarScheduler` is
already set, so duplicate `gateway_start` firings (if the host ever does
that) don't double-install intervals.

Bumps version 0.3.2 → 0.3.3.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hzhang merged commit 065b0d3da3 into main 2026-05-21 09:54:55 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: zhi/HarborForge.OpenclawPlugin#8