fix(hooks): preserve plugin-registered internal hooks when refreshing file hooks#64340
fix(hooks): preserve plugin-registered internal hooks when refreshing file hooks#64340anyran wants to merge 2 commits into
Conversation
… clearInternalHooks() wiping plugin-registered handlers The dreaming startup bug was caused by clearInternalHooks() clearing all registered handlers, including plugin hooks registered during loadOpenClawPlugins(). This function is designed to refresh file-based hooks from ~/.openclaw/hooks/, but it inadvertently wiped plugin hooks that have a different lifecycle. Changes: - Add separate pluginHandlers registry for plugin-registered hooks - registerInternalHook() now accepts source: 'file' | 'plugin' parameter - clearInternalHooks() only clears file hooks, preserving plugin hooks - triggerInternalHook() invokes handlers from both registries - Add clearAllInternalHooks() for tests needing full reset - Add clearPluginInternalHooks() for plugin cleanup This ensures memory-core's gateway:startup hook survives the startup sequence and dreaming cron reconciliation runs correctly.
…est isolation Tests that call clearInternalHooks() now use clearAllInternalHooks() to ensure both file and plugin hooks are cleared between test cases. Also adds new tests to verify plugin hooks survive clearInternalHooks().
Greptile SummaryThis PR fixes a real startup-lifecycle bug: Confidence Score: 5/5Safe to merge; the fix is correct and well-tested across the changed files. The core logic is sound: two separate global-singleton maps, narrowed clearInternalHooks(), correct { source: 'plugin' } wiring in registry.ts, and updated test files. The only finding is a P2 fragility in an untouched file (src/plugins/loader.test.ts) where clearInternalHooks() now has weaker semantics than before — but this is not currently breaking and does not affect the primary fix path. src/plugins/loader.test.ts — two inline clearInternalHooks() calls should ideally become clearAllInternalHooks() to match the rest of the test suite after this PR's semantic change.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bbeef4be33
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| export function clearInternalHooks(): void { | ||
| handlers.clear(); |
There was a problem hiding this comment.
Clear plugin handlers when resetting internal hooks
clearInternalHooks() now leaves pluginHandlers intact, but the gateway can perform multiple activating plugin loads in one process (initial startup load, then reloadDeferredGatewayPlugins when deferred channel plugins are present). In that flow, plugin hooks are registered again without a plugin-hook reset, so events like gateway:startup execute the same plugin handler more than once, duplicating side effects such as startup reconciliation/scheduling work.
Useful? React with 👍 / 👎.
|
Closing this as implemented after Codex review. Current What I checked:
So I’m closing this as already implemented rather than keeping a duplicate issue open. Review notes: reviewed against 11804a484ded; fix evidence: commit 11804a484ded. |
Summary
Fix a bug where
clearInternalHooks()wiped plugin-registered internal hooks during startup.This caused plugin hooks like memory-core's
gateway:startuphandler to disappear before the startup event fired, which prevented managed dreaming cron reconciliation from running automatically.Changes
clearInternalHooks()clear only file hooksclearAllInternalHooks()for testsWhy this fixes dreaming
memory-core registers its dreaming startup reconcile hook through the plugin hook path.
Previously that hook could be cleared during startup before
gateway:startupwas triggered, soMemory Dreaming Promotionwas never auto-reconciled.With this change, plugin hooks survive file-hook refresh and the startup reconcile can run correctly.