Plugin System
This document describes Séance's auto-install mechanism for agent integrations and version tracking.
Overview
Séance auto-installs agent integrations on startup. The mechanism varies by integration type:
- TypeScript plugins — copied to agent config directories
- Python plugins — installed as directories with manifest files
- Shell hooks — injected into JSON configuration files
- TOML config hooks — appended to TOML configuration files
- Built-in wrappers — no installation needed (wrapper scripts in
resources/bin/) - Session log monitors — no installation needed (wrapper scripts with inotifywait)
For detailed documentation on each integration approach, see:
Auto-Install Mechanism
TypeScript Plugins
- Check if agent is installed — verify config directory exists (e.g.,
~/.config/opencode/) - 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
Python Plugins (Hermes)
- Check if
~/.hermes/exists - Create
~/.hermes/plugins/seance/directory - Write
plugin.yamlmanifest and__init__.pyhook registration
Shell Hooks (Claude Code)
- Read
~/.claude/settings.json - Parse the
hooksarray - Add new hook entries if not present
- Write back the modified JSON
TOML Config (Vibe)
- Check if
~/.vibe/hooks.tomlexists - If not, create with Séance hooks
- If exists, check for
"Auto-installed by"marker - If marker present, already installed — skip
- If marker missing, append Séance hooks after existing content
Version Tracking
Each TypeScript plugin embeds a version as a 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.
Current plugin versions:
| Agent | Plugin Version |
|---|---|
| OpenCode | @seance-version 13 |
| Kilo Code | @seance-version 13 |
| MiMo Code | @seance-version 37 |
Wrapper Scripts
Every agent integration includes a wrapper script in resources/bin/ that intercepts agent launches inside Séance terminals. The wrapper:
- Discovers the real binary — skips the wrapper directory to find the actual agent executable
- Passes through if not in Séance — if
SEANCE_SURFACE_IDis not set, runs the agent directly - Exports PID — sets
SEANCE_<AGENT>_PIDfor process tracking - Launches the agent — runs as a child process (non-exec)
- Fires session-end on exit — uses
trap ... EXITto ensure cleanup even on crash
| Wrapper | Agent | PID Env Var | Hook Command |
|---|---|---|---|
resources/bin/claude | Claude Code | SEANCE_CLAUDE_PID | claude-hook |
resources/bin/codebuff | Codebuff | SEANCE_CODEBUFF_PID | codebuff-hook |
resources/bin/codex | Codex | SEANCE_CODEX_PID | codex-hook |
resources/bin/freebuff | Freebuff | SEANCE_FREEBUFF_PID | freebuff-hook |
resources/bin/hermes | Hermes Agent | SEANCE_HERMES_PID | hermes-hook |
resources/bin/kilo | Kilo Code | SEANCE_KILO_PID | kilo-hook |
resources/bin/mimo | MiMo Code | SEANCE_MIMOCODE_PID | mimocode-hook |
resources/bin/opencode | OpenCode | SEANCE_OPENCODE_PID | opencode-hook |
resources/bin/pi | Pi Agent | SEANCE_PI_PID | pi-hook |
resources/bin/pool | Poolside Agent CLI | SEANCE_POOL_PID | pool-hook |
resources/bin/vibe | Mistral Vibe | SEANCE_VIBE_PID | vibe-hook |
Config Toggles
Each agent integration can be toggled in ~/.config/seance/config.toml:
# Agent integrations
opencode-hooks = true
kilo-hooks = true
mimocode-hooks = true
codex-hooks = true
pi-hooks = true
pool-hooks = true
codebuff-hooks = true
freebuff-hooks = true
vibe-hooks = true
hermes-hooks = trueOr via the Settings UI: Settings → Terminal → Agent Integration.