How Vibe Check Works
Vibe Check uses Claude Code’s hook system to monitor your coding sessions and deliver timely health reminders. The plugin operates entirely within your Claude conversation — no system popups, no OS notifications, just gentle in-context nudges.Architecture Overview
Vibe Check consists of three core components:- SessionStart Hook — Initializes or joins session state (
session_start.py) - UserPromptSubmit Hook — Checks timers and fires reminders (
check_reminder.py) - Shared State File — Persistent tracking across sessions (
~/.claude/vibe-check-state.json)
All timing logic runs in Python scripts, with state managed in a shared JSON file that supports multi-session tracking.
Session Lifecycle
SessionStart Hook Executes
When you start a Claude Code session, the Logic:
SessionStart hook loads or creates the shared state file.- If an active session exists (activity within the last 60 minutes), join it without resetting timers
- If no recent activity, start fresh with new timers
- This enables seamless multi-window support
Every Prompt Triggers Check
Each time you send a prompt, the
UserPromptSubmit hook runs check_reminder.py to evaluate elapsed time since your last breaks.The script checks three timers in priority order:- Full break (50 minutes) — highest priority
- Hydration (30 minutes) — medium priority
- Micro-break (20 minutes) — lowest priority
Reminder Formatted and Displayed
If you’re due for a break, the hook formats a reminder with Unicode box-drawing characters:Claude receives instructions to output the box exactly as-is, preserving all formatting.
Intelligent Break Detection
Vibe Check includes sophisticated logic to handle real-world coding patterns:Break Compliance Detection
After firing a reminder, the system measures whether you actually took the break:- Gap measurement — calculates time between Claude’s last response and your next prompt
- Threshold comparison — if the gap exceeds the break duration threshold, the timer resets
- Type-specific reset — full breaks reset all timers, micro and hydration breaks reset only their specific timer
Spontaneous Break Detection
If you step away from your computer without a pending reminder:- 15+ minute gaps are automatically credited as spontaneous breaks
- All timers reset — you get a fresh start when you return
- No reminder fires since you’ve already taken time away
Stale Session Handling
- 60 minutes of inactivity marks a session as stale
- Next session starts with fresh timers
- Prevents inappropriate reminders after long breaks (overnight, lunch, etc.)
Visual Reminder Format
Reminders appear as structured boxes with horizontal lines:- Unicode box-drawing character
─(U+2500) for horizontal lines - Default width of 80 columns (configurable via
VIBE_CHECK_BOX_WIDTH) - Emoji indicators for break type (👁️ eyes, 🙌 stretch, 💧 hydration)
- Elapsed time shown in the header
- Tips rotate automatically to provide variety
Multi-Session Support
Vibe Check uses a shared state file (~/.claude/vibe-check-state.json) that enables:
- Cross-session tracking — all Claude Code windows share the same timers
- Seamless joining — new sessions within 60 minutes continue existing tracking
- File locking — prevents race conditions when multiple sessions write state simultaneously
- Deduplication — 30-second window prevents the same reminder firing in parallel sessions
State Management
The state file tracks:last_micro,last_full,last_hydration— timestamps of last break for each typepending_break— tracks active reminder awaiting compliance checktip_index— ensures tips rotate through the full list before repeatinglast_response_end— enables gap measurement for break compliancereminder_count— total reminders fired in this session