Plugin-Based Integration
Plugin-based integrations use the agent's native plugin system to subscribe to lifecycle events and forward them to Séance. This is the most common integration approach for agents with rich plugin ecosystems.
How It Works
- Séance auto-installs a plugin to the agent's config directory on startup
- The agent process loads the plugin and exposes its event system
- The plugin subscribes to lifecycle events (session created, tool executed, permission requested, etc.)
- Each event is translated to a Séance hook command via
seance ctl <agent>-hook <event> - The hook payload (JSON) is piped via stdin to the running Séance instance
Plugin Types
TypeScript Plugins
Used by: OpenCode, Kilo Code, MiMo Code
TypeScript plugins are the most common approach. The plugin is a .ts file that exports a SeancePlugin async function receiving $ (shell executor). It subscribes to the agent's event system and sends hooks via subprocess calls.
Install locations:
| Agent | Install Target | Source |
|---|---|---|
| OpenCode | ~/.config/opencode/plugins/seance-opencode.ts | plugins/seance-opencode/index.ts |
| Kilo Code | ~/.config/kilo/plugins/seance-kilo.ts | plugins/seance-kilo/index.ts |
| MiMo Code | ~/.config/mimocode/plugins/seance-mimocode.ts | plugins/seance-mimocode/index.ts |
Version tracking: Each plugin embeds a version comment:
// @seance-version 13This version is extracted by extractVersion() in src/app.zig and compared against the installed version. If the bundled version is newer, the plugin is reinstalled.
Python Plugins
Used by: Hermes Agent
Python plugins are used when the agent's plugin callbacks fire from a shared core that covers multiple surfaces (CLI, TUI, gateway, desktop).
Install location: ~/.hermes/plugins/seance/ directory with:
plugin.yaml— manifest withname,version,hooks:list__init__.py— exposesdef register(ctx)that callsctx.register_hook(event, callback)
Why Python: Hermes's plugin callbacks fire from the shared core, covering CLI, TUI, gateway, desktop, and dashboard surfaces. An earlier shell-hooks design only worked on the CLI surface because the TUI backend never called register_from_config.
Event Flow
Agent Framework → Plugin → seance ctl <agent>-hook → Socket API → Workspace Metadata → Sidebar UI- The agent framework fires a lifecycle event
- The plugin receives the event and translates it to a Séance hook command
- The plugin runs
seance ctl <agent>-hook <event>as a subprocess, passing JSON via stdin ctl.zigreceives the command over the Unix socket, updates workspace metadata- The sidebar UI reflects the updated status
Auto-Install Mechanism
Plugins are auto-installed on Séance startup:
- Check if agent is installed — verify the config directory exists
- Read bundled plugin — from
{prefix}/share/seance/{name}-plugin.ts - Compare version and content — extract
@seance-versionfrom bundled and installed plugins - Write atomically — if outdated or missing, write to a
.tmpfile then rename (atomic replace)
For Python plugins (Hermes), the mechanism installs a directory with plugin.yaml and __init__.py.
Advantages
- Rich event data — plugins receive structured event objects with session IDs, tool names, and other metadata
- Reliable — events are fired by the agent framework itself, not inferred from file changes
- Real-time — events fire immediately when they occur
- Full lifecycle coverage — can track sessions, tools, permissions, and more
Limitations
- Agent-specific — each agent has its own plugin API; plugins can't be shared across agents
- Maintenance burden — plugins must be updated when the agent's API changes
- Installation complexity — requires writing to the agent's config directory
Adding a New Plugin-Based Integration
To add support for a new agent with a TypeScript plugin:
- Create
plugins/seance-{name}/index.ts— copy from an existing plugin - Create
resources/bin/{binary-name}— wrapper script for PID tracking - Add
AgentConfiginsrc/ctl.zig— define the agent's config struct - Add dispatch in
src/ctl.zig—if (eql(command, "{name}-hook")) - Add auto-install in
src/app.zig—install{Name}Plugin()function - Add config toggle in
src/config.zig—{name}_hooks: bool = true - Add settings UI in
src/settings.zig— toggle widget - Add build integration in
build.zig— install plugin toshare/seance/