# Plugins `src/plugins/` exposes both a C plugin ABI and a Python plugin runtime. Both funnel through a shared core that fires callbacks on cproof events. ## Files | File | Role | |---|---| | `plugins.c/h` | Public surface: load/unload, list, dispatch hooks. | | `c_plugins.c/h` | C plugin loader (dlopen). | | `python_plugins.c/h` | Python plugin loader (embedded interpreter). | | `c_api.c/h` | C-side API exposed **to** plugins. | | `python_api.c/h` | Python-side API exposed **to** plugins. | | `api.c/h` | Shared API helpers. | | `profapi.c/h` | The `prof` Python module surface. | | `callbacks.c/h` | Hooks: pre/post message, pre/post presence, etc. | | `autocompleters.c/h` | Plugin-registered autocompleters. | | `disco.c/h` | Service-discovery feature contributions from plugins. | | `settings.c/h` | Per-plugin settings storage. | | `themes.c/h` | Plugin-supplied themes. | ## Hook points Plugins fire on events around (cf. `src/plugins/callbacks.c`): - Pre/post message send, pre/post message receive. - Pre/post chat-message-display. - Pre/post connect, disconnect. - Pre/post quit. - Window-switch, room-join, room-leave. The callback names follow `prof_pre_*` / `prof_post_*` in the plugin API surface; in cproof internals they are dispatched via `plugins_pre_chat_message_send()` and similar. ## API surface for plugins C API (`c_api.h`) and Python API (`python_api.h`) are kept in sync — any new function in one should land in the other unless explicitly C-only or Python-only. The Python wrapper is in `profapi.c/h` and is exposed as the `prof` module inside plugins. ## Adding a plugin hook point 1. Define dispatcher in `plugins.c/h`: `void plugins__();` 2. Wire callback storage in `callbacks.c/h`. 3. Expose to plugins via `c_api.c/h` and `python_api.c/h` (matching names). 4. Call the dispatcher at the appropriate site (usually in `src/event/` or `src/xmpp/`). 5. Document the hook in cproof's plugin docs (out of scope for this repo). ## Testing `tests/unittests/test_plugins_disco.{c,h}` covers plugin-disco feature contribution; broader plugin-system testing is light. Stubs: `tests/unittests/plugins/stub_*.c`. ## Pitfalls - Plugin callbacks may re-enter cproof via the C/Python API. Ensure state is consistent **before** firing a callback — see `patterns/events.md`. - The Python interpreter is global; plugins share state. Don't assume isolation. - Plugin loading is not sandboxed; treat plugins as trusted code.