fix(plugins): deprecate deactivate hook alias

This commit is contained in:
Vincent Koc
2026-05-16 18:35:00 +08:00
parent 7e4929e004
commit a85cd65775
9 changed files with 68 additions and 7 deletions

View File

@@ -135,6 +135,11 @@ const knownDeprecatedSurfaceMarkers = [
file: "src/plugin-sdk/compat.ts",
marker: "@deprecated Use `openclaw/plugin-sdk/channel-message`.",
},
{
code: "legacy-deactivate-hook-alias",
file: "src/plugins/hook-types.ts",
marker: "@deprecated Use gateway_stop",
},
{
code: "channel-route-key-aliases",
file: "src/plugin-sdk/channel-route.ts",

View File

@@ -23,6 +23,22 @@ export const PLUGIN_COMPAT_RECORDS = [
releaseNote:
"Legacy `before_agent_start` hook compatibility remains wired while plugins migrate to modern hook stages.",
},
{
code: "legacy-deactivate-hook-alias",
status: "deprecated",
owner: "sdk",
introduced: "2026-05-16",
deprecated: "2026-05-16",
warningStarts: "2026-05-16",
removeAfter: "2026-08-16",
replacement: "`gateway_stop` hook",
docsPath: "/plugins/hooks#upcoming-deprecations",
surfaces: ["api.on(\"deactivate\", ...)", "plugin typed hook registration"],
diagnostics: ["plugin runtime compatibility warning"],
tests: ["src/plugins/loader.test.ts"],
releaseNote:
"`api.on(\"deactivate\", ...)` remains wired as a deprecated compatibility alias while plugins migrate to `gateway_stop`.",
},
{
code: "hook-only-plugin-shape",
status: "active",

View File

@@ -94,6 +94,7 @@ export type PluginHookName =
| "subagent_delivery_target"
| "subagent_spawned"
| "subagent_ended"
/** @deprecated Use gateway_stop. */
| "deactivate"
| "gateway_start"
| "gateway_stop"
@@ -1003,11 +1004,13 @@ export type PluginHookHandlerMap = {
ctx: PluginHookSubagentContext,
) => Promise<void> | void;
/**
* Compatibility alias for gateway_stop.
* Deprecated compatibility alias for gateway_stop.
*
* New plugins should register gateway_stop directly; the loader normalizes
* deactivate registrations onto gateway_stop so cleanup handlers still run
* during Gateway shutdown.
*
* @deprecated Use gateway_stop.
*/
deactivate: (
event: PluginHookGatewayStopEvent,

View File

@@ -5939,7 +5939,8 @@ module.exports = {
registry.diagnostics.some(
(diag) =>
diag.pluginId === "legacy-deactivate-hook" &&
diag.message === 'typed hook "deactivate" is a compatibility alias for "gateway_stop"',
diag.message ===
'typed hook "deactivate" is deprecated (legacy-deactivate-hook-alias); use "gateway_stop". This compatibility alias will be removed after 2026-08-16.',
),
).toBe(true);
});

View File

@@ -51,6 +51,7 @@ import {
import { buildPluginApi } from "./api-builder.js";
import { normalizeRegisteredChannelPlugin } from "./channel-validation.js";
import { CODEX_APP_SERVER_EXTENSION_RUNTIME_ID } from "./codex-app-server-extension-factory.js";
import { getPluginCompatRecord } from "./compat/registry.js";
import type { CodexAppServerExtensionFactory } from "./codex-app-server-extension-types.js";
import {
isReservedCommandName,
@@ -187,6 +188,16 @@ export type PluginHttpRouteRegistration = RegistryTypesPluginHttpRouteRegistrati
};
const GATEWAY_METHOD_DISPATCH_CONTRACT = "authenticated-request";
const LEGACY_DEACTIVATE_HOOK_ALIAS_COMPAT = getPluginCompatRecord("legacy-deactivate-hook-alias");
function formatLegacyDeactivateHookAliasDiagnostic(): string {
const removeAfter =
LEGACY_DEACTIVATE_HOOK_ALIAS_COMPAT.removeAfter ?? "a future breaking release";
return (
`typed hook "deactivate" is deprecated (${LEGACY_DEACTIVATE_HOOK_ALIAS_COMPAT.code}); ` +
`use "gateway_stop". This compatibility alias will be removed after ${removeAfter}.`
);
}
type PluginOwnedProviderRegistration<T extends { id: string }> = {
pluginId: string;
@@ -2304,7 +2315,7 @@ export function createPluginRegistry(registryParams: PluginRegistryParams) {
level: "warn",
pluginId: record.id,
source: record.source,
message: 'typed hook "deactivate" is a compatibility alias for "gateway_stop"',
message: formatLegacyDeactivateHookAliasDiagnostic(),
});
}
let effectiveHandler = handler;