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:
| Column | Type | Description |
|---|---|---|
session_id | UUID | Claude Code session ID |
project_path | TEXT | Working directory |
summary | TEXT | Auto-generated summary |
message_count | INT | Total messages |
started_at | TIMESTAMP | Session start |
ended_at | TIMESTAMP | Session end |
tools_used | JSONB | Tool usage counts |
claude_messages
Individual messages:
| Column | Type | Description |
|---|---|---|
id | UUID | Message ID |
session_id | UUID | Parent session |
role | TEXT | user, assistant, system |
content | TEXT | Message content |
tool_calls | JSONB | Tool invocations |
timestamp | TIMESTAMP | When 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
-
Check hooks are installed:
ls ~/.claude/hooks/ -
Verify daemon is running:
systemctl --user status claudebox-daemon -
Check for errors:
cat ~/.claude/inbox/claudebox/logs/hook-errors.log
Database connection issues
-
Verify env file exists:
cat ~/.config/claudebox/env -
Test connection:
psql "$RHEA_APPS_DB_LOCAL" -c "SELECT 1"
Dead letters accumulating
-
Check dead letter queue:
janus_claudebox_inbox_status() -
Review error messages:
cat ~/.claude/inbox/claudebox/dead-letter/dead_*.json | jq .error -
Fix issue and reprocess:
mv ~/.claude/inbox/claudebox/dead-letter/*.json \
~/.claude/inbox/claudebox/events/