Hook-Based Integration
Hook-based integrations use the agent's native hook configuration system to register callbacks that fire during the agent's lifecycle. This approach works when agents support hooks through configuration files rather than plugin APIs.
How It Works
- Séance injects hook definitions into the agent's configuration file
- The agent loads the configuration and registers the hooks
- When lifecycle events occur, the agent calls the registered hooks
- The hooks invoke
seance ctl <agent>-hook <event>with a JSON payload
Hook Mechanisms
Shell Hooks (Claude Code)
Used by: Claude Code
Claude Code uses a JSON-based hook system configured in ~/.claude/settings.json. Séance injects hook commands into the hooks array.
How it works:
- Séance reads
~/.claude/settings.json - Adds hook entries to the
hooksarray:json{ "hooks": { "SessionStart": [{"type": "command", "command": "seance ctl claude-hook session-start"}], "Stop": [{"type": "command", "command": "seance ctl claude-hook stop"}] } } - Claude Code fires these hooks during its lifecycle
- Each hook calls back to
seance ctl claude-hook
Why JSON: Claude Code's hook system is configured via JSON, not a plugin API. This is the only way to register lifecycle callbacks without modifying the agent's source code.
TOML Config Hooks (Mistral Vibe)
Used by: Mistral Vibe
Vibe uses a TOML-based hook system configured in ~/.vibe/hooks.toml. Séance appends hook definitions to this file.
How it works:
- Séance reads
~/.vibe/hooks.toml(or creates it if missing) - Checks for
"Auto-installed by"marker to avoid duplicate installs - Appends hook definitions:toml
# Auto-installed by Séance [hooks] before_tool = "seance ctl vibe-hook pre-tool-use" after_tool = "seance ctl vibe-hook post-tool-use" post_agent_turn = "seance ctl vibe-hook stop" - Vibe calls these hooks during tool execution and turn completion
Append strategy: The install function appends to the file rather than overwriting, preserving any user-authored hooks above the marker.
Experimental hooks: Vibe's hooks are experimental. The wrapper script sets VIBE_ENABLE_EXPERIMENTAL_HOOKS=1. Without this, hooks silently do nothing.
Event Flow
Agent Configuration → Hook Registration → Agent Event → Hook Callback → seance ctl <agent>-hook → Sidebar UI- Séance injects hook definitions into the agent's config file
- The agent loads the config and registers the hooks
- When a lifecycle event occurs, the agent calls the registered hook
- The hook invokes
seance ctl <agent>-hook <event>with JSON payload ctl.zigreceives the command and updates the sidebar
Auto-Install Mechanism
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
Advantages
- No plugin required — works with agents that don't have a plugin API
- Simple configuration — just JSON or TOML entries
- Agent-native — uses the agent's own hook system, not external tooling
Limitations
- Limited event data — hooks receive less context than plugins (no session objects, just event names)
- Configuration file modification — modifies agent config files, which may conflict with user customizations
- Inferred boundaries — some agents (Vibe) don't have explicit session start/end hooks, requiring inference
Agent-Specific Notes
Claude Code
- Status mode: Session-level (shared across workspace surfaces)
- Notification support: Yes — hooks fire on permission requests and completions
- Session directory: Not exposed
Mistral Vibe
- Status mode: Per-surface
- Notification support: No — Vibe has no notification hook type
- Session boundaries: Inferred from hook activity and wrapper exit
- Experimental: Requires
VIBE_ENABLE_EXPERIMENTAL_HOOKS=1