Daemon Mode and Webhook Hooks

Run Octomind as a persistent background session that reacts to external events.

Daemon Mode

Start a session that stays alive after processing, accepting injected messages:

octomind run --name ci-watcher --daemon --format jsonl
FlagPurpose
--nameRequired for daemon. Identifies the session.
--daemonKeep session alive after processing
--format jsonlStructured output for programmatic consumption

Sending Messages

Inject messages into a running daemon:

echo "Check the build status" | octomind send --name ci-watcher

Webhook Hooks

HTTP webhook listeners that pipe payloads through scripts and inject output into the session.

Configuration

[[hooks]]
name = "github-push"
bind = "0.0.0.0:9876"
script = "/path/to/process-github-push.sh"
timeout = 30
FieldTypeDefaultDescription
namestringrequiredUnique hook identifier
bindstringrequiredHTTP server address:port
scriptstringrequiredPath to executable script
timeoutu3230Script timeout (1-3600 seconds)

Activating Hooks

octomind run --name ci-watcher --daemon --format jsonl --hook github-push

Multiple hooks can be activated:

octomind run --daemon --hook github-push --hook slack-notify

Script Interface

When a webhook request arrives:

ChannelContent
stdinRaw HTTP body
stdoutMessage to inject into session (on exit 0)
stderrError info (logged on non-zero exit)

Exit codes:

  • 0 -- success, stdout is injected as user message
  • Non-zero -- failure, stderr is logged

Environment Variables

Available to hook scripts:

VariableDescription
HOOK_NAMEHook identifier
HOOK_METHODHTTP method (GET, POST, etc.)
HOOK_PATHRequest path
HOOK_QUERYQuery string
HOOK_CONTENT_TYPEContent-Type header
HOOK_SESSIONSession name
HOOK_HEADER_*Each HTTP header (uppercased, hyphens to underscores)

Example: GitHub Push Hook

Script (/path/to/process-github-push.sh):

#!/bin/bash
# Read JSON payload from stdin
payload=$(cat)

# Extract info
repo=$(echo "$payload" | jq -r '.repository.full_name')
branch=$(echo "$payload" | jq -r '.ref' | sed 's|refs/heads/||')
pusher=$(echo "$payload" | jq -r '.pusher.name')
commits=$(echo "$payload" | jq -r '.commits | length')

# Output message to inject into session
echo "New push to $repo ($branch) by $pusher: $commits commit(s). Please review the changes."

Unified Inbox

All injected messages flow through a unified inbox system:

Message sources:

  • Schedule -- scheduled messages from the schedule tool
  • BackgroundAgent -- completed async agent jobs
  • TapRun -- completed tap run (specialist agent) jobs
  • Skill -- skill activations requiring content injection
  • SkillValidator -- skill validation results
  • Inject -- external injection via octomind send
  • Webhook -- HTTP webhook requests

Messages are drained in order: scheduled → background → tap run → skill → skill validator → inject → webhook. Each session has an isolated queue with async notification support.

Use Cases

CI/CD Monitoring

# Start daemon
octomind run --name ci-bot --daemon --format jsonl --hook github-push

# GitHub webhook posts to http://server:9876/
# Script processes payload, injects summary
# AI analyzes changes and reports issues

Slack Integration

octomind run --name slack-bot --daemon --hook slack-event

Automated Code Review

octomind run --name reviewer --daemon --hook github-pr
# Script extracts PR details
# AI reviews code and posts comments

Further Reading

See Custom Hooks for comprehensive hook development guide with examples in Python, Node.js, Bash, Ruby, and Go -- including signature validation, event filtering, and multi-hook architecture patterns.