Skip to main content

Conversation Daemon

Automatic capture and storage of Claude Code sessions.

Overview

The ClaudeBox daemon watches for Claude Code session events and stores complete conversation history in PostgreSQL. This enables:

  • Session Search - Find past conversations by content
  • Usage Analytics - Track tool usage, file modifications
  • Context Persistence - Reference previous work across sessions
  • Audit Trail - Complete record of AI-assisted development

How It Works

Claude Code Session


Hook fires (stop/notification)


Hook script writes event to ~/.claude/inbox/claudebox/events/


Daemon (watchdog) detects new file


Parse event JSON + transcript JSONL


Insert to PostgreSQL (argus schema)


Delete event file


Available via janus_claudebox_* MCP tools

Database Schema

Conversations are stored in the argus database:

claude_conversations

Session metadata:

ColumnTypeDescription
session_idUUIDClaude Code session ID
project_pathTEXTWorking directory
summaryTEXTAuto-generated summary
message_countINTTotal messages
started_atTIMESTAMPSession start
ended_atTIMESTAMPSession end
tools_usedJSONBTool usage counts

claude_messages

Individual messages:

ColumnTypeDescription
idUUIDMessage ID
session_idUUIDParent session
roleTEXTuser, assistant, system
contentTEXTMessage content
tool_callsJSONBTool invocations
timestampTIMESTAMPWhen sent

Querying Conversations

Via Janus MCP

# List recent sessions
janus_claudebox_list(limit=20, project="janus")

# Get specific conversation
janus_claudebox_get(session_id="abc-123")

# Full-text search
janus_claudebox_search(query="authentication bug")

# Search message content
janus_claudebox_search_messages(query="useEffect cleanup")

# Usage statistics
janus_claudebox_stats(since="7d")

Via Argus UI

Browse conversations at: https://argus.meetrhea.com/claudebox

Features:

  • Session timeline
  • Message viewer
  • Tool usage breakdown
  • File modification tracking
  • Search and filter

Event Processing

Idempotency

Each event has a unique ID. The daemon checks for existing records before inserting, preventing duplicates if the same event is processed multiple times.

Dead Letter Queue

Failed events are moved to ~/.claude/inbox/claudebox/dead-letter/ with error details:

{
"event": { ... },
"error": "Database connection failed",
"attempts": 3,
"last_attempt": "2025-01-01T12:00:00Z"
}

Check dead letter status:

janus_claudebox_inbox_status()

Retry Logic

  • Max retries: 3
  • Backoff: Exponential (2^attempt seconds)
  • After max retries: Move to dead letter queue

Running the Daemon

# Start manually
claudebox-daemon

# Via systemd (recommended)
systemctl --user start claudebox-daemon
systemctl --user status claudebox-daemon

# View logs
journalctl --user -u claudebox-daemon -f

Configuration

The daemon reads from ~/.config/claudebox/env:

# Database connection
RHEA_APPS_DB_LOCAL=postgresql://user:pass@localhost/argus

# Optional overrides
CLAUDEBOX_INBOX_DIR=~/.claude/inbox/claudebox
CLAUDEBOX_POLL_INTERVAL=1.0
CLAUDEBOX_MAX_RETRIES=3

Directory Structure

~/.claude/inbox/claudebox/
├── events/ # Pending event files
│ └── event_*.json
├── dead-letter/ # Failed events
│ └── dead_*.json
└── logs/ # Hook logs
└── hook-errors.log

Troubleshooting

Events not being captured

  1. Check hooks are installed:

    ls ~/.claude/hooks/
  2. Verify daemon is running:

    systemctl --user status claudebox-daemon
  3. Check for errors:

    cat ~/.claude/inbox/claudebox/logs/hook-errors.log

Database connection issues

  1. Verify env file exists:

    cat ~/.config/claudebox/env
  2. Test connection:

    psql "$RHEA_APPS_DB_LOCAL" -c "SELECT 1"

Dead letters accumulating

  1. Check dead letter queue:

    janus_claudebox_inbox_status()
  2. Review error messages:

    cat ~/.claude/inbox/claudebox/dead-letter/dead_*.json | jq .error
  3. Fix issue and reprocess:

    mv ~/.claude/inbox/claudebox/dead-letter/*.json \
    ~/.claude/inbox/claudebox/events/