fix(plugin): add dispose lifecycle for full teardown on reload
Plugin created managers, hooks, intervals, and process listeners on every load but had no teardown mechanism. On plugin reload, old instances remained alive causing cumulative memory leaks. - Add createPluginDispose() orchestrating shutdown sequence: backgroundManager.shutdown() → skillMcpManager.disconnectAll() → disposeHooks() - Add disposeHooks() aggregator with safe optional chaining - Wire dispose into index.ts to clean previous instance on reload - Make dispose idempotent (safe to call multiple times) Tests: 4 pass, 8 expects
This commit is contained in:
@@ -7,6 +7,7 @@ import { createHooks } from "./create-hooks"
|
||||
import { createManagers } from "./create-managers"
|
||||
import { createTools } from "./create-tools"
|
||||
import { createPluginInterface } from "./plugin-interface"
|
||||
import { createPluginDispose, type PluginDispose } from "./plugin-dispose"
|
||||
|
||||
import { loadPluginConfig } from "./plugin-config"
|
||||
import { createModelCacheState } from "./plugin-state"
|
||||
@@ -14,6 +15,8 @@ import { createFirstMessageVariantGate } from "./shared/first-message-variant"
|
||||
import { injectServerAuthIntoClient, log } from "./shared"
|
||||
import { startTmuxCheck } from "./tools"
|
||||
|
||||
let activePluginDispose: PluginDispose | null = null
|
||||
|
||||
const OhMyOpenCodePlugin: Plugin = async (ctx) => {
|
||||
// Initialize config context for plugin runtime (prevents warnings from hooks)
|
||||
initConfigContext("opencode", null)
|
||||
@@ -23,6 +26,7 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
|
||||
|
||||
injectServerAuthIntoClient(ctx.client)
|
||||
startTmuxCheck()
|
||||
await activePluginDispose?.()
|
||||
|
||||
const pluginConfig = loadPluginConfig(ctx.directory, ctx)
|
||||
const disabledHooks = new Set(pluginConfig.disabled_hooks ?? [])
|
||||
@@ -67,6 +71,12 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
|
||||
availableSkills: toolsResult.availableSkills,
|
||||
})
|
||||
|
||||
const dispose = createPluginDispose({
|
||||
backgroundManager: managers.backgroundManager,
|
||||
skillMcpManager: managers.skillMcpManager,
|
||||
disposeHooks: hooks.disposeHooks,
|
||||
})
|
||||
|
||||
const pluginInterface = createPluginInterface({
|
||||
ctx,
|
||||
pluginConfig,
|
||||
@@ -76,6 +86,8 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
|
||||
tools: toolsResult.filteredTools,
|
||||
})
|
||||
|
||||
activePluginDispose = dispose
|
||||
|
||||
return {
|
||||
...pluginInterface,
|
||||
|
||||
|
||||
Reference in New Issue
Block a user