skills/cc-analytics/SKILL.md
Use when user asks for Claude Code usage stats, weekly analytics, project activity summary, or wants to see what projects were worked on. Triggers on "аналитика", "статистика claude", "cc stats", "weekly report", "что делал"
npx skillsauth add serejaris/ris-claude-code cc-analyticsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Generate HTML report of Claude Code usage from ~/.claude/history.jsonl.
~/.claude/history.jsonl — prompts with timestamps and project pathsSingle HTML file with terminal aesthetic:
Run this Python script to generate the report:
import json
import os
import subprocess
from datetime import datetime, timedelta
from collections import defaultdict
def get_git_info(path):
if not os.path.isdir(path) or not os.path.exists(os.path.join(path, '.git')):
return None, 0
try:
result = subprocess.run(['git', '-C', path, 'remote', 'get-url', 'origin'],
capture_output=True, text=True, timeout=5)
remote = result.stdout.strip() if result.returncode == 0 else None
if remote:
remote = remote.replace('[email protected]:', 'github.com/').replace('.git', '').replace('https://', '')
week_ago = (datetime.now() - timedelta(days=7)).strftime('%Y-%m-%d')
result = subprocess.run(['git', '-C', path, 'rev-list', '--count', f'--since={week_ago}', 'HEAD'],
capture_output=True, text=True, timeout=5)
commits = int(result.stdout.strip()) if result.returncode == 0 else 0
return remote, commits
except:
return None, 0
# Parse history
history = []
with open(os.path.expanduser('~/.claude/history.jsonl'), 'r') as f:
for line in f:
try:
history.append(json.loads(line))
except:
pass
# Filter last N days (default 7)
days = 7
now = datetime.now()
cutoff = (now - timedelta(days=days)).timestamp() * 1000
projects = defaultdict(lambda: {'prompts': [], 'sessions': set()})
for entry in history:
ts = entry.get('timestamp', 0)
if ts >= cutoff:
project = entry.get('project', 'unknown')
projects[project]['prompts'].append(entry)
projects[project]['sessions'].add(datetime.fromtimestamp(ts/1000).strftime('%Y-%m-%d'))
# Collect data
results = []
total_commits = 0
for project, data in projects.items():
remote, commits = get_git_info(project)
total_commits += commits
results.append({
'name': os.path.basename(project) or project.replace('/Users/ris/', '~/'),
'folder': project.replace('/Users/ris/', '~/'),
'remote': remote,
'prompts': len(data['prompts']),
'sessions': len(data['sessions']),
'commits': commits
})
results.sort(key=lambda x: -x['prompts'])
max_prompts = results[0]['prompts'] if results else 1
Use terminal aesthetic with:
'SF Mono', 'Monaco', 'Inconsolata', monospace#0d0d0d#b0b0b0 (text), #555 (dim), #4ec9b0 (cyan), #ce9178 (orange)$ command --flags style section headers█ characters<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>claude-analytics</title>
<style>
body {
font-family: 'SF Mono', 'Monaco', 'Inconsolata', monospace;
background: #0d0d0d;
color: #b0b0b0;
font-size: 14px;
line-height: 1.6;
padding: 24px;
}
.container { max-width: 900px; margin: 0 auto; }
.header { color: #6a9955; margin-bottom: 24px; }
.dim { color: #555; }
.bright { color: #e0e0e0; }
.cyan { color: #4ec9b0; }
.orange { color: #ce9178; }
.row {
display: grid;
grid-template-columns: 24px 200px 1fr 80px 80px 60px;
gap: 8px;
padding: 6px 0;
border-bottom: 1px solid #1a1a1a;
}
.row:hover { background: #141414; }
a { color: #555; text-decoration: none; }
a:hover { color: #888; }
.stat-box { display: inline-block; margin-right: 32px; }
.stat-value { font-size: 28px; color: #e0e0e0; }
.stat-label { color: #555; font-size: 12px; }
</style>
</head>
<body>
<div class="container">
<pre class="header">
┌─────────────────────────────────────────────────────────────────┐
│ ██████╗██╗ █████╗ ██╗ ██╗██████╗ ███████╗ │
│ ██╔════╝██║ ██╔══██╗██║ ██║██╔══██╗██╔════╝ │
│ ██║ ██║ ███████║██║ ██║██║ ██║█████╗ │
│ ██║ ██║ ██╔══██║██║ ██║██║ ██║██╔══╝ │
│ ╚██████╗███████╗██║ ██║╚██████╔╝██████╔╝███████╗ │
│ ╚═════╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝ │
│ Weekly Analytics Report │
│ {start_date} .. {end_date} │
└─────────────────────────────────────────────────────────────────┘
</pre>
<!-- Stats, table, chart sections -->
</div>
</body>
</html>
def make_bar(value, max_val, width=40):
filled = int((value / max_val) * width)
return '█' * filled
# Example output:
# cohorts ████████████████████████████████████████ 194
# ai-whisper █████████████████████████████████████▋ 183
~/claude-analytics.htmlopen ~/claude-analytics.htmldays = 7 to desired rangetools
Use when transitioning from retro to weekly plan, prioritizing backlog, choosing outcomes for the week, or when user says "план на неделю", "планирование", "W13 plan", "outcomes", "приоритизация". Runs after weekly-retro skill.
testing
Use when preparing for, running, or closing a live meeting with an AI assistant dashboard. Triggers on "meeting copilot", "live copilot", "prepare for a call", "update copilot", "close the session", or requests to turn transcript chunks into meeting questions, topic maps, decisions, and follow-ups.
tools
Use when conducting weekly retrospective, reviewing past week, or when user says "retro", "weekly retro", "week review". Triggers at end of week or start of new week.
tools
Use when creating GitHub issues, adding tasks to backlog, or when unsure which repo/project an issue belongs to. Triggers on "создай задачу", "issue", "добавь в бэклог", "task routing", "куда положить задачу".