Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 58 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 🎯 Claude Code Usage Monitor
[![PyPI Version](https://img.shields.io/pypi/v/claude-monitor.svg)](https://pypi.org/project/claude-monitor/)
[![Python Version](https://img.shields.io/badge/python-3.9+-blue.svg)](https://python.org)
[![Python Version](https://img.shields.io/badge/python-3.11+-blue.svg)](https://python.org)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](http://makeapullrequest.com)
[![codecov](https://codecov.io/gh/Maciek-roboblog/Claude-Code-Usage-Monitor/branch/main/graph/badge.svg)](https://codecov.io/gh/Maciek-roboblog/Claude-Code-Usage-Monitor)
Expand Down Expand Up @@ -63,6 +63,7 @@ A beautiful real-time terminal monitoring tool for Claude AI token usage with ad
- **πŸ§ͺ Extensive testing** - 100+ test cases with full coverage
- **🎯 Error reporting** - Optional Sentry integration for production monitoring
- **⚑ Performance optimized** - Advanced caching and efficient data processing
- **πŸ€– JSON output mode** - Machine-readable JSON for automation and scripting

### πŸ“‹ Default Custom Plan

Expand Down Expand Up @@ -199,6 +200,7 @@ claude-monitor --help
| --debug | flag | False | Enable debug logging |
| --version, -v | flag | False | Show version information |
| --clear | flag | False | Clear saved configuration |
| --json-output | flag | False | Output analysis data as JSON instead of interactive UI |

#### Plan Options

Expand Down Expand Up @@ -353,6 +355,9 @@ claude-monitor --log-file ~/.claude-monitor/logs/monitor.log

# Set log level
claude-monitor --log-level WARNING # DEBUG, INFO, WARNING, ERROR, CRITICAL

# Output JSON for automation/scripting
claude-monitor --json-output
```

### Available Plans
Expand All @@ -370,6 +375,54 @@ claude-monitor --log-level WARNING # DEBUG, INFO, WARNING, ERROR, CRITICAL
- **Cost Tracking**: Model-specific pricing with cache token calculations
- **Limit Detection**: Intelligent threshold detection with 95% confidence

### Automation & Scripting

#### JSON Output Mode

For automation, CI/CD pipelines, and programmatic access:

```bash
# Get usage data as JSON
claude-monitor --json-output

# Combine with other flags
claude-monitor --json-output --plan max20

# Example JSON output structure
{
"success": true,
"error": null,
"data": {
"blocks": [
{
"id": "session_123",
"isActive": true,
"totalTokens": 15420,
"costUSD": 7.32,
"startTime": "2025-01-20T10:00:00Z",
"endTime": "2025-01-20T15:00:00Z"
}
],
"metadata": {
"generated_at": "2025-01-20T15:30:00Z",
"entries_count": 1
}
},
"metadata": {
"data_path": "/home/user/.claude/projects",
"hours_back": 96,
"plan": "max20",
"version": "3.0.0"
}
}
```

**Use Cases:**
- **CI/CD Integration**: Monitor token usage in automated pipelines
- **Cost Tracking**: Extract usage data for billing and reporting
- **API Integration**: Feed data into dashboards and monitoring systems
- **Shell Scripts**: Parse JSON with `jq` for automated workflows


## πŸš€ What's New in v3.0.0

Expand Down Expand Up @@ -398,7 +451,7 @@ claude-monitor --log-level WARNING # DEBUG, INFO, WARNING, ERROR, CRITICAL
#### **Breaking Changes**
- Package name changed from claude-usage-monitor to claude-monitor
- Default plan changed from pro to custom (with auto-detection)
- Minimum Python version increased to 3.9+
- Minimum Python version increased to 3.10+
- Command structure updated (see examples above)


Expand Down Expand Up @@ -540,9 +593,9 @@ tzdata # Windows timezone data

#### Python Requirements

- **Minimum**: Python 3.9+
- **Minimum**: Python 3.11+
- **Recommended**: Python 3.11+
- **Tested on**: Python 3.9, 3.10, 3.11, 3.12, 3.13
- **Tested on**: Python 3.11, 3.12, 3.13

### Smart Detection Features

Expand Down Expand Up @@ -850,7 +903,7 @@ python -m pytest tests/test_analysis.py -v

### Prerequisites

1. **Python 3.9+** installed on your system
1. **Python 3.11+** installed on your system
2. **Git** for cloning the repository


Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ claude_monitor = ["py.typed"]

[tool.black]
line-length = 88
target-version = ["py39", "py310", "py311", "py312"]
target-version = ["py39", "py310", "py311", "py312", "py313"]
skip-string-normalization = false
include = '\.pyi?$'
extend-exclude = '''
Expand Down
75 changes: 74 additions & 1 deletion src/claude_monitor/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,11 @@ def main(argv: Optional[List[str]] = None) -> int:

args = settings.to_namespace()

_run_monitoring(args)
# Check if JSON output mode is requested
if hasattr(args, 'json_output') and args.json_output:
return _run_json_output(args)
else:
_run_monitoring(args)

return 0

Expand All @@ -101,6 +105,75 @@ def main(argv: Optional[List[str]] = None) -> int:
return 1


def _run_json_output(args: argparse.Namespace) -> int:
"""Run in JSON output mode - analyze data and output JSON to stdout."""
import json

try:
# Discover Claude data paths
data_paths: List[Path] = discover_claude_data_paths()
if not data_paths:
error_result = {
"error": "No Claude data directory found",
"success": False,
"data": None,
"metadata": {"version": __version__}
}
print(json.dumps(error_result, indent=2))
return 1

data_path: Path = data_paths[0]

# Get hours_back parameter (default to 96 hours to match interactive mode)
hours_back: int = getattr(args, 'hours_back', 96)

# Analyze usage data
usage_data = analyze_usage(
hours_back=hours_back,
use_cache=True,
quick_start=False,
data_path=str(data_path)
)

if usage_data is None:
error_result = {
"error": "Failed to analyze usage data",
"success": False,
"data": None,
"metadata": {"version": __version__}
}
print(json.dumps(error_result, indent=2))
return 1

# Add metadata
result = {
"success": True,
"error": None,
"data": usage_data,
"metadata": {
"data_path": str(data_path),
"hours_back": hours_back,
"plan": getattr(args, 'plan', 'custom'),
"generated_at": usage_data.get("metadata", {}).get("generated_at"),
"version": __version__
}
}

# Output JSON to stdout
print(json.dumps(result, indent=2, default=str))
return 0

except Exception as e:
error_result = {
"error": str(e),
"success": False,
"data": None,
"metadata": {"version": __version__}
}
print(json.dumps(error_result, indent=2))
return 1


def _run_monitoring(args: argparse.Namespace) -> None:
"""Main monitoring implementation without facade."""
if hasattr(args, "theme") and args.theme:
Expand Down
6 changes: 6 additions & 0 deletions src/claude_monitor/core/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@ def _get_system_time_format() -> str:

clear: bool = Field(default=False, description="Clear saved configuration")

json_output: bool = Field(
default=False,
description="Output analysis data as JSON instead of running interactive monitor",
)

@field_validator("plan", mode="before")
@classmethod
def validate_plan(cls, v: Any) -> str:
Expand Down Expand Up @@ -329,5 +334,6 @@ def to_namespace(self) -> argparse.Namespace:
args.log_level = self.log_level
args.log_file = str(self.log_file) if self.log_file else None
args.version = self.version
args.json_output = self.json_output

return args
Loading
Loading