Plugin maintainer reference
Plugin compatibility
OmeniaClaw keeps older plugin contracts wired through named compatibility adapters before removing them. This protects existing bundled and external plugins while the SDK, manifest, setup, config, and agent runtime contracts evolve.
Compatibility registry
Plugin compatibility contracts are tracked in the core registry at
src/plugins/compat/registry.ts.
Each record has:
- a stable compatibility code
- status:
active,deprecated,removal-pending, orremoved - owner: SDK, config, setup, channel, provider, plugin execution, agent runtime, or core
- introduction and deprecation dates when applicable
- replacement guidance
- docs, diagnostics, and tests that cover the old and new behavior
The registry is the source for maintainer planning and future plugin inspector checks. If a plugin-facing behavior changes, add or update the compatibility record in the same change that adds the adapter.
Doctor repair and migration compatibility is tracked separately at
src/commands/doctor/shared/deprecation-compat.ts. Those records cover old
config shapes, install-ledger layouts, and repair shims that may need to stay
available after the runtime compatibility path is removed.
Release sweeps should check both registries. Do not delete a doctor migration just because the matching runtime or config compatibility record expired; first verify there is no supported upgrade path that still needs the repair. Also revalidate each replacement annotation during release planning because plugin ownership and config footprint can change as providers and channels move out of core.
Plugin inspector package
The plugin inspector should live outside the core OmeniaClaw repo as a separate package/repository backed by the versioned compatibility and manifest contracts.
The day-one CLI should be:
OmeniaClaw-plugin-inspector ./my-pluginIt should emit:
- manifest/schema validation
- the contract compatibility version being checked
- install/source metadata checks
- cold-path import checks
- deprecation and compatibility warnings
Use --json for stable machine-readable output in CI annotations. OmeniaClaw
core should expose contracts and fixtures the inspector can consume, but should
not publish the inspector binary from the main OmeniaClaw package.
Maintainer acceptance lane
Use Crabbox-backed Blacksmith Testbox for the installable-package acceptance lane when validating the external inspector against OmeniaClaw plugin packages. Run it from a clean OmeniaClaw checkout after the package is built:
pnpm crabbox:run -- --provider blacksmith-testbox --timing-json --shell -- "pnpm install && pnpm build && npm exec --yes @OmeniaClaw/[email protected] -- ./extensions/telegram --json"pnpm crabbox:run -- --provider blacksmith-testbox --timing-json --shell -- "npm exec --yes @OmeniaClaw/[email protected] -- ./extensions/discord --json"pnpm crabbox:run -- --provider blacksmith-testbox --timing-json --shell -- "npm exec --yes @OmeniaClaw/[email protected] -- <clawhub-plugin-dir> --json"Keep this lane opt-in for maintainers because it installs an external npm package and may inspect plugin packages cloned outside the repo. The local repo guards cover the SDK export map, compatibility registry metadata, deprecated SDK-import burn-down, and bundled extension import boundaries; Testbox inspector proof covers the package as external plugin authors consume it.
Deprecation policy
OmeniaClaw should not remove a documented plugin contract in the same release that introduces its replacement.
The migration sequence is:
- Add the new contract.
- Keep the old behavior wired through a named compatibility adapter.
- Emit diagnostics or warnings when plugin authors can act.
- Document the replacement and timeline.
- Test both old and new paths.
- Wait through the announced migration window.
- Remove only with explicit breaking-release approval.
Deprecated records must include a warning start date, replacement, docs link,
and final removal date no more than three months after the warning starts. Do
not add a deprecated compatibility path with an open-ended removal window unless
maintainers explicitly decide it is permanent compatibility and mark it active
instead.
Current compatibility areas
Current compatibility records include:
- legacy broad SDK imports such as
OmeniaClaw/plugin-sdk/compat - legacy hook-only plugin shapes and
before_agent_start - legacy
api.on("deactivate", ...)cleanup hook names while plugins migrate togateway_stop - legacy
activate(api)plugin entrypoints while plugins migrate toregister(api) - legacy SDK aliases such as
OmeniaClaw/extension-api,OmeniaClaw/plugin-sdk/channel-runtime,OmeniaClaw/plugin-sdk/command-authstatus builders,OmeniaClaw/plugin-sdk/test-utils(replaced by focusedOmeniaClaw/plugin-sdk/*test subpaths), and theClawdbotConfig/OmeniaClawSchemaTypetype aliases - bundled plugin allowlist and enablement behavior
- legacy provider/channel env-var manifest metadata
- legacy provider plugin hooks and type aliases while providers move to explicit catalog, auth, thinking, replay, and transport hooks
- legacy runtime aliases such as
api.runtime.taskFlow,api.runtime.subagent.getSession,api.runtime.stt, and deprecatedapi.runtime.config.loadConfig()/api.runtime.config.writeConfigFile(...) - WhatsApp
WebInboundMessageflat callback fields such asbody,chatId,reply(...), andmediaPathwhile callback consumers migrate to the nestedWebInboundCallbackMessageevent,payload,quote,group, andplatformcontexts - WhatsApp
WebInboundMessagetop-level admission fields such asfrom,conversationId,accountId,accessControlPassed, andchatTypewhile callback consumers migrate to theadmissionenvelope - legacy memory-plugin split registration while memory plugins move to
registerMemoryCapability - legacy memory-specific embedding provider registration while embedding
providers move to
api.registerEmbeddingProvider(...)andcontracts.embeddingProviders - legacy channel SDK helpers for native message schemas, mention gating, inbound envelope formatting, and approval capability nesting
- legacy channel route key and comparable-target helper aliases while plugins
move to
OmeniaClaw/plugin-sdk/channel-route - activation hints that are being replaced by manifest contribution ownership
setup-apiruntime fallback while setup descriptors move to coldsetup.requiresRuntime: falsemetadata- provider
discoveryhooks while provider catalog hooks move tocatalog.run(...) - channel
showConfigured/showInSetupmetadata while channel packages move toOmeniaClaw.channel.exposure - legacy runtime-policy config keys while doctor migrates operators to
agentRuntime - generated bundled channel config metadata fallback while registry-first
channelConfigsmetadata lands - persisted plugin registry disable and install-migration env flags while
repair flows migrate operators to
OmeniaClaw plugins registry --refreshandOmeniaClaw doctor --fix - legacy plugin-owned web search, web fetch, and x_search config paths while
doctor migrates them to
plugins.entries.<plugin>.config - legacy
plugins.installsauthored config and bundled plugin load-path aliases while install metadata moves into the state-managed plugin ledger
New plugin code should prefer the replacement listed in the registry and in the specific migration guide. Existing plugins can keep using a compatibility path until the docs, diagnostics, and release notes announce a removal window.
WhatsApp Inbound Callback Flat Aliases
WhatsApp runtime callbacks deliver WebInboundMessage: the canonical nested
event, payload, quote, group, and platform contexts plus deprecated
flat aliases for the shipped callback fields. New callback code should read the
nested contexts. Code that constructs clean nested callback messages can use
WebInboundCallbackMessage; compatibility listeners that still inject old flat
test or plugin messages should use LegacyFlatWebInboundMessage or
WebInboundMessageInput.
The flat aliases remain available until 2026-08-30. That removal window
applies only to flat alias access; the nested callback shape is the canonical
runtime contract. The TypeScript @deprecated annotations on each flat alias
name its exact nested replacement. Common examples:
id,timestamp, andisBatchedmove underevent.body,mediaPath,mediaType,mediaFileName,mediaUrl,location, anduntrustedStructuredContextmove underpayload.to,chatId, sender/self fields,sendComposing,reply(...), andsendMedia(...)move underplatform.replyTo*fields move underquote, and group subject/participant/mention fields move undergroup.
payload.untrustedStructuredContext is extracted from inbound provider payloads.
Plugins should inspect the label, source, and type before treating its
payload as authoritative.
WhatsApp Inbound Admission Fields
Accepted WhatsApp callback messages now carry admission, a public-safe
envelope for the access-control decision that admitted the message. New callback
code should read admission facts from msg.admission instead of the older
top-level admission fields.
The top-level fields remain available until 2026-08-30. The TypeScript
@deprecated annotations name each replacement:
fromandconversationIdmove toadmission.conversation.id.accountIdmoves toadmission.accountId.accessControlPassedis a derived compatibility view ofadmission.ingress.decision === "allow"; on messages that already carryadmission, writing the legacy boolean does not rewrite the ingress graph.chatTypemoves toadmission.conversation.kind.
Release notes
Release notes should include upcoming plugin deprecations with target dates and
links to migration docs. That warning needs to happen before a compatibility
path moves to removal-pending or removed.