hermes_cli/plugins.py (7193 -> 4961):
- _register_scoped_provider: one body for the 8 scope-keyed register_*_provider methods;
_track_callback/_track_mapping_entry unify manager-mapping lease tracking (4 sites);
_track_scoped_registration for the ownership ledger. Public method names, signatures,
return values and warning strings unchanged.
- Manifest v2 type checks table-driven (_manifest_field_of_type); _unload_scoped split into
_unload_target_keys + _reset_after_unload_all; _gate_manifest/_record_placeholder out of
_discover_and_load_inner; _track_tool_override_policy/_attribute_registrations out of
_load_plugin_scoped; bounded hook worker lifted into _run_hook_callback_bounded;
prompt-section rendering extracted; resolve_pre_tool_block delegates to
_dispatch_pre_tool_call_hooks; _evict_modules (3 sites); _remove_name_if_unowned and
_nowait_plugin_set unify unowned-name cleanup and *_nowait probes.
- Dead (zero references outside their own test): unload_plugins, has_portable_mcp_servers,
_classify_entrypoint_kind, _reset_event_bus, get_plugin_subscriptions,
get_telegram_handler_factories, pass-through _restore_* helpers; _env_enabled is now an alias
of utils.env_var_enabled (plugins/memory still imports it).
- Docstrings/comments compacted; contract sentences and rationale kept (multi-profile ledger
keying, persistent auth-provider registration, capability declaration is not a grant).
Platforms added to main after the original branch was cut; keeps the
source invariant (every connectable adapter calls _wire_plugin_handlers)
true, and adds qqbot to the invariant test's gateway list.
ctx.register_platform_handler(platform, factory) — the generic surface for
plugins to wire native handlers into any platform adapter at connect()
time. Factories receive (native, adapter): the platform's client/app
object (PTB Application, discord.py Bot, slack_bolt AsyncApp, Teams App,
DingTalkStreamClient, aiohttp web.Application) or None for adapters with
no separate native object.
- BasePlatformAdapter._wire_plugin_handlers(native): shared, isolated
invocation helper — a raising plugin cannot block a platform connect.
- All 27 connectable adapters call it: telegram/slack/teams/line/
api_server/msgraph_webhook wire before their dispatch tables freeze;
the rest hook at connect success.
- register_telegram_handler and get_telegram_handler_factories retained
as thin back-compat aliases over the telegram bucket.
- Source-invariant test guarantees every adapter with connect() keeps
calling the hook.