development: absorbed openclaw-plugin-dev as a workflow, with reference docs for plugin structure, hooks, tools, state, config. hf-hangman-lab: hf-wakeup workflow — full agent wakeup lifecycle: set busy → check due slots → select & defer → identify task → plan work → create work channel → execute. All branches end with status reset to idle. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1.3 KiB
1.3 KiB
Plugin Entry Point
Format
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
const _G = globalThis as Record<string, unknown>;
const LIFECYCLE_KEY = "_myPluginGatewayLifecycleRegistered";
export default {
id: "my-plugin",
name: "My Plugin",
register(api: OpenClawPluginApi) {
const config = normalizeConfig(api);
// Gateway lifecycle: only once
if (!_G[LIFECYCLE_KEY]) {
_G[LIFECYCLE_KEY] = true;
// Start sidecars, init global resources
api.on("gateway_stop", () => { _G[LIFECYCLE_KEY] = false; });
}
// Agent session hooks: every register() call (dedup inside handler)
registerMyHook(api, config);
// Tools
registerMyTools(api, config);
api.logger.info("my-plugin: registered");
},
};
Why globalThis?
OpenClaw may hot-reload plugins. Module-level variables reset on reload, but globalThis persists. All mutable state must be on globalThis:
- Startup flags → prevent double initialization
- Dedup sets → prevent double hook execution
- Runtime references → keep connections alive across reloads
- Shared registries → preserve cross-plugin state
Naming Convention
_<pluginId>PluginXxx # Internal state (e.g., _prismFacetRouters)
__<pluginId> # Cross-plugin public API (e.g., __yonexusClient)