Monitor Claude thinking in real-time with smart accumulation, optional AI compression, and sentiment-based coloring.
ccthink watches your Claude Code conversation sessions, extracts thinking content, and optionally commits it to git. Think of it as a background process that captures your AI assistant's reasoning while you work.
- Patch CC to always show thinking https://github.com/aleks-apostle/claude-code-thinking-patch
- CC chats in real-time on a web UI
npx claude-code-templates@latest --chatshttps://github.com/davila7/claude-code-templates - Export CC logs https://github.com/ZeroSumQuant/claude-conversation-extractor
- Displays thinking/chat as it arrives from Claude Code sessions
- Shows tool uses (Bash, Read, Write, etc.) in chronological order with thinking (optional)
- Accumulates thinking entries before committing (prevents commit spam)
- Compresses phrases using Claude models (Sonnet or Haiku) to make thinking more scannable (optional)
- Applies sentiment colors via ANSI 256 codes for visual feedback (optional)
- Manages git branches automatically for each conversation session (optional)
- No API keys required - uses Claude Code's authentication
Keep a permanent record of Claude's reasoning process for future reference. Useful when:
- Building complex features that require understanding design decisions
- Onboarding team members who need context on implementation choices
- Creating technical documentation from Claude's analytical approach
Study how Claude approaches problems to improve your own problem-solving. Track:
- Debugging strategies and diagnostic techniques
- Architectural decision-making processes
- Code optimization reasoning
- Error analysis approaches
Share Claude's thinking with your team through git history:
- Code review context: Reviewers see the reasoning behind changes
- Pair programming documentation: Capture the collaborative thought process
- Knowledge transfer: Junior developers learn from Claude's explanations
Review thinking behaviors over time to:
- Identify recurring architectural decisions
- Spot common debugging approaches
- Analyze problem-solving strategies
- Track Claude's reasoning evolution on long-term projects
Preserve diagnostic thinking when debugging issues:
- Trace the investigation process step-by-step
- Document hypothesis formation and elimination
- Record solution discovery paths
- Create reproducible debugging narratives
# Basic monitoring (display only)
cd /path/to/your/project
ccthink
# Monitor with git commits
ccthink --commit
# Monitor with Sonnet compression
ccthink --sonnet
# Monitor with Haiku compression (faster, lower cost)
ccthink --haiku
# Full features: commits + compression + streaming + colors
ccthink --commit --sonnet --streaming --colors
# Or use Haiku for faster compression
ccthink --commit --haiku --streaming --colors
# Successive starts(maintains the last configuration):
ccthinkccthink stores settings in ccthink.conf in your project directory. On first run, it creates this file with defaults:
{
"commit_enabled": false,
"sonnet_enabled": false,
"sonnet_streaming": false,
"colors": false,
"tool_uses": true,
"thinking_enabled": true,
"chat_text_enabled": false,
"thinking_color": "#A5D8FF",
"chat_text_color": "#FFFACD",
"poll_interval_seconds": 1.0,
"line_max_length": 55,
"main_branch": "master"
}Change behavior with CLI flags that persist to configuration:
| Flag | Effect | Persists |
|---|---|---|
--commit |
Enable git commits | Yes |
--no-commit |
Disable git commits | Yes |
--sonnet |
Enable Sonnet phrase compression | Yes |
--no-sonnet |
Disable Sonnet phrase compression | Yes |
--haiku |
Enable Haiku phrase compression | Yes |
--no-haiku |
Disable Haiku phrase compression | Yes |
--colors |
Apply sentiment-based colors | Yes |
--no-colors |
Display plain text | Yes |
--chat-text |
Enable chat text content extraction | Yes |
--no-chat-text |
Disable chat text content (thinking only) | Yes |
--streaming |
Stream compression output | Yes |
--no-streaming |
Show compression results instantly | Yes |
--verbose |
Enable verbose logging with timestamps | Yes |
--no-verbose |
Disable verbose logging | Yes |
--simulate |
Enable dry-run mode (skip git operations) | Yes |
--no-simulate |
Disable dry-run mode (perform git ops) | Yes |
Example workflow:
# First run: enable commits and Sonnet compression
ccthink --commit --sonnet
# Settings saved to ccthink.conf
# Or use Haiku for faster compression
ccthink --commit --haiku
# Later: just run ccthink (settings remembered)
ccthink
# Switch between models
ccthink --haiku # Switch to Haiku
ccthink --sonnet # Switch to Sonnet
# Temporarily disable compression
ccthink --no-sonnet
# This updates ccthink.confccthink uses smart batching to avoid noisy commits:
- First thinking arrives → Start 30-second timer
- More thinking within 30s → Commit accumulated batch immediately
- Timeout expires → Commit what was accumulated
- File switches → Commit pending thinking and merge branch
This creates meaningful commits with multiple thinking entries rather than one commit for each thought.
- Python 3.10+ required
- Git for commit functionality
- Claude Code installed and configured
# Clone repository
git clone https://github.com/normalnormie/ccthink.git
cd ccthink
# Install
bash install.shThis installs to ~/.local/lib/ccthink and creates a symlink at ~/.local/bin/ccthink.
Add to PATH (if not already):
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrcREM Clone repository
git clone https://github.com/normalnormie/ccthink.git
cd ccthink
REM Install
install.batThis installs to %LOCALAPPDATA%\Programs\ccthink and creates a launcher in %LOCALAPPDATA%\Microsoft\WindowsApps.
Verify installation:
ccthink --helpLinux/macOS:
bash uninstall.shWindows:
uninstall.batMonitors ~/.claude/projects/{your-project}/ for JSONL conversation files and extracts thinking content in real-time.
What it does:
- Polls every 1 second (configurable)
- Reads only incoming content (tracks file position)
- Skips non-thinking messages
- Formats long lines at natural breakpoints (periods, semicolons, commas)
- Preserves code blocks and numbered lists
- Separates thinking entries with
---divider
Line formatting:
Long thinking is split into ~55 character lines at natural pauses for easier scanning:
Original: "Analyzing the user's request and determining the best approach for implementation using existing patterns"
Formatted:
Analyzing the user's request and determining
the best approach for implementation using
existing patterns
Shows Claude Code tool calls alongside thinking in chronological order.
What it does:
- Captures Bash, Read, Write, Edit, Task, and other tool invocations
- Displays full file paths and command details
- Maintains chronological ordering with thinking entries
- Configurable via
tool_usesflag (defaults to true)
Display format:
Analyzing requirements...
Bash(mkdir -p /home/user/project/src)
Write(/home/user/project/src/main.py)
Files created successfully...
Disable tool use display:
Edit ccthink.conf:
{
"tool_uses": false
}Creates git commits with thinking content as the commit message.
What it does:
- Creates conversation-specific branches (named by JSONL file)
- Accumulates multiple thinking entries before committing
- Uses 30-second timeout before auto-commit
- Immediately commits if additional thinking arrives while waiting
- Merges conversation branches to main on file switch
- Handles "nothing to commit" gracefully
- Optional quit-on-conflict mode
Branch strategy:
# Session 1: conversation_abc123.jsonl
git branch: conversation_abc123
# Multiple commits on this branch
# Session 2: conversation_def456.jsonl
# Automatically merges conversation_abc123 → master
git branch: conversation_def456Transforms verbose thinking into concise, scannable phrases using Claude models (Sonnet or Haiku).
What it does:
- Compresses while preserving details, tense, and voice
- Analyzes sentiment and suggests ANSI 256 color codes
- Caches results (hash-based, max 100 entries)
- Retries on failure (3 attempts with exponential backoff)
- Processes up to 3 phrases concurrently
- Falls back to original text on compression failure
- No API keys needed (uses Claude Code's authentication)
Model selection:
- Sonnet (
--sonnet): Higher quality compression, more detailed - Haiku (
--haiku): Faster compression, lower cost, excellent for high-volume use
Compression examples:
Before: "Looking at the error message and determining what might be causing the authentication failure in the database connection"
After: "Diagnosing auth failure in DB connection"
Color: Yellow (cautious sentiment)
Before: "Built the caching layer with Redis integration and verified all checks pass"
After: "Configured Redis caching, checks passing"
Color: Green (positive sentiment)
Streaming mode:
When --streaming is enabled, you see compressed text as it arrives token-by-token:
Analyzing... database... schema... for... optimization... opportunities
Colored output:
When --colors is enabled, compressed phrases display with sentiment-appropriate colors:
- 🟢 Green (40-46): Success, completion, positive outcomes
- 🟡 Yellow (220-226): Caution, analysis, consideration
- 🔴 Red (196-202): Errors, warnings, blockers
- 🔵 Blue (33-39): Information, neutral observations
- 🟣 Purple (129-135): Creative thinking, conceptual ideas
Performance characteristics:
- Compression timeout: 5 seconds for each phrase
- Batch size: Up to 3 concurrent compressions
- Retry strategy: 3 attempts (1s → 2s → 4s delays)
- Cache: SHA256 hash-based, FIFO eviction at 100 items
- Fallback: Shows original thinking if compression fails
Configure colors for thinking and chat content independently:
{
"thinking_color": "#A5D8FF", // Light blue (default)
"chat_text_color": "#FFFACD" // Light yellow (default)
}Supported color formats:
- CSS color names:
"lightblue","red","magenta","yellow","white", etc. - Hex codes:
"#A5D8FF","#FFFACD","#FF5733"
Color application logic:
-
When Sonnet compression is disabled (
sonnet_enabled: false):- Configured colors are always applied to raw content
- Thinking content uses
thinking_color - Chat text content uses
chat_text_color
-
When Sonnet compression is enabled (
sonnet_enabled: true):- Compression service applies sentiment-aware coloring
- If compression returns no color: Falls back to configured colors
- If compression fails completely: Falls back to configured colors
Examples:
# Set custom colors via configuration file
echo '{
"thinking_color": "lightblue",
"chat_text_color": "yellow"
}' > ccthink.conf
# Or use hex codes for precise colors
echo '{
"thinking_color": "#4A90E2",
"chat_text_color": "#FFD700"
}' > ccthink.confExtended settings in ccthink.conf:
{
"poll_interval_seconds": 1.0,
"line_max_length": 55,
"separator": "\n\n---\n\n",
"main_branch": "master",
"tool_uses": true,
"thinking_enabled": true,
"chat_text_enabled": false,
"thinking_color": "#A5D8FF",
"chat_text_color": "#FFFACD",
"quit_on_conflict": false,
"projects_dir": "~/.claude/projects/",
"compression_prompt": "Compress this phrase keeping details, tense, and voice, choosing an ANSI 256 color reflecting its sentiment, output as json {\"color\":\"\",\"text\":\"\"}: {phrase}",
"claude_agent": {
"model": "sonnet", // or "haiku" for faster compression
"maxTurns": 1,
"systemPrompt": "Ignore any project context and respond based solely on this query. Output only the compressed phrase.",
"disallowedTools": [
"Bash",
"Read",
"Write",
"Edit",
"MultiEdit",
"Glob",
"Grep",
"WebFetch",
"WebSearch",
"Task",
"LS",
"ExitPlanMode",
"NotebookRead",
"NotebookEdit",
"TodoWrite",
"KillBash",
"BashOutput",
"SlashCommand"
]
}
}Modify the compression behavior by editing the prompt template in ccthink.conf. The prompt must include {phrase} and instruct Claude to output JSON with color and text fields:
{
"compression_prompt": "Summarize in 10 words or less, choosing an ANSI 256 color reflecting sentiment, output as json {{\"color\":\"\",\"text\":\"\"}}: {phrase}"
}Examples:
// Ultra-concise mode
"compression_prompt": "5 words max, choose ANSI 256 color by sentiment, output json {{\"color\":\"\",\"text\":\"\"}}: {phrase}"
// Technical focus
"compression_prompt": "Extract technical action and outcome, choose ANSI 256 color by outcome result, output json {{\"color\":\"\",\"text\":\"\"}}: {phrase}"
// Neutral tone
"compression_prompt": "Compress keeping all details, neutral color (37), output json {{\"color\":\"37\",\"text\":\"\"}}: {phrase}"Note: The double braces {{ and }} are required to escape JSON braces in the configuration file.
Run ccthink on multiple projects simultaneously, each with independent configuration:
# Terminal 1: Monitor project A with commits
cd ~/projects/my-app
ccthink --commit
# Terminal 2: Monitor project B with compression
cd ~/projects/another-app
ccthink --sonnet --colors
# Terminal 3: Monitor project C (display only)
cd ~/projects/third-app
ccthinkEach project maintains:
- Separate
ccthink.confconfiguration - Independent file position tracking
- Isolated git branch management
- Individual accumulation state
Leverage git to analyze thinking over time:
# View all thinking commits on a conversation branch
git log conversation_abc123
# Export thinking from a specific conversation
git log conversation_abc123 --format="%B" > thinking-log.txt
# Search thinking history
git log --all --grep="authentication"
# View thinking from last 7 days
git log --since="7 days ago" --all --format="%B"Adjust polling and formatting for your workflow:
Faster polling (more responsive, higher CPU usage):
{
"poll_interval_seconds": 0.5
}Longer lines (more context, less wrapping):
{
"line_max_length": 80
}Custom separator (visual preference):
{
"separator": "\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
}Enable compression only when needed and switch between models:
# Start without compression
ccthink --commit
# Enable Sonnet compression for specific sessions
ccthink --sonnet
# Switch to Haiku for faster compression
ccthink --haiku
# Disable compression
ccthink --no-sonnet
# Or
ccthink --no-haikuSettings persist, so each change updates ccthink.conf for future runs.
- Ensure Claude Code is running a conversation
- Check
~/.claude/projects/exists and contains JSONL files - Verify
ccthink.confhas correctprojects_dirpath
- Ensure Claude Code is configured with valid authentication
- Check
~/.claude.jsonexists (Claude Code's config) - Try switching models:
--haikuor--sonnet - Try
--no-sonnetor--no-haikuto disable compression temporarily
Linux/macOS:
export PATH="$HOME/.local/bin:$PATH"Windows:
Ensure %LOCALAPPDATA%\Microsoft\WindowsApps is in your PATH.
If ccthink exits on merge conflicts:
# Resolve conflict manually
git status
git merge --abort # Or resolve and commit
# Disable quit-on-conflict
# Edit ccthink.conf: "quit_on_conflict": falseNo. ccthink only reads JSONL files that Claude Code writes to disk. It does not interact with Claude Code directly or affect its operation in any way. The polling interval (default 1 second) has negligible impact on system resources.
Yes. Each project directory gets its own independent configuration, state tracking, and git branch management. You can run ccthink in multiple terminal windows, each monitoring a different project with different settings.
State is persisted continuously. When you restart ccthink, it resumes from the last saved position:
- File position is preserved (won't re-display old thinking)
- Accumulated thinking is saved (will commit on restart or timeout)
- Configuration changes persist across restarts
No. ccthink uses Claude Code's authentication via the claude-agent-sdk, which automatically reads credentials from ~/.claude.json. If Claude Code works, compression will work.
When the first thinking entry arrives, ccthink starts a 30-second timer. If more thinking arrives before the timer expires, it immediately commits all accumulated thinking and resets. If the timer expires without additional thinking, it commits what was accumulated. This prevents both commit spam and lost thinking.
Yes. Edit the compression_prompt field in ccthink.conf:
{
"compression_prompt": "Your custom prompt template: {phrase}"
}The {phrase} variable is required and will be replaced with the thinking text.
By default, ccthink displays content from MessageContent blocks with type: "thinking" and tool use invocations (when tool_uses is enabled). Regular text messages are filtered out unless you enable chat_text_enabled in ccthink.conf. This focuses on Claude's internal reasoning process while allowing optional text message extraction when needed.
When ccthink detects a file switch (different JSONL file):
- Commits any pending accumulated thinking
- Brings the previous conversation branch into main
- Resets file position and state
- Begins monitoring the current file
Each conversation gets its own git branch, brought into main when you move to the next conversation.
Yes. ccthink reads the JSONL file incrementally as Claude writes to it. You'll see thinking appear in real-time as Claude generates it, even during streaming responses.
Minimal. Configuration files are typically <1KB. Cached compression results use ~10KB for 100 entries. Git commits contain only thinking text, which compresses well in git's object database.
Not currently. All thinking content is captured. If you want selective commits, use --no-commit mode and manually commit the thinking you want to keep from the displayed output.
- With --streaming: You see compressed text token-by-token as Sonnet generates it (like typing animation)
- Without --streaming: You see the complete compressed result instantly after Sonnet finishes
Both produce the same final output; streaming just provides visual feedback during generation.
Compression falls back to original thinking when:
- Sonnet API request times out (5 seconds)
- Response fails to parse as valid JSON
- All retry attempts exhausted (3 tries)
- Network connectivity issues
The original thinking is always preserved and displayed.
- Monitors
~/.claude/projects/{project}/for JSONL conversation files - Parses thinking entries and tool uses from JSONL records
- Displays items in chronological order as they occur
- Accumulates multiple entries for 30 seconds or until more thinking arrives
- Optionally compresses with Claude models (concurrently, with caching and retry)
- Formats long lines at natural breakpoints for readability
- Commits to conversation-specific git branch (optional)
- Merges branches when switching between conversation sessions (optional)
- Python 3.10 or later
- Git (for commit functionality)
- Claude Code with valid authentication
- Dependencies:
claude-agent-sdk>=0.0.25pydantic>=2.0.0orjson>=3.9.0
MIT License - see LICENSE file for details
Contributions welcome! Please open an issue before submitting major changes.

